NFSv4.2: Fix a race in nfs42_proc_deallocate()
authorTrond Myklebust <trond.myklebust@primarydata.com>
Sat, 25 Jun 2016 21:50:53 +0000 (17:50 -0400)
committerTrond Myklebust <trond.myklebust@primarydata.com>
Tue, 5 Jul 2016 23:11:07 +0000 (19:11 -0400)
When punching holes in a file, we want to ensure the operation is
serialised w.r.t. other writes, meaning that we want to call
nfs_sync_inode() while holding the inode lock.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
fs/nfs/nfs42proc.c

index aa03ed09ba06f79763146b0a6f8cb171c9778b0c..0f9f536e647b7242fd145643b3a592aec048dbf7 100644 (file)
@@ -113,15 +113,17 @@ int nfs42_proc_deallocate(struct file *filep, loff_t offset, loff_t len)
        if (!nfs_server_capable(inode, NFS_CAP_DEALLOCATE))
                return -EOPNOTSUPP;
 
-       nfs_wb_all(inode);
        inode_lock(inode);
+       err = nfs_sync_inode(inode);
+       if (err)
+               goto out_unlock;
 
        err = nfs42_proc_fallocate(&msg, filep, offset, len);
        if (err == 0)
                truncate_pagecache_range(inode, offset, (offset + len) -1);
        if (err == -EOPNOTSUPP)
                NFS_SERVER(inode)->caps &= ~NFS_CAP_DEALLOCATE;
-
+out_unlock:
        inode_unlock(inode);
        return err;
 }