diff options
author | Trond Myklebust <trond.myklebust@primarydata.com> | 2016-06-25 17:50:53 -0400 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2016-07-05 19:11:07 -0400 |
commit | 1e564d3dbd684a105582471cb9ff2aada64a9052 (patch) | |
tree | bab58a4d7ddb228f6eb7e891540e3bf017587f38 /fs | |
parent | 79566ef018f53a181f067afdf7bef9cc53f9d34b (diff) | |
download | linux-stable-1e564d3dbd684a105582471cb9ff2aada64a9052.tar.gz linux-stable-1e564d3dbd684a105582471cb9ff2aada64a9052.tar.bz2 linux-stable-1e564d3dbd684a105582471cb9ff2aada64a9052.zip |
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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/nfs42proc.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c index aa03ed09ba06..0f9f536e647b 100644 --- a/fs/nfs/nfs42proc.c +++ b/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)) 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; } |