Message ID | alpine.LFD.2.00.0910212305090.3526@localhost.localdomain (mailing list archive) |
---|---|
State | Changes Requested |
Headers | show |
On Wed, Oct 21, 2009 at 11:07:18PM +0200, John Kacur wrote: > From 0c2b412cdccf73bdeb19bb866bfe556942eaeca2 Mon Sep 17 00:00:00 2001 > From: John Kacur <jkacur@redhat.com> > Date: Wed, 21 Oct 2009 23:01:12 +0200 > Subject: [PATCH] macintosh: Explicitly set llseek to no_llseek in ans-lcd > > Now that we've removed the BKL here, let's explicitly set lleek to no_llseek > > Signed-off-by: John Kacur <jkacur@redhat.com> > --- > drivers/macintosh/ans-lcd.c | 1 + > 1 files changed, 1 insertions(+), 0 deletions(-) > > diff --git a/drivers/macintosh/ans-lcd.c b/drivers/macintosh/ans-lcd.c > index 4ae8ec9..a1a1bde 100644 > --- a/drivers/macintosh/ans-lcd.c > +++ b/drivers/macintosh/ans-lcd.c > @@ -137,6 +137,7 @@ const struct file_operations anslcd_fops = { > .write = anslcd_write, > .unlocked_ioctl = anslcd_ioctl, > .open = anslcd_open, > + .llseedk = no_llseek, llseedk? :) Should we better pushdown default_llseek to every to every file operations that don't implement llseek? I don't know how many of them don't implement llseek() though. That said we can't continue anymore with this default attribution of default_llseek() on new fops.
On Wed, 21 Oct 2009, Frederic Weisbecker wrote: > On Wed, Oct 21, 2009 at 11:07:18PM +0200, John Kacur wrote: > > From 0c2b412cdccf73bdeb19bb866bfe556942eaeca2 Mon Sep 17 00:00:00 2001 > > From: John Kacur <jkacur@redhat.com> > > Date: Wed, 21 Oct 2009 23:01:12 +0200 > > Subject: [PATCH] macintosh: Explicitly set llseek to no_llseek in ans-lcd > > > > Now that we've removed the BKL here, let's explicitly set lleek to no_llseek > > > > Signed-off-by: John Kacur <jkacur@redhat.com> > > --- > > drivers/macintosh/ans-lcd.c | 1 + > > 1 files changed, 1 insertions(+), 0 deletions(-) > > > > diff --git a/drivers/macintosh/ans-lcd.c b/drivers/macintosh/ans-lcd.c > > index 4ae8ec9..a1a1bde 100644 > > --- a/drivers/macintosh/ans-lcd.c > > +++ b/drivers/macintosh/ans-lcd.c > > @@ -137,6 +137,7 @@ const struct file_operations anslcd_fops = { > > .write = anslcd_write, > > .unlocked_ioctl = anslcd_ioctl, > > .open = anslcd_open, > > + .llseedk = no_llseek, > > > llseedk? :) > > > Should we better pushdown default_llseek to every to every > file operations that don't implement llseek? > I don't know how many of them don't implement llseek() though. > > That said we can't continue anymore with this default attribution > of default_llseek() on new fops. > If you don't explicitly set it to no_llseek, you automatically get the default_llseek, which uses the BKL. So if your driver doesn't need it, it is best to explicitly set it to no_llseek. There is also a generic_file_llseek_unlocked, somewhat analogous to the unlocked_ioctls that you can use if you don't need to provide a full llseek yourself.
On Wed, Oct 21, 2009 at 11:33:17PM +0200, John Kacur wrote: > > Should we better pushdown default_llseek to every to every > > file operations that don't implement llseek? > > I don't know how many of them don't implement llseek() though. > > > > That said we can't continue anymore with this default attribution > > of default_llseek() on new fops. > > > > If you don't explicitly set it to no_llseek, you automatically get the > default_llseek, which uses the BKL. So if your driver doesn't need it, it > is best to explicitly set it to no_llseek. Sure, that's the right thing to do. > There is also a generic_file_llseek_unlocked, somewhat analogous to the > unlocked_ioctls that you can use if you don't need to provide a full > llseek yourself. No problem with that. Setting no_llseek or generic_file_llseek_unlocked, depending on the context is the right thing to do. What I'm wondering about concerns the future code that will have no llsek() implemented in their fops. We can't continue to use default_llseek() for future code unless we want to continue these post reviews and fixes forever.
On Wed, 21 Oct 2009, Frederic Weisbecker wrote: > On Wed, Oct 21, 2009 at 11:33:17PM +0200, John Kacur wrote: > > > Should we better pushdown default_llseek to every to every > > > file operations that don't implement llseek? > > > I don't know how many of them don't implement llseek() though. > > > > > > That said we can't continue anymore with this default attribution > > > of default_llseek() on new fops. > > > > > > > If you don't explicitly set it to no_llseek, you automatically get the > > default_llseek, which uses the BKL. So if your driver doesn't need it, it > > is best to explicitly set it to no_llseek. > > > Sure, that's the right thing to do. > > > > There is also a generic_file_llseek_unlocked, somewhat analogous to the > > unlocked_ioctls that you can use if you don't need to provide a full > > llseek yourself. > > > No problem with that. Setting no_llseek or generic_file_llseek_unlocked, > depending on the context is the right thing to do. > > What I'm wondering about concerns the future code that will have > no llsek() implemented in their fops. > > We can't continue to use default_llseek() for future code unless we > want to continue these post reviews and fixes forever. > I'm thinking that the simplier approach, would be to make the default_llseek the unlocked one. Then you only have to audit the drivers that have the BKL - ie the ones we are auditing anyway, and explicitly set them to the bkl locked llseek. There might be a hidden interaction though between the non-unlocked variety of ioctls and default llseek though.
On Wed, Oct 21, 2009 at 11:53:21PM +0200, John Kacur wrote: > > No problem with that. Setting no_llseek or generic_file_llseek_unlocked, > > depending on the context is the right thing to do. > > > > What I'm wondering about concerns the future code that will have > > no llsek() implemented in their fops. > > > > We can't continue to use default_llseek() for future code unless we > > want to continue these post reviews and fixes forever. > > > > I'm thinking that the simplier approach, would be to make the > default_llseek the unlocked one. Then you only have to audit the drivers > that have the BKL - ie the ones we are auditing anyway, and explicitly set > them to the bkl locked llseek. > > There might be a hidden interaction though between the non-unlocked > variety of ioctls and default llseek though. I fear that won't work because the bkl in default_llseek() does not only synchronizes with others uses of the bkl in a driver, it also synchronizes lseek() itself. As an example offset change is not atomic. This is a long long, so updating its value is not atomic in 32 bits archs.
On Thursday 22 October 2009, Frederic Weisbecker wrote: > > I'm thinking that the simplier approach, would be to make the > > default_llseek the unlocked one. Then you only have to audit the drivers > > that have the BKL - ie the ones we are auditing anyway, and explicitly set > > them to the bkl locked llseek. > > > > There might be a hidden interaction though between the non-unlocked > > variety of ioctls and default llseek though. > > > I fear that won't work because the bkl in default_llseek() does not > only synchronizes with others uses of the bkl in a driver, it also > synchronizes lseek() itself. > > As an example offset change is not atomic. This is a long long, so > updating its value is not atomic in 32 bits archs. A late follow-up on this one: I looked at what places in the code manipulate file->f_pos directly and found that almost all the uses in driver code are broken because they don't take any locks. Most of them are in driver specific lseek operations. Others are in read/write methods and are even more broken because the change gets immediately overwritten by vfs_read/vfs_write when the driver method returns. IMHO, we should complete the pushdown into all ioctl methods that John and Thomas have started working on, fixing the lseek methods in those files we touch. When that is done, all interaction between default_llseek and driver locking has to be with explicit calls to lock_kernel in those drivers, so we can reasonably well script the search for drivers needing the BKL in llseek: everyhing that a) defines file_operations without an llseek function, b) touches f_pos somewhere, and c) calls lock_kernel() somewhere That should only be a small number and when they are fixed, we can remove default_llseek and instead call generic_file_llseek for any file operation without a separate llseek method. Arnd <><
On Mon, Nov 02, 2009 at 04:51:52PM +0100, Arnd Bergmann wrote: > I looked at what places in the code manipulate file->f_pos directly > and found that almost all the uses in driver code are broken because > they don't take any locks. Most of them are in driver specific > lseek operations. Others are in read/write methods and are even > more broken because the change gets immediately overwritten by > vfs_read/vfs_write when the driver method returns. > > IMHO, we should complete the pushdown into all ioctl methods > that John and Thomas have started working on, fixing the lseek > methods in those files we touch. > > When that is done, all interaction between default_llseek and > driver locking has to be with explicit calls to lock_kernel > in those drivers, so we can reasonably well script the search > for drivers needing the BKL in llseek: everyhing that > a) defines file_operations without an llseek function, > b) touches f_pos somewhere, and > c) calls lock_kernel() somewhere > That should only be a small number and when they are fixed, > we can remove default_llseek and instead call generic_file_llseek > for any file operation without a separate llseek method. As mentioned before making generic_file_llseek the new default is probably a bad idea. The majority of our file_operations instances don't actually support seeking, so no_llseek should become the new default if you spend some effort on converting things. Anything that wants to allow seeking will have to set a llseek method. This also mirrors what we do for other file operations. None of the major ones has a non-trivial default, it's either silently succeeding for a selected few like open or release or returning an error for operatings that actually do something like read and write.
On Monday 16 November 2009, Christoph Hellwig wrote: > As mentioned before making generic_file_llseek the new default is > probably a bad idea. The majority of our file_operations instances > don't actually support seeking, so no_llseek should become the new > default if you spend some effort on converting things. Anything that > wants to allow seeking will have to set a llseek method. This also > mirrors what we do for other file operations. None of the major ones > has a non-trivial default, it's either silently succeeding for a > selected few like open or release or returning an error for operatings > that actually do something like read and write. Ok, good point. Do you think we should also prevent pread/pwrite for devices without an llseek operation, like nonseekable_open does? I guess that would be consistent. Then there is the point that (I forgot who) brought up that changing code to do no_llseek is actually an ABI change. Even if the file position is never used anywhere, some random user application might expect a chardev not to return an error when its llseek method is called, resulting in regressions. Arnd <><
diff --git a/drivers/macintosh/ans-lcd.c b/drivers/macintosh/ans-lcd.c index 4ae8ec9..a1a1bde 100644 --- a/drivers/macintosh/ans-lcd.c +++ b/drivers/macintosh/ans-lcd.c @@ -137,6 +137,7 @@ const struct file_operations anslcd_fops = { .write = anslcd_write, .unlocked_ioctl = anslcd_ioctl, .open = anslcd_open, + .llseedk = no_llseek, }; static struct miscdevice anslcd_dev = {