Browse Source

NFSv4.2: Fix a race in nfs42_proc_deallocate()

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>
Trond Myklebust 9 years ago
parent
commit
1e564d3dbd
1 changed files with 4 additions and 2 deletions
  1. 4 2
      fs/nfs/nfs42proc.c

+ 4 - 2
fs/nfs/nfs42proc.c

@@ -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))
 	if (!nfs_server_capable(inode, NFS_CAP_DEALLOCATE))
 		return -EOPNOTSUPP;
 		return -EOPNOTSUPP;
 
 
-	nfs_wb_all(inode);
 	inode_lock(inode);
 	inode_lock(inode);
+	err = nfs_sync_inode(inode);
+	if (err)
+		goto out_unlock;
 
 
 	err = nfs42_proc_fallocate(&msg, filep, offset, len);
 	err = nfs42_proc_fallocate(&msg, filep, offset, len);
 	if (err == 0)
 	if (err == 0)
 		truncate_pagecache_range(inode, offset, (offset + len) -1);
 		truncate_pagecache_range(inode, offset, (offset + len) -1);
 	if (err == -EOPNOTSUPP)
 	if (err == -EOPNOTSUPP)
 		NFS_SERVER(inode)->caps &= ~NFS_CAP_DEALLOCATE;
 		NFS_SERVER(inode)->caps &= ~NFS_CAP_DEALLOCATE;
-
+out_unlock:
 	inode_unlock(inode);
 	inode_unlock(inode);
 	return err;
 	return err;
 }
 }