Fix a race condition in FASYNC handling
[linux-2.6.git] / fs / ioctl.c
index d152856c371be4906b7effec1f3c42842a4cee2d..43e8b2c0664b1b3d302a6d46e3fa40185edb5ae7 100644 (file)
@@ -400,11 +400,9 @@ static int ioctl_fioasync(unsigned int fd, struct file *filp,
 
        /* Did FASYNC state change ? */
        if ((flag ^ filp->f_flags) & FASYNC) {
-               if (filp->f_op && filp->f_op->fasync) {
-                       lock_kernel();
+               if (filp->f_op && filp->f_op->fasync)
                        error = filp->f_op->fasync(fd, filp, on);
-                       unlock_kernel();
-               } else
+               else
                        error = -ENOTTY;
        }
        if (error)
@@ -440,11 +438,17 @@ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
                break;
 
        case FIONBIO:
+               /* BKL needed to avoid races tweaking f_flags */
+               lock_kernel();
                error = ioctl_fionbio(filp, argp);
+               unlock_kernel();
                break;
 
        case FIOASYNC:
+               /* BKL needed to avoid races tweaking f_flags */
+               lock_kernel();
                error = ioctl_fioasync(fd, filp, argp);
+               unlock_kernel();
                break;
 
        case FIOQSIZE: