Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'bkl-removal' of git://git.lwn.net/linux-2.6

* 'bkl-removal' of git://git.lwn.net/linux-2.6:
Rationalize fasync return values
Move FASYNC bit handling to f_op->fasync()
Use f_lock to protect f_flags
Rename struct file->f_ep_lock

+90 -113
+5 -2
Documentation/filesystems/Locking
··· 437 437 can and should be done using the internal locking with smaller critical areas). 438 438 Current worst offender is ext2_get_block()... 439 439 440 - ->fasync() is a mess. This area needs a big cleanup and that will probably 441 - affect locking. 440 + ->fasync() is called without BKL protection, and is responsible for 441 + maintaining the FASYNC bit in filp->f_flags. Most instances call 442 + fasync_helper(), which does that maintenance, so it's not normally 443 + something one needs to worry about. Return values > 0 will be mapped to 444 + zero in the VFS layer. 442 445 443 446 ->readdir() and ->ioctl() on directories must be changed. Ideally we would 444 447 move ->readdir() to inode_operations and use a separate method for directory
+1 -6
drivers/char/sonypi.c
··· 888 888 889 889 static int sonypi_misc_fasync(int fd, struct file *filp, int on) 890 890 { 891 - int retval; 892 - 893 - retval = fasync_helper(fd, filp, on, &sonypi_device.fifo_async); 894 - if (retval < 0) 895 - return retval; 896 - return 0; 891 + return fasync_helper(fd, filp, on, &sonypi_device.fifo_async); 897 892 } 898 893 899 894 static int sonypi_misc_release(struct inode *inode, struct file *file)
+2 -3
drivers/char/tty_io.c
··· 2162 2162 if (get_user(nonblock, p)) 2163 2163 return -EFAULT; 2164 2164 2165 - /* file->f_flags is still BKL protected in the fs layer - vomit */ 2166 - lock_kernel(); 2165 + spin_lock(&file->f_lock); 2167 2166 if (nonblock) 2168 2167 file->f_flags |= O_NONBLOCK; 2169 2168 else 2170 2169 file->f_flags &= ~O_NONBLOCK; 2171 - unlock_kernel(); 2170 + spin_unlock(&file->f_lock); 2172 2171 return 0; 2173 2172 } 2174 2173
+1 -5
drivers/gpu/drm/drm_fops.c
··· 337 337 { 338 338 struct drm_file *priv = filp->private_data; 339 339 struct drm_device *dev = priv->minor->dev; 340 - int retcode; 341 340 342 341 DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, 343 342 (long)old_encode_dev(priv->minor->device)); 344 - retcode = fasync_helper(fd, filp, on, &dev->buf_async); 345 - if (retcode < 0) 346 - return retcode; 347 - return 0; 343 + return fasync_helper(fd, filp, on, &dev->buf_async); 348 344 } 349 345 EXPORT_SYMBOL(drm_fasync); 350 346
+1 -4
drivers/hid/usbhid/hiddev.c
··· 227 227 */ 228 228 static int hiddev_fasync(int fd, struct file *file, int on) 229 229 { 230 - int retval; 231 230 struct hiddev_list *list = file->private_data; 232 231 233 - retval = fasync_helper(fd, file, on, &list->fasync); 234 - 235 - return retval < 0 ? retval : 0; 232 + return fasync_helper(fd, file, on, &list->fasync); 236 233 } 237 234 238 235
+1 -5
drivers/ieee1394/dv1394.c
··· 1325 1325 1326 1326 struct video_card *video = file_to_video_card(file); 1327 1327 1328 - int retval = fasync_helper(fd, file, on, &video->fasync); 1329 - 1330 - if (retval < 0) 1331 - return retval; 1332 - return 0; 1328 + return fasync_helper(fd, file, on, &video->fasync); 1333 1329 } 1334 1330 1335 1331 static ssize_t dv1394_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
+1 -4
drivers/input/evdev.c
··· 94 94 static int evdev_fasync(int fd, struct file *file, int on) 95 95 { 96 96 struct evdev_client *client = file->private_data; 97 - int retval; 98 97 99 - retval = fasync_helper(fd, file, on, &client->fasync); 100 - 101 - return retval < 0 ? retval : 0; 98 + return fasync_helper(fd, file, on, &client->fasync); 102 99 } 103 100 104 101 static int evdev_flush(struct file *file, fl_owner_t id)
+1 -4
drivers/input/joydev.c
··· 159 159 160 160 static int joydev_fasync(int fd, struct file *file, int on) 161 161 { 162 - int retval; 163 162 struct joydev_client *client = file->private_data; 164 163 165 - retval = fasync_helper(fd, file, on, &client->fasync); 166 - 167 - return retval < 0 ? retval : 0; 164 + return fasync_helper(fd, file, on, &client->fasync); 168 165 } 169 166 170 167 static void joydev_free(struct device *dev)
+1 -4
drivers/input/mousedev.c
··· 403 403 404 404 static int mousedev_fasync(int fd, struct file *file, int on) 405 405 { 406 - int retval; 407 406 struct mousedev_client *client = file->private_data; 408 407 409 - retval = fasync_helper(fd, file, on, &client->fasync); 410 - 411 - return retval < 0 ? retval : 0; 408 + return fasync_helper(fd, file, on, &client->fasync); 412 409 } 413 410 414 411 static void mousedev_free(struct device *dev)
+1 -3
drivers/input/serio/serio_raw.c
··· 58 58 static int serio_raw_fasync(int fd, struct file *file, int on) 59 59 { 60 60 struct serio_raw_list *list = file->private_data; 61 - int retval; 62 61 63 - retval = fasync_helper(fd, file, on, &list->fasync); 64 - return retval < 0 ? retval : 0; 62 + return fasync_helper(fd, file, on, &list->fasync); 65 63 } 66 64 67 65 static struct serio_raw *serio_raw_locate(int minor)
+2 -2
drivers/net/wan/cosa.c
··· 998 998 static int cosa_fasync(struct inode *inode, struct file *file, int on) 999 999 { 1000 1000 int port = iminor(inode); 1001 - int rv = fasync_helper(inode, file, on, &fasync[port]); 1002 - return rv < 0 ? rv : 0; 1001 + 1002 + return fasync_helper(inode, file, on, &fasync[port]); 1003 1003 } 1004 1004 #endif 1005 1005
+1 -6
drivers/platform/x86/sony-laptop.c
··· 1917 1917 1918 1918 static int sonypi_misc_fasync(int fd, struct file *filp, int on) 1919 1919 { 1920 - int retval; 1921 - 1922 - retval = fasync_helper(fd, filp, on, &sonypi_compat.fifo_async); 1923 - if (retval < 0) 1924 - return retval; 1925 - return 0; 1920 + return fasync_helper(fd, filp, on, &sonypi_compat.fifo_async); 1926 1921 } 1927 1922 1928 1923 static int sonypi_misc_release(struct inode *inode, struct file *file)
+1 -3
drivers/scsi/sg.c
··· 1154 1154 static int 1155 1155 sg_fasync(int fd, struct file *filp, int mode) 1156 1156 { 1157 - int retval; 1158 1157 Sg_device *sdp; 1159 1158 Sg_fd *sfp; 1160 1159 ··· 1162 1163 SCSI_LOG_TIMEOUT(3, printk("sg_fasync: %s, mode=%d\n", 1163 1164 sdp->disk->disk_name, mode)); 1164 1165 1165 - retval = fasync_helper(fd, filp, mode, &sfp->async_qp); 1166 - return (retval < 0) ? retval : 0; 1166 + return fasync_helper(fd, filp, mode, &sfp->async_qp); 1167 1167 } 1168 1168 1169 1169 static int
+6 -1
drivers/usb/gadget/file_storage.c
··· 1711 1711 curlun->sense_data = SS_WRITE_PROTECTED; 1712 1712 return -EINVAL; 1713 1713 } 1714 + spin_lock(&curlun->filp->f_lock); 1714 1715 curlun->filp->f_flags &= ~O_SYNC; // Default is not to wait 1716 + spin_unlock(&curlun->filp->f_lock); 1715 1717 1716 1718 /* Get the starting Logical Block Address and check that it's 1717 1719 * not too big */ ··· 1730 1728 curlun->sense_data = SS_INVALID_FIELD_IN_CDB; 1731 1729 return -EINVAL; 1732 1730 } 1733 - if (fsg->cmnd[1] & 0x08) // FUA 1731 + if (fsg->cmnd[1] & 0x08) { // FUA 1732 + spin_lock(&curlun->filp->f_lock); 1734 1733 curlun->filp->f_flags |= O_SYNC; 1734 + spin_unlock(&curlun->filp->f_lock); 1735 + } 1735 1736 } 1736 1737 if (lba >= curlun->num_sectors) { 1737 1738 curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
+7 -5
fs/eventpoll.c
··· 417 417 ep_unregister_pollwait(ep, epi); 418 418 419 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 421 if (ep_is_linked(&epi->fllink)) 422 422 list_del_init(&epi->fllink); 423 - spin_unlock(&file->f_ep_lock); 423 + spin_unlock(&file->f_lock); 424 424 425 425 rb_erase(&epi->rbn, &ep->rbr); 426 426 ··· 538 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 542 * necessary. It is not necessary because we're in the "struct file" 543 543 * cleanup path, and this means that noone is using this file anymore. 544 544 * So, for example, epoll_ctl() cannot hit here sicne if we reach this ··· 547 547 * will correctly serialize the operation. We do need to acquire 548 548 * "ep->mtx" after "epmutex" because ep_remove() requires it when called 549 549 * from anywhere but ep_free(). 550 + * 551 + * Besides, ep_remove() acquires the lock, so we can't hold it here. 550 552 */ 551 553 mutex_lock(&epmutex); 552 554 ··· 787 785 goto error_unregister; 788 786 789 787 /* Add the current item to the list of active epoll hook for this file */ 790 - spin_lock(&tfile->f_ep_lock); 788 + spin_lock(&tfile->f_lock); 791 789 list_add_tail(&epi->fllink, &tfile->f_ep_links); 792 - spin_unlock(&tfile->f_ep_lock); 790 + spin_unlock(&tfile->f_lock); 793 791 794 792 /* 795 793 * Add the current item to the RB tree. All RB tree operations are
+20 -13
fs/fcntl.c
··· 141 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 146 146 static int setfl(int fd, struct file * filp, unsigned long arg) 147 147 { ··· 177 177 return error; 178 178 179 179 /* 180 - * We still need a lock here for now to keep multiple FASYNC calls 181 - * from racing with each other. 180 + * ->fasync() is responsible for setting the FASYNC bit. 182 181 */ 183 - lock_kernel(); 184 - if ((arg ^ filp->f_flags) & FASYNC) { 185 - if (filp->f_op && filp->f_op->fasync) { 186 - error = filp->f_op->fasync(fd, filp, (arg & FASYNC) != 0); 187 - if (error < 0) 188 - goto out; 189 - } 182 + if (((arg ^ filp->f_flags) & FASYNC) && filp->f_op && 183 + filp->f_op->fasync) { 184 + error = filp->f_op->fasync(fd, filp, (arg & FASYNC) != 0); 185 + if (error < 0) 186 + goto out; 187 + if (error > 0) 188 + error = 0; 190 189 } 191 - 190 + spin_lock(&filp->f_lock); 192 191 filp->f_flags = (arg & SETFL_MASK) | (filp->f_flags & ~SETFL_MASK); 192 + spin_unlock(&filp->f_lock); 193 + 193 194 out: 194 - unlock_kernel(); 195 195 return error; 196 196 } 197 197 ··· 516 516 static 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 520 * to set up the fasync queue. It returns negative on error, 0 if it did 521 521 * no changes and positive if it added/deleted the entry. 522 522 */ ··· 555 555 result = 1; 556 556 } 557 557 out: 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 565 write_unlock_irq(&fasync_lock); 559 566 return result; 560 567 }
+1
fs/file_table.c
··· 128 128 atomic_long_set(&f->f_count, 1); 129 129 rwlock_init(&f->f_owner.lock); 130 130 f->f_cred = get_cred(cred); 131 + spin_lock_init(&f->f_lock); 131 132 eventpoll_init_file(f); 132 133 /* f->f_version: 0 */ 133 134 return f;
+4 -14
fs/ioctl.c
··· 404 404 if (O_NONBLOCK != O_NDELAY) 405 405 flag |= O_NDELAY; 406 406 #endif 407 + spin_lock(&filp->f_lock); 407 408 if (on) 408 409 filp->f_flags |= flag; 409 410 else 410 411 filp->f_flags &= ~flag; 412 + spin_unlock(&filp->f_lock); 411 413 return error; 412 414 } 413 415 ··· 427 425 /* Did FASYNC state change ? */ 428 426 if ((flag ^ filp->f_flags) & FASYNC) { 429 427 if (filp->f_op && filp->f_op->fasync) 428 + /* fasync() adjusts filp->f_flags */ 430 429 error = filp->f_op->fasync(fd, filp, on); 431 430 else 432 431 error = -ENOTTY; 433 432 } 434 - if (error) 435 - return error; 436 - 437 - if (on) 438 - filp->f_flags |= FASYNC; 439 - else 440 - filp->f_flags &= ~FASYNC; 441 - return error; 433 + return error < 0 ? error : 0; 442 434 } 443 435 444 436 static int ioctl_fsfreeze(struct file *filp) ··· 495 499 break; 496 500 497 501 case FIONBIO: 498 - /* BKL needed to avoid races tweaking f_flags */ 499 - lock_kernel(); 500 502 error = ioctl_fionbio(filp, argp); 501 - unlock_kernel(); 502 503 break; 503 504 504 505 case FIOASYNC: 505 - /* BKL needed to avoid races tweaking f_flags */ 506 - lock_kernel(); 507 506 error = ioctl_fioasync(fd, filp, argp); 508 - unlock_kernel(); 509 507 break; 510 508 511 509 case FIOQSIZE:
+4 -1
fs/nfsd/vfs.c
··· 998 998 999 999 if (!EX_ISSYNC(exp)) 1000 1000 stable = 0; 1001 - if (stable && !EX_WGATHER(exp)) 1001 + if (stable && !EX_WGATHER(exp)) { 1002 + spin_lock(&file->f_lock); 1002 1003 file->f_flags |= O_SYNC; 1004 + spin_unlock(&file->f_lock); 1005 + } 1003 1006 1004 1007 /* Write the data. */ 1005 1008 oldfs = get_fs(); set_fs(KERNEL_DS);
+3 -13
fs/pipe.c
··· 667 667 retval = fasync_helper(fd, filp, on, &inode->i_pipe->fasync_readers); 668 668 mutex_unlock(&inode->i_mutex); 669 669 670 - if (retval < 0) 671 - return retval; 672 - 673 - return 0; 670 + return retval; 674 671 } 675 672 676 673 ··· 681 684 retval = fasync_helper(fd, filp, on, &inode->i_pipe->fasync_writers); 682 685 mutex_unlock(&inode->i_mutex); 683 686 684 - if (retval < 0) 685 - return retval; 686 - 687 - return 0; 687 + return retval; 688 688 } 689 689 690 690 ··· 700 706 fasync_helper(-1, filp, 0, &pipe->fasync_readers); 701 707 } 702 708 mutex_unlock(&inode->i_mutex); 703 - 704 - if (retval < 0) 705 - return retval; 706 - 707 - return 0; 709 + return retval; 708 710 } 709 711 710 712
-1
include/linux/eventpoll.h
··· 61 61 static inline void eventpoll_init_file(struct file *file) 62 62 { 63 63 INIT_LIST_HEAD(&file->f_ep_links); 64 - spin_lock_init(&file->f_ep_lock); 65 64 } 66 65 67 66
+1 -1
include/linux/fs.h
··· 849 849 #define f_dentry f_path.dentry 850 850 #define f_vfsmnt f_path.mnt 851 851 const struct file_operations *f_op; 852 + spinlock_t f_lock; /* f_ep_links, f_flags */ 852 853 atomic_long_t f_count; 853 854 unsigned int f_flags; 854 855 fmode_t f_mode; ··· 868 867 #ifdef CONFIG_EPOLL 869 868 /* Used by fs/eventpoll.c to link all the hooks to this file */ 870 869 struct list_head f_ep_links; 871 - spinlock_t f_ep_lock; 872 870 #endif /* #ifdef CONFIG_EPOLL */ 873 871 struct address_space *f_mapping; 874 872 #ifdef CONFIG_DEBUG_WRITECOUNT
+2
ipc/mqueue.c
··· 1156 1156 omqstat.mq_flags = filp->f_flags & O_NONBLOCK; 1157 1157 if (u_mqstat) { 1158 1158 audit_mq_getsetattr(mqdes, &mqstat); 1159 + spin_lock(&filp->f_lock); 1159 1160 if (mqstat.mq_flags & O_NONBLOCK) 1160 1161 filp->f_flags |= O_NONBLOCK; 1161 1162 else 1162 1163 filp->f_flags &= ~O_NONBLOCK; 1164 + spin_unlock(&filp->f_lock); 1163 1165 1164 1166 inode->i_atime = inode->i_ctime = CURRENT_TIME; 1165 1167 }
+7
net/socket.c
··· 1074 1074 1075 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 1084 prev = &(sock->fasync_list); 1078 1085 1079 1086 for (fa = *prev; fa != NULL; prev = &fa->fa_next, fa = *prev)
+2 -5
sound/core/control.c
··· 1373 1373 static int snd_ctl_fasync(int fd, struct file * file, int on) 1374 1374 { 1375 1375 struct snd_ctl_file *ctl; 1376 - int err; 1376 + 1377 1377 ctl = file->private_data; 1378 - err = fasync_helper(fd, file, on, &ctl->fasync); 1379 - if (err < 0) 1380 - return err; 1381 - return 0; 1378 + return fasync_helper(fd, file, on, &ctl->fasync); 1382 1379 } 1383 1380 1384 1381 /*
+2
sound/core/oss/pcm_oss.c
··· 1903 1903 1904 1904 static int snd_pcm_oss_nonblock(struct file * file) 1905 1905 { 1906 + spin_lock(&file->f_lock); 1906 1907 file->f_flags |= O_NONBLOCK; 1908 + spin_unlock(&file->f_lock); 1907 1909 return 0; 1908 1910 } 1909 1911
+1 -3
sound/core/pcm_native.c
··· 3246 3246 err = fasync_helper(fd, file, on, &runtime->fasync); 3247 3247 out: 3248 3248 unlock_kernel(); 3249 - if (err < 0) 3250 - return err; 3251 - return 0; 3249 + return err; 3252 3250 } 3253 3251 3254 3252 /*
+1 -5
sound/core/timer.c
··· 1825 1825 static int snd_timer_user_fasync(int fd, struct file * file, int on) 1826 1826 { 1827 1827 struct snd_timer_user *tu; 1828 - int err; 1829 1828 1830 1829 tu = file->private_data; 1831 - err = fasync_helper(fd, file, on, &tu->fasync); 1832 - if (err < 0) 1833 - return err; 1834 - return 0; 1830 + return fasync_helper(fd, file, on, &tu->fasync); 1835 1831 } 1836 1832 1837 1833 static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,
+2
sound/oss/au1550_ac97.c
··· 1627 1627 sizeof(abinfo)) ? -EFAULT : 0; 1628 1628 1629 1629 case SNDCTL_DSP_NONBLOCK: 1630 + spin_lock(&file->f_lock); 1630 1631 file->f_flags |= O_NONBLOCK; 1632 + spin_unlock(&file->f_lock); 1631 1633 return 0; 1632 1634 1633 1635 case SNDCTL_DSP_GETODELAY:
+2
sound/oss/audio.c
··· 433 433 return dma_ioctl(dev, cmd, arg); 434 434 435 435 case SNDCTL_DSP_NONBLOCK: 436 + spin_lock(&file->f_lock); 436 437 file->f_flags |= O_NONBLOCK; 438 + spin_unlock(&file->f_lock); 437 439 return 0; 438 440 439 441 case SNDCTL_DSP_GETCAPS:
+2
sound/oss/sh_dac_audio.c
··· 135 135 return put_user(AFMT_U8, (int *)arg); 136 136 137 137 case SNDCTL_DSP_NONBLOCK: 138 + spin_lock(&file->f_lock); 138 139 file->f_flags |= O_NONBLOCK; 140 + spin_unlock(&file->f_lock); 139 141 return 0; 140 142 141 143 case SNDCTL_DSP_GETCAPS:
+2
sound/oss/swarm_cs4297a.c
··· 2200 2200 sizeof(abinfo)) ? -EFAULT : 0; 2201 2201 2202 2202 case SNDCTL_DSP_NONBLOCK: 2203 + spin_lock(&file->f_lock); 2203 2204 file->f_flags |= O_NONBLOCK; 2205 + spin_unlock(&file->f_lock); 2204 2206 return 0; 2205 2207 2206 2208 case SNDCTL_DSP_GETODELAY:
+2
sound/oss/vwsnd.c
··· 2673 2673 2674 2674 case SNDCTL_DSP_NONBLOCK: /* _SIO ('P',14) */ 2675 2675 DBGX("SNDCTL_DSP_NONBLOCK\n"); 2676 + spin_lock(&file->f_lock); 2676 2677 file->f_flags |= O_NONBLOCK; 2678 + spin_unlock(&file->f_lock); 2677 2679 return 0; 2678 2680 2679 2681 case SNDCTL_DSP_RESET: /* _SIO ('P', 0) */