Merge branch 'for-2.6.30' into for-2.6.31
[sfrench/cifs-2.6.git] / fs / ioctl.c
index 240ec63984cb9f5eb5e25f113a508cb518f73d18..ac2d47e439265c1622199ed17b00315c475a4a4f 100644 (file)
@@ -404,10 +404,12 @@ static int ioctl_fionbio(struct file *filp, int __user *argp)
        if (O_NONBLOCK != O_NDELAY)
                flag |= O_NDELAY;
 #endif
+       spin_lock(&filp->f_lock);
        if (on)
                filp->f_flags |= flag;
        else
                filp->f_flags &= ~flag;
+       spin_unlock(&filp->f_lock);
        return error;
 }
 
@@ -425,18 +427,12 @@ 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)
+                       /* fasync() adjusts filp->f_flags */
                        error = filp->f_op->fasync(fd, filp, on);
                else
                        error = -ENOTTY;
        }
-       if (error)
-               return error;
-
-       if (on)
-               filp->f_flags |= FASYNC;
-       else
-               filp->f_flags &= ~FASYNC;
-       return error;
+       return error < 0 ? error : 0;
 }
 
 static int ioctl_fsfreeze(struct file *filp)
@@ -499,17 +495,11 @@ 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: