]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - fs/nfs/file.c
Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[karo-tx-linux.git] / fs / nfs / file.c
index 668213984d68708c3d54cccce36ad3a0c048657e..5713eb32a45ea20c1de50f2ee28f4ddcae468f67 100644 (file)
@@ -482,7 +482,7 @@ static int nfs_launder_page(struct page *page)
                inode->i_ino, (long long)page_offset(page));
 
        nfs_fscache_wait_on_page_write(nfsi, page);
-       return nfs_wb_launder_page(inode, page);
+       return nfs_wb_page(inode, page);
 }
 
 static int nfs_swap_activate(struct swap_info_struct *sis, struct file *file,
@@ -697,14 +697,14 @@ do_unlk(struct file *filp, int cmd, struct file_lock *fl, int is_local)
        if (!IS_ERR(l_ctx)) {
                status = nfs_iocounter_wait(l_ctx);
                nfs_put_lock_context(l_ctx);
-               if (status < 0)
+               /*  NOTE: special case
+                *      If we're signalled while cleaning up locks on process exit, we
+                *      still need to complete the unlock.
+                */
+               if (status < 0 && !(fl->fl_flags & FL_CLOSE))
                        return status;
        }
 
-       /* NOTE: special case
-        *      If we're signalled while cleaning up locks on process exit, we
-        *      still need to complete the unlock.
-        */
        /*
         * Use local locking if mounted with "-onolock" or with appropriate
         * "-olocal_lock="
@@ -820,9 +820,23 @@ int nfs_flock(struct file *filp, int cmd, struct file_lock *fl)
        if (NFS_SERVER(inode)->flags & NFS_MOUNT_LOCAL_FLOCK)
                is_local = 1;
 
-       /* We're simulating flock() locks using posix locks on the server */
-       if (fl->fl_type == F_UNLCK)
+       /*
+        * VFS doesn't require the open mode to match a flock() lock's type.
+        * NFS, however, may simulate flock() locking with posix locking which
+        * requires the open mode to match the lock type.
+        */
+       switch (fl->fl_type) {
+       case F_UNLCK:
                return do_unlk(filp, cmd, fl, is_local);
+       case F_RDLCK:
+               if (!(filp->f_mode & FMODE_READ))
+                       return -EBADF;
+               break;
+       case F_WRLCK:
+               if (!(filp->f_mode & FMODE_WRITE))
+                       return -EBADF;
+       }
+
        return do_setlk(filp, cmd, fl, is_local);
 }
 EXPORT_SYMBOL_GPL(nfs_flock);