aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/filesystems/Locking7
-rw-r--r--drivers/char/sonypi.c7
-rw-r--r--drivers/char/tty_io.c5
-rw-r--r--drivers/gpu/drm/drm_fops.c6
-rw-r--r--drivers/hid/usbhid/hiddev.c5
-rw-r--r--drivers/ieee1394/dv1394.c6
-rw-r--r--drivers/input/evdev.c5
-rw-r--r--drivers/input/joydev.c5
-rw-r--r--drivers/input/mousedev.c5
-rw-r--r--drivers/input/serio/serio_raw.c4
-rw-r--r--drivers/net/wan/cosa.c4
-rw-r--r--drivers/platform/x86/sony-laptop.c7
-rw-r--r--drivers/scsi/sg.c4
-rw-r--r--drivers/usb/gadget/file_storage.c7
-rw-r--r--fs/eventpoll.c12
-rw-r--r--fs/fcntl.c33
-rw-r--r--fs/file_table.c1
-rw-r--r--fs/ioctl.c18
-rw-r--r--fs/nfsd/vfs.c5
-rw-r--r--fs/pipe.c16
-rw-r--r--include/linux/eventpoll.h1
-rw-r--r--include/linux/fs.h2
-rw-r--r--ipc/mqueue.c2
-rw-r--r--net/socket.c7
-rw-r--r--sound/core/control.c7
-rw-r--r--sound/core/oss/pcm_oss.c2
-rw-r--r--sound/core/pcm_native.c4
-rw-r--r--sound/core/timer.c6
-rw-r--r--sound/oss/au1550_ac97.c2
-rw-r--r--sound/oss/audio.c2
-rw-r--r--sound/oss/sh_dac_audio.c2
-rw-r--r--sound/oss/swarm_cs4297a.c2
-rw-r--r--sound/oss/vwsnd.c2
33 files changed, 90 insertions, 113 deletions
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index ec6a9392a173..4e78ce677843 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -437,8 +437,11 @@ grab BKL for cases when we close a file that had been opened r/w, but that
437can and should be done using the internal locking with smaller critical areas). 437can and should be done using the internal locking with smaller critical areas).
438Current worst offender is ext2_get_block()... 438Current worst offender is ext2_get_block()...
439 439
440->fasync() is a mess. This area needs a big cleanup and that will probably 440->fasync() is called without BKL protection, and is responsible for
441affect locking. 441maintaining the FASYNC bit in filp->f_flags. Most instances call
442fasync_helper(), which does that maintenance, so it's not normally
443something one needs to worry about. Return values > 0 will be mapped to
444zero in the VFS layer.
442 445
443->readdir() and ->ioctl() on directories must be changed. Ideally we would 446->readdir() and ->ioctl() on directories must be changed. Ideally we would
444move ->readdir() to inode_operations and use a separate method for directory 447move ->readdir() to inode_operations and use a separate method for directory
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index f4374437a033..fd3dced97776 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -888,12 +888,7 @@ found:
888 888
889static int sonypi_misc_fasync(int fd, struct file *filp, int on) 889static int sonypi_misc_fasync(int fd, struct file *filp, int on)
890{ 890{
891 int retval; 891 return fasync_helper(fd, filp, on, &sonypi_device.fifo_async);
892
893 retval = fasync_helper(fd, filp, on, &sonypi_device.fifo_async);
894 if (retval < 0)
895 return retval;
896 return 0;
897} 892}
898 893
899static int sonypi_misc_release(struct inode *inode, struct file *file) 894static int sonypi_misc_release(struct inode *inode, struct file *file)
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/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index f52663ebe016..e13cb62bbaee 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -337,14 +337,10 @@ int drm_fasync(int fd, struct file *filp, int on)
337{ 337{
338 struct drm_file *priv = filp->private_data; 338 struct drm_file *priv = filp->private_data;
339 struct drm_device *dev = priv->minor->dev; 339 struct drm_device *dev = priv->minor->dev;
340 int retcode;
341 340
342 DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, 341 DRM_DEBUG("fd = %d, device = 0x%lx\n", fd,
343 (long)old_encode_dev(priv->minor->device)); 342 (long)old_encode_dev(priv->minor->device));
344 retcode = fasync_helper(fd, filp, on, &dev->buf_async); 343 return fasync_helper(fd, filp, on, &dev->buf_async);
345 if (retcode < 0)
346 return retcode;
347 return 0;
348} 344}
349EXPORT_SYMBOL(drm_fasync); 345EXPORT_SYMBOL(drm_fasync);
350 346
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index 1f5b5d4c3c34..aa214170baf4 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -227,12 +227,9 @@ void hiddev_report_event(struct hid_device *hid, struct hid_report *report)
227 */ 227 */
228static int hiddev_fasync(int fd, struct file *file, int on) 228static int hiddev_fasync(int fd, struct file *file, int on)
229{ 229{
230 int retval;
231 struct hiddev_list *list = file->private_data; 230 struct hiddev_list *list = file->private_data;
232 231
233 retval = fasync_helper(fd, file, on, &list->fasync); 232 return fasync_helper(fd, file, on, &list->fasync);
234
235 return retval < 0 ? retval : 0;
236} 233}
237 234
238 235
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
index 3838bc4acaba..cb15bfa38d70 100644
--- a/drivers/ieee1394/dv1394.c
+++ b/drivers/ieee1394/dv1394.c
@@ -1325,11 +1325,7 @@ static int dv1394_fasync(int fd, struct file *file, int on)
1325 1325
1326 struct video_card *video = file_to_video_card(file); 1326 struct video_card *video = file_to_video_card(file);
1327 1327
1328 int retval = fasync_helper(fd, file, on, &video->fasync); 1328 return fasync_helper(fd, file, on, &video->fasync);
1329
1330 if (retval < 0)
1331 return retval;
1332 return 0;
1333} 1329}
1334 1330
1335static ssize_t dv1394_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) 1331static ssize_t dv1394_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index ed8baa0aec3c..7a7a026ba712 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -94,11 +94,8 @@ static void evdev_event(struct input_handle *handle,
94static int evdev_fasync(int fd, struct file *file, int on) 94static int evdev_fasync(int fd, struct file *file, int on)
95{ 95{
96 struct evdev_client *client = file->private_data; 96 struct evdev_client *client = file->private_data;
97 int retval;
98
99 retval = fasync_helper(fd, file, on, &client->fasync);
100 97
101 return retval < 0 ? retval : 0; 98 return fasync_helper(fd, file, on, &client->fasync);
102} 99}
103 100
104static int evdev_flush(struct file *file, fl_owner_t id) 101static int evdev_flush(struct file *file, fl_owner_t id)
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index 6f2366220a50..4224f0112849 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -159,12 +159,9 @@ static void joydev_event(struct input_handle *handle,
159 159
160static int joydev_fasync(int fd, struct file *file, int on) 160static int joydev_fasync(int fd, struct file *file, int on)
161{ 161{
162 int retval;
163 struct joydev_client *client = file->private_data; 162 struct joydev_client *client = file->private_data;
164 163
165 retval = fasync_helper(fd, file, on, &client->fasync); 164 return fasync_helper(fd, file, on, &client->fasync);
166
167 return retval < 0 ? retval : 0;
168} 165}
169 166
170static void joydev_free(struct device *dev) 167static void joydev_free(struct device *dev)
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index ef99a7e6d40c..17fd6d46d082 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -403,12 +403,9 @@ static void mousedev_event(struct input_handle *handle,
403 403
404static int mousedev_fasync(int fd, struct file *file, int on) 404static int mousedev_fasync(int fd, struct file *file, int on)
405{ 405{
406 int retval;
407 struct mousedev_client *client = file->private_data; 406 struct mousedev_client *client = file->private_data;
408 407
409 retval = fasync_helper(fd, file, on, &client->fasync); 408 return fasync_helper(fd, file, on, &client->fasync);
410
411 return retval < 0 ? retval : 0;
412} 409}
413 410
414static void mousedev_free(struct device *dev) 411static void mousedev_free(struct device *dev)
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
index 06bbd0e74c6f..b03009bb7468 100644
--- a/drivers/input/serio/serio_raw.c
+++ b/drivers/input/serio/serio_raw.c
@@ -58,10 +58,8 @@ static unsigned int serio_raw_no;
58static int serio_raw_fasync(int fd, struct file *file, int on) 58static int serio_raw_fasync(int fd, struct file *file, int on)
59{ 59{
60 struct serio_raw_list *list = file->private_data; 60 struct serio_raw_list *list = file->private_data;
61 int retval;
62 61
63 retval = fasync_helper(fd, file, on, &list->fasync); 62 return fasync_helper(fd, file, on, &list->fasync);
64 return retval < 0 ? retval : 0;
65} 63}
66 64
67static struct serio_raw *serio_raw_locate(int minor) 65static struct serio_raw *serio_raw_locate(int minor)
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index d276d72ee3b7..61581ee5f08c 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -998,8 +998,8 @@ static struct fasync_struct *fasync[256] = { NULL, };
998static int cosa_fasync(struct inode *inode, struct file *file, int on) 998static int cosa_fasync(struct inode *inode, struct file *file, int on)
999{ 999{
1000 int port = iminor(inode); 1000 int port = iminor(inode);
1001 int rv = fasync_helper(inode, file, on, &fasync[port]); 1001
1002 return rv < 0 ? rv : 0; 1002 return fasync_helper(inode, file, on, &fasync[port]);
1003} 1003}
1004#endif 1004#endif
1005 1005
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index 537959d07148..bc8996c849ac 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -1917,12 +1917,7 @@ static struct sonypi_compat_s sonypi_compat = {
1917 1917
1918static int sonypi_misc_fasync(int fd, struct file *filp, int on) 1918static int sonypi_misc_fasync(int fd, struct file *filp, int on)
1919{ 1919{
1920 int retval; 1920 return fasync_helper(fd, filp, on, &sonypi_compat.fifo_async);
1921
1922 retval = fasync_helper(fd, filp, on, &sonypi_compat.fifo_async);
1923 if (retval < 0)
1924 return retval;
1925 return 0;
1926} 1921}
1927 1922
1928static int sonypi_misc_release(struct inode *inode, struct file *file) 1923static int sonypi_misc_release(struct inode *inode, struct file *file)
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 516925d8b570..b4ef2f84ea32 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1154,7 +1154,6 @@ sg_poll(struct file *filp, poll_table * wait)
1154static int 1154static int
1155sg_fasync(int fd, struct file *filp, int mode) 1155sg_fasync(int fd, struct file *filp, int mode)
1156{ 1156{
1157 int retval;
1158 Sg_device *sdp; 1157 Sg_device *sdp;
1159 Sg_fd *sfp; 1158 Sg_fd *sfp;
1160 1159
@@ -1163,8 +1162,7 @@ sg_fasync(int fd, struct file *filp, int mode)
1163 SCSI_LOG_TIMEOUT(3, printk("sg_fasync: %s, mode=%d\n", 1162 SCSI_LOG_TIMEOUT(3, printk("sg_fasync: %s, mode=%d\n",
1164 sdp->disk->disk_name, mode)); 1163 sdp->disk->disk_name, mode));
1165 1164
1166 retval = fasync_helper(fd, filp, mode, &sfp->async_qp); 1165 return fasync_helper(fd, filp, mode, &sfp->async_qp);
1167 return (retval < 0) ? retval : 0;
1168} 1166}
1169 1167
1170static int 1168static int
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index d3c2464dee82..5c030b080d4c 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;
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 011b9b8c90c6..c5c424f23fd5 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -417,10 +417,10 @@ static int ep_remove(struct eventpoll *ep, struct epitem *epi)
417 ep_unregister_pollwait(ep, epi); 417 ep_unregister_pollwait(ep, epi);
418 418
419 /* Remove the current item from the list of epoll hooks */ 419 /* Remove the current item from the list of epoll hooks */
420 spin_lock(&file->f_ep_lock); 420 spin_lock(&file->f_lock);
421 if (ep_is_linked(&epi->fllink)) 421 if (ep_is_linked(&epi->fllink))
422 list_del_init(&epi->fllink); 422 list_del_init(&epi->fllink);
423 spin_unlock(&file->f_ep_lock); 423 spin_unlock(&file->f_lock);
424 424
425 rb_erase(&epi->rbn, &ep->rbr); 425 rb_erase(&epi->rbn, &ep->rbr);
426 426
@@ -538,7 +538,7 @@ void eventpoll_release_file(struct file *file)
538 struct epitem *epi; 538 struct epitem *epi;
539 539
540 /* 540 /*
541 * We don't want to get "file->f_ep_lock" because it is not 541 * We don't want to get "file->f_lock" because it is not
542 * necessary. It is not necessary because we're in the "struct file" 542 * necessary. It is not necessary because we're in the "struct file"
543 * cleanup path, and this means that noone is using this file anymore. 543 * cleanup path, and this means that noone is using this file anymore.
544 * So, for example, epoll_ctl() cannot hit here sicne if we reach this 544 * So, for example, epoll_ctl() cannot hit here sicne if we reach this
@@ -547,6 +547,8 @@ void eventpoll_release_file(struct file *file)
547 * will correctly serialize the operation. We do need to acquire 547 * will correctly serialize the operation. We do need to acquire
548 * "ep->mtx" after "epmutex" because ep_remove() requires it when called 548 * "ep->mtx" after "epmutex" because ep_remove() requires it when called
549 * from anywhere but ep_free(). 549 * from anywhere but ep_free().
550 *
551 * Besides, ep_remove() acquires the lock, so we can't hold it here.
550 */ 552 */
551 mutex_lock(&epmutex); 553 mutex_lock(&epmutex);
552 554
@@ -785,9 +787,9 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event,
785 goto error_unregister; 787 goto error_unregister;
786 788
787 /* Add the current item to the list of active epoll hook for this file */ 789 /* Add the current item to the list of active epoll hook for this file */
788 spin_lock(&tfile->f_ep_lock); 790 spin_lock(&tfile->f_lock);
789 list_add_tail(&epi->fllink, &tfile->f_ep_links); 791 list_add_tail(&epi->fllink, &tfile->f_ep_links);
790 spin_unlock(&tfile->f_ep_lock); 792 spin_unlock(&tfile->f_lock);
791 793
792 /* 794 /*
793 * Add the current item to the RB tree. All RB tree operations are 795 * Add the current item to the RB tree. All RB tree operations are
diff --git a/fs/fcntl.c b/fs/fcntl.c
index bd215cc791da..d865ca66ccba 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -141,7 +141,7 @@ SYSCALL_DEFINE1(dup, unsigned int, fildes)
141 return ret; 141 return ret;
142} 142}
143 143
144#define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | FASYNC | O_DIRECT | O_NOATIME) 144#define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
145 145
146static int setfl(int fd, struct file * filp, unsigned long arg) 146static int setfl(int fd, struct file * filp, unsigned long arg)
147{ 147{
@@ -177,21 +177,21 @@ static int setfl(int fd, struct file * filp, unsigned long arg)
177 return error; 177 return error;
178 178
179 /* 179 /*
180 * We still need a lock here for now to keep multiple FASYNC calls 180 * ->fasync() is responsible for setting the FASYNC bit.
181 * from racing with each other.
182 */ 181 */
183 lock_kernel(); 182 if (((arg ^ filp->f_flags) & FASYNC) && filp->f_op &&
184 if ((arg ^ filp->f_flags) & FASYNC) { 183 filp->f_op->fasync) {
185 if (filp->f_op && filp->f_op->fasync) { 184 error = filp->f_op->fasync(fd, filp, (arg & FASYNC) != 0);
186 error = filp->f_op->fasync(fd, filp, (arg & FASYNC) != 0); 185 if (error < 0)
187 if (error < 0) 186 goto out;
188 goto out; 187 if (error > 0)
189 } 188 error = 0;
190 } 189 }
191 190 spin_lock(&filp->f_lock);
192 filp->f_flags = (arg & SETFL_MASK) | (filp->f_flags & ~SETFL_MASK); 191 filp->f_flags = (arg & SETFL_MASK) | (filp->f_flags & ~SETFL_MASK);
192 spin_unlock(&filp->f_lock);
193
193 out: 194 out:
194 unlock_kernel();
195 return error; 195 return error;
196} 196}
197 197
@@ -516,7 +516,7 @@ static DEFINE_RWLOCK(fasync_lock);
516static struct kmem_cache *fasync_cache __read_mostly; 516static struct kmem_cache *fasync_cache __read_mostly;
517 517
518/* 518/*
519 * fasync_helper() is used by some character device drivers (mainly mice) 519 * fasync_helper() is used by almost all character device drivers
520 * to set up the fasync queue. It returns negative on error, 0 if it did 520 * to set up the fasync queue. It returns negative on error, 0 if it did
521 * no changes and positive if it added/deleted the entry. 521 * no changes and positive if it added/deleted the entry.
522 */ 522 */
@@ -555,6 +555,13 @@ int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fap
555 result = 1; 555 result = 1;
556 } 556 }
557out: 557out:
558 /* Fix up FASYNC bit while still holding fasync_lock */
559 spin_lock(&filp->f_lock);
560 if (on)
561 filp->f_flags |= FASYNC;
562 else
563 filp->f_flags &= ~FASYNC;
564 spin_unlock(&filp->f_lock);
558 write_unlock_irq(&fasync_lock); 565 write_unlock_irq(&fasync_lock);
559 return result; 566 return result;
560} 567}
diff --git a/fs/file_table.c b/fs/file_table.c
index da806aceae3f..b74a8e1da913 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -128,6 +128,7 @@ struct file *get_empty_filp(void)
128 atomic_long_set(&f->f_count, 1); 128 atomic_long_set(&f->f_count, 1);
129 rwlock_init(&f->f_owner.lock); 129 rwlock_init(&f->f_owner.lock);
130 f->f_cred = get_cred(cred); 130 f->f_cred = get_cred(cred);
131 spin_lock_init(&f->f_lock);
131 eventpoll_init_file(f); 132 eventpoll_init_file(f);
132 /* f->f_version: 0 */ 133 /* f->f_version: 0 */
133 return f; 134 return f;
diff --git a/fs/ioctl.c b/fs/ioctl.c
index 240ec63984cb..ac2d47e43926 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -404,10 +404,12 @@ static int ioctl_fionbio(struct file *filp, int __user *argp)
404 if (O_NONBLOCK != O_NDELAY) 404 if (O_NONBLOCK != O_NDELAY)
405 flag |= O_NDELAY; 405 flag |= O_NDELAY;
406#endif 406#endif
407 spin_lock(&filp->f_lock);
407 if (on) 408 if (on)
408 filp->f_flags |= flag; 409 filp->f_flags |= flag;
409 else 410 else
410 filp->f_flags &= ~flag; 411 filp->f_flags &= ~flag;
412 spin_unlock(&filp->f_lock);
411 return error; 413 return error;
412} 414}
413 415
@@ -425,18 +427,12 @@ static int ioctl_fioasync(unsigned int fd, struct file *filp,
425 /* Did FASYNC state change ? */ 427 /* Did FASYNC state change ? */
426 if ((flag ^ filp->f_flags) & FASYNC) { 428 if ((flag ^ filp->f_flags) & FASYNC) {
427 if (filp->f_op && filp->f_op->fasync) 429 if (filp->f_op && filp->f_op->fasync)
430 /* fasync() adjusts filp->f_flags */
428 error = filp->f_op->fasync(fd, filp, on); 431 error = filp->f_op->fasync(fd, filp, on);
429 else 432 else
430 error = -ENOTTY; 433 error = -ENOTTY;
431 } 434 }
432 if (error) 435 return error < 0 ? error : 0;
433 return error;
434
435 if (on)
436 filp->f_flags |= FASYNC;
437 else
438 filp->f_flags &= ~FASYNC;
439 return error;
440} 436}
441 437
442static int ioctl_fsfreeze(struct file *filp) 438static int ioctl_fsfreeze(struct file *filp)
@@ -499,17 +495,11 @@ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
499 break; 495 break;
500 496
501 case FIONBIO: 497 case FIONBIO:
502 /* BKL needed to avoid races tweaking f_flags */
503 lock_kernel();
504 error = ioctl_fionbio(filp, argp); 498 error = ioctl_fionbio(filp, argp);
505 unlock_kernel();
506 break; 499 break;
507 500
508 case FIOASYNC: 501 case FIOASYNC:
509 /* BKL needed to avoid races tweaking f_flags */
510 lock_kernel();
511 error = ioctl_fioasync(fd, filp, argp); 502 error = ioctl_fioasync(fd, filp, argp);
512 unlock_kernel();
513 break; 503 break;
514 504
515 case FIOQSIZE: 505 case FIOQSIZE:
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 6e50aaa56ca2..c165a6403df0 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -998,8 +998,11 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
998 998
999 if (!EX_ISSYNC(exp)) 999 if (!EX_ISSYNC(exp))
1000 stable = 0; 1000 stable = 0;
1001 if (stable && !EX_WGATHER(exp)) 1001 if (stable && !EX_WGATHER(exp)) {
1002 spin_lock(&file->f_lock);
1002 file->f_flags |= O_SYNC; 1003 file->f_flags |= O_SYNC;
1004 spin_unlock(&file->f_lock);
1005 }
1003 1006
1004 /* Write the data. */ 1007 /* Write the data. */
1005 oldfs = get_fs(); set_fs(KERNEL_DS); 1008 oldfs = get_fs(); set_fs(KERNEL_DS);
diff --git a/fs/pipe.c b/fs/pipe.c
index 14f502b89cf5..94ad15967cf9 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -667,10 +667,7 @@ pipe_read_fasync(int fd, struct file *filp, int on)
667 retval = fasync_helper(fd, filp, on, &inode->i_pipe->fasync_readers); 667 retval = fasync_helper(fd, filp, on, &inode->i_pipe->fasync_readers);
668 mutex_unlock(&inode->i_mutex); 668 mutex_unlock(&inode->i_mutex);
669 669
670 if (retval < 0) 670 return retval;
671 return retval;
672
673 return 0;
674} 671}
675 672
676 673
@@ -684,10 +681,7 @@ pipe_write_fasync(int fd, struct file *filp, int on)
684 retval = fasync_helper(fd, filp, on, &inode->i_pipe->fasync_writers); 681 retval = fasync_helper(fd, filp, on, &inode->i_pipe->fasync_writers);
685 mutex_unlock(&inode->i_mutex); 682 mutex_unlock(&inode->i_mutex);
686 683
687 if (retval < 0) 684 return retval;
688 return retval;
689
690 return 0;
691} 685}
692 686
693 687
@@ -706,11 +700,7 @@ pipe_rdwr_fasync(int fd, struct file *filp, int on)
706 fasync_helper(-1, filp, 0, &pipe->fasync_readers); 700 fasync_helper(-1, filp, 0, &pipe->fasync_readers);
707 } 701 }
708 mutex_unlock(&inode->i_mutex); 702 mutex_unlock(&inode->i_mutex);
709 703 return retval;
710 if (retval < 0)
711 return retval;
712
713 return 0;
714} 704}
715 705
716 706
diff --git a/include/linux/eventpoll.h b/include/linux/eventpoll.h
index f1e1d3c47125..f6856a5a1d4b 100644
--- a/include/linux/eventpoll.h
+++ b/include/linux/eventpoll.h
@@ -61,7 +61,6 @@ struct file;
61static inline void eventpoll_init_file(struct file *file) 61static inline void eventpoll_init_file(struct file *file)
62{ 62{
63 INIT_LIST_HEAD(&file->f_ep_links); 63 INIT_LIST_HEAD(&file->f_ep_links);
64 spin_lock_init(&file->f_ep_lock);
65} 64}
66 65
67 66
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 5bc81c4a98c1..1cd44f727dac 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -849,6 +849,7 @@ struct file {
849#define f_dentry f_path.dentry 849#define f_dentry f_path.dentry
850#define f_vfsmnt f_path.mnt 850#define f_vfsmnt f_path.mnt
851 const struct file_operations *f_op; 851 const struct file_operations *f_op;
852 spinlock_t f_lock; /* f_ep_links, f_flags */
852 atomic_long_t f_count; 853 atomic_long_t f_count;
853 unsigned int f_flags; 854 unsigned int f_flags;
854 fmode_t f_mode; 855 fmode_t f_mode;
@@ -867,7 +868,6 @@ struct file {
867#ifdef CONFIG_EPOLL 868#ifdef CONFIG_EPOLL
868 /* Used by fs/eventpoll.c to link all the hooks to this file */ 869 /* Used by fs/eventpoll.c to link all the hooks to this file */
869 struct list_head f_ep_links; 870 struct list_head f_ep_links;
870 spinlock_t f_ep_lock;
871#endif /* #ifdef CONFIG_EPOLL */ 871#endif /* #ifdef CONFIG_EPOLL */
872 struct address_space *f_mapping; 872 struct address_space *f_mapping;
873#ifdef CONFIG_DEBUG_WRITECOUNT 873#ifdef CONFIG_DEBUG_WRITECOUNT
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 54b4077fed79..a8ddadbc7459 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -1156,10 +1156,12 @@ SYSCALL_DEFINE3(mq_getsetattr, mqd_t, mqdes,
1156 omqstat.mq_flags = filp->f_flags & O_NONBLOCK; 1156 omqstat.mq_flags = filp->f_flags & O_NONBLOCK;
1157 if (u_mqstat) { 1157 if (u_mqstat) {
1158 audit_mq_getsetattr(mqdes, &mqstat); 1158 audit_mq_getsetattr(mqdes, &mqstat);
1159 spin_lock(&filp->f_lock);
1159 if (mqstat.mq_flags & O_NONBLOCK) 1160 if (mqstat.mq_flags & O_NONBLOCK)
1160 filp->f_flags |= O_NONBLOCK; 1161 filp->f_flags |= O_NONBLOCK;
1161 else 1162 else
1162 filp->f_flags &= ~O_NONBLOCK; 1163 filp->f_flags &= ~O_NONBLOCK;
1164 spin_unlock(&filp->f_lock);
1163 1165
1164 inode->i_atime = inode->i_ctime = CURRENT_TIME; 1166 inode->i_atime = inode->i_ctime = CURRENT_TIME;
1165 } 1167 }
diff --git a/net/socket.c b/net/socket.c
index 47a3dc074eb0..af0205ff56f2 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1074,6 +1074,13 @@ static int sock_fasync(int fd, struct file *filp, int on)
1074 1074
1075 lock_sock(sk); 1075 lock_sock(sk);
1076 1076
1077 spin_lock(&filp->f_lock);
1078 if (on)
1079 filp->f_flags |= FASYNC;
1080 else
1081 filp->f_flags &= ~FASYNC;
1082 spin_unlock(&filp->f_lock);
1083
1077 prev = &(sock->fasync_list); 1084 prev = &(sock->fasync_list);
1078 1085
1079 for (fa = *prev; fa != NULL; prev = &fa->fa_next, fa = *prev) 1086 for (fa = *prev; fa != NULL; prev = &fa->fa_next, fa = *prev)
diff --git a/sound/core/control.c b/sound/core/control.c
index 636b3b52ef8b..4b20fa2b7e6d 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -1373,12 +1373,9 @@ EXPORT_SYMBOL(snd_ctl_unregister_ioctl_compat);
1373static int snd_ctl_fasync(int fd, struct file * file, int on) 1373static int snd_ctl_fasync(int fd, struct file * file, int on)
1374{ 1374{
1375 struct snd_ctl_file *ctl; 1375 struct snd_ctl_file *ctl;
1376 int err; 1376
1377 ctl = file->private_data; 1377 ctl = file->private_data;
1378 err = fasync_helper(fd, file, on, &ctl->fasync); 1378 return fasync_helper(fd, file, on, &ctl->fasync);
1379 if (err < 0)
1380 return err;
1381 return 0;
1382} 1379}
1383 1380
1384/* 1381/*
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 2864cefb773c..dda000b9684c 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -1903,7 +1903,9 @@ static int snd_pcm_oss_set_fragment(struct snd_pcm_oss_file *pcm_oss_file, unsig
1903 1903
1904static int snd_pcm_oss_nonblock(struct file * file) 1904static int snd_pcm_oss_nonblock(struct file * file)
1905{ 1905{
1906 spin_lock(&file->f_lock);
1906 file->f_flags |= O_NONBLOCK; 1907 file->f_flags |= O_NONBLOCK;
1908 spin_unlock(&file->f_lock);
1907 return 0; 1909 return 0;
1908} 1910}
1909 1911
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index d9b8f5379428..a151fb01ba82 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -3246,9 +3246,7 @@ static int snd_pcm_fasync(int fd, struct file * file, int on)
3246 err = fasync_helper(fd, file, on, &runtime->fasync); 3246 err = fasync_helper(fd, file, on, &runtime->fasync);
3247out: 3247out:
3248 unlock_kernel(); 3248 unlock_kernel();
3249 if (err < 0) 3249 return err;
3250 return err;
3251 return 0;
3252} 3250}
3253 3251
3254/* 3252/*
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 796532081e81..3f0050d0b71e 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -1825,13 +1825,9 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
1825static int snd_timer_user_fasync(int fd, struct file * file, int on) 1825static int snd_timer_user_fasync(int fd, struct file * file, int on)
1826{ 1826{
1827 struct snd_timer_user *tu; 1827 struct snd_timer_user *tu;
1828 int err;
1829 1828
1830 tu = file->private_data; 1829 tu = file->private_data;
1831 err = fasync_helper(fd, file, on, &tu->fasync); 1830 return fasync_helper(fd, file, on, &tu->fasync);
1832 if (err < 0)
1833 return err;
1834 return 0;
1835} 1831}
1836 1832
1837static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, 1833static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,
diff --git a/sound/oss/au1550_ac97.c b/sound/oss/au1550_ac97.c
index 81e1f443d094..4191acccbcdb 100644
--- a/sound/oss/au1550_ac97.c
+++ b/sound/oss/au1550_ac97.c
@@ -1627,7 +1627,9 @@ au1550_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
1627 sizeof(abinfo)) ? -EFAULT : 0; 1627 sizeof(abinfo)) ? -EFAULT : 0;
1628 1628
1629 case SNDCTL_DSP_NONBLOCK: 1629 case SNDCTL_DSP_NONBLOCK:
1630 spin_lock(&file->f_lock);
1630 file->f_flags |= O_NONBLOCK; 1631 file->f_flags |= O_NONBLOCK;
1632 spin_unlock(&file->f_lock);
1631 return 0; 1633 return 0;
1632 1634
1633 case SNDCTL_DSP_GETODELAY: 1635 case SNDCTL_DSP_GETODELAY:
diff --git a/sound/oss/audio.c b/sound/oss/audio.c
index 89bd27a5e865..b69c05b7ea7b 100644
--- a/sound/oss/audio.c
+++ b/sound/oss/audio.c
@@ -433,7 +433,9 @@ int audio_ioctl(int dev, struct file *file, unsigned int cmd, void __user *arg)
433 return dma_ioctl(dev, cmd, arg); 433 return dma_ioctl(dev, cmd, arg);
434 434
435 case SNDCTL_DSP_NONBLOCK: 435 case SNDCTL_DSP_NONBLOCK:
436 spin_lock(&file->f_lock);
436 file->f_flags |= O_NONBLOCK; 437 file->f_flags |= O_NONBLOCK;
438 spin_unlock(&file->f_lock);
437 return 0; 439 return 0;
438 440
439 case SNDCTL_DSP_GETCAPS: 441 case SNDCTL_DSP_GETCAPS:
diff --git a/sound/oss/sh_dac_audio.c b/sound/oss/sh_dac_audio.c
index e5d423994918..78cfb66e4c59 100644
--- a/sound/oss/sh_dac_audio.c
+++ b/sound/oss/sh_dac_audio.c
@@ -135,7 +135,9 @@ static int dac_audio_ioctl(struct inode *inode, struct file *file,
135 return put_user(AFMT_U8, (int *)arg); 135 return put_user(AFMT_U8, (int *)arg);
136 136
137 case SNDCTL_DSP_NONBLOCK: 137 case SNDCTL_DSP_NONBLOCK:
138 spin_lock(&file->f_lock);
138 file->f_flags |= O_NONBLOCK; 139 file->f_flags |= O_NONBLOCK;
140 spin_unlock(&file->f_lock);
139 return 0; 141 return 0;
140 142
141 case SNDCTL_DSP_GETCAPS: 143 case SNDCTL_DSP_GETCAPS:
diff --git a/sound/oss/swarm_cs4297a.c b/sound/oss/swarm_cs4297a.c
index 41562ecde5bb..1edab7b4ea83 100644
--- a/sound/oss/swarm_cs4297a.c
+++ b/sound/oss/swarm_cs4297a.c
@@ -2200,7 +2200,9 @@ static int cs4297a_ioctl(struct inode *inode, struct file *file,
2200 sizeof(abinfo)) ? -EFAULT : 0; 2200 sizeof(abinfo)) ? -EFAULT : 0;
2201 2201
2202 case SNDCTL_DSP_NONBLOCK: 2202 case SNDCTL_DSP_NONBLOCK:
2203 spin_lock(&file->f_lock);
2203 file->f_flags |= O_NONBLOCK; 2204 file->f_flags |= O_NONBLOCK;
2205 spin_unlock(&file->f_lock);
2204 return 0; 2206 return 0;
2205 2207
2206 case SNDCTL_DSP_GETODELAY: 2208 case SNDCTL_DSP_GETODELAY:
diff --git a/sound/oss/vwsnd.c b/sound/oss/vwsnd.c
index 78b8acc7c3b9..187f72750e8f 100644
--- a/sound/oss/vwsnd.c
+++ b/sound/oss/vwsnd.c
@@ -2673,7 +2673,9 @@ static int vwsnd_audio_do_ioctl(struct inode *inode,
2673 2673
2674 case SNDCTL_DSP_NONBLOCK: /* _SIO ('P',14) */ 2674 case SNDCTL_DSP_NONBLOCK: /* _SIO ('P',14) */
2675 DBGX("SNDCTL_DSP_NONBLOCK\n"); 2675 DBGX("SNDCTL_DSP_NONBLOCK\n");
2676 spin_lock(&file->f_lock);
2676 file->f_flags |= O_NONBLOCK; 2677 file->f_flags |= O_NONBLOCK;
2678 spin_unlock(&file->f_lock);
2677 return 0; 2679 return 0;
2678 2680
2679 case SNDCTL_DSP_RESET: /* _SIO ('P', 0) */ 2681 case SNDCTL_DSP_RESET: /* _SIO ('P', 0) */