aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJonathan Corbet <corbet@lwn.net>2009-02-06 17:25:24 -0500
committerJonathan Corbet <corbet@lwn.net>2009-03-16 10:32:27 -0400
commitdb1dd4d376134eba0e08af523b61cc566a4ea1cd (patch)
tree8882c673abbaa5713511b7046493fa862b9140d1 /drivers
parent684999149002dd046269666a390458e0acb38280 (diff)
Use f_lock to protect f_flags
Traditionally, changes to struct file->f_flags have been done under BKL protection, or with no protection at all. This patch causes all f_flags changes after file open/creation time to be done under protection of f_lock. This allows the removal of some BKL usage and fixes a number of longstanding (if microscopic) races. Reviewed-by: Christoph Hellwig <hch@lst.de> Cc: Al Viro <viro@ZenIV.linux.org.uk> Signed-off-by: Jonathan Corbet <corbet@lwn.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/tty_io.c5
-rw-r--r--drivers/usb/gadget/file_storage.c7
2 files changed, 8 insertions, 4 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index bc84e125c6bc..224f271d8cbe 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -2162,13 +2162,12 @@ static int fionbio(struct file *file, int __user *p)
2162 if (get_user(nonblock, p)) 2162 if (get_user(nonblock, p))
2163 return -EFAULT; 2163 return -EFAULT;
2164 2164
2165 /* file->f_flags is still BKL protected in the fs layer - vomit */ 2165 spin_lock(&file->f_lock);
2166 lock_kernel();
2167 if (nonblock) 2166 if (nonblock)
2168 file->f_flags |= O_NONBLOCK; 2167 file->f_flags |= O_NONBLOCK;
2169 else 2168 else
2170 file->f_flags &= ~O_NONBLOCK; 2169 file->f_flags &= ~O_NONBLOCK;
2171 unlock_kernel(); 2170 spin_unlock(&file->f_lock);
2172 return 0; 2171 return 0;
2173} 2172}
2174 2173
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index 1ab9dac7e12d..33bb76cef33c 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -1711,7 +1711,9 @@ static int do_write(struct fsg_dev *fsg)
1711 curlun->sense_data = SS_WRITE_PROTECTED; 1711 curlun->sense_data = SS_WRITE_PROTECTED;
1712 return -EINVAL; 1712 return -EINVAL;
1713 } 1713 }
1714 spin_lock(&curlun->filp->f_lock);
1714 curlun->filp->f_flags &= ~O_SYNC; // Default is not to wait 1715 curlun->filp->f_flags &= ~O_SYNC; // Default is not to wait
1716 spin_unlock(&curlun->filp->f_lock);
1715 1717
1716 /* Get the starting Logical Block Address and check that it's 1718 /* Get the starting Logical Block Address and check that it's
1717 * not too big */ 1719 * not too big */
@@ -1728,8 +1730,11 @@ static int do_write(struct fsg_dev *fsg)
1728 curlun->sense_data = SS_INVALID_FIELD_IN_CDB; 1730 curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
1729 return -EINVAL; 1731 return -EINVAL;
1730 } 1732 }
1731 if (fsg->cmnd[1] & 0x08) // FUA 1733 if (fsg->cmnd[1] & 0x08) { // FUA
1734 spin_lock(&curlun->filp->f_lock);
1732 curlun->filp->f_flags |= O_SYNC; 1735 curlun->filp->f_flags |= O_SYNC;
1736 spin_unlock(&curlun->filp->f_lock);
1737 }
1733 } 1738 }
1734 if (lba >= curlun->num_sectors) { 1739 if (lba >= curlun->num_sectors) {
1735 curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; 1740 curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;