diff options
author | Trond Myklebust <trond.myklebust@primarydata.com> | 2016-06-25 18:12:03 -0400 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2016-07-05 19:11:07 -0400 |
commit | 837bb1d752d92ea4d870877ffbd6ec5cf76624b3 (patch) | |
tree | bc6efb2d8fff743b5dd56ed0848fa9f4f99c2e3c /fs/nfs/nfs42proc.c | |
parent | 1e564d3dbd684a105582471cb9ff2aada64a9052 (diff) | |
download | talos-obmc-linux-837bb1d752d92ea4d870877ffbd6ec5cf76624b3.tar.gz talos-obmc-linux-837bb1d752d92ea4d870877ffbd6ec5cf76624b3.zip |
NFSv4.2: Fix writeback races in nfs4_copy_file_range
We need to ensure that any writes to the destination file are serialised
with the copy, meaning that the writeback has to occur under the inode lock.
Also relax the writeback requirement on the source, and rely on the
stateid checking to tell us if the source rebooted. Add the helper
nfs_filemap_write_and_wait_range() to call pnfs_sync_inode() as
is appropriate for pNFS servers that may need a layoutcommit.
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs/nfs42proc.c')
-rw-r--r-- | fs/nfs/nfs42proc.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c index 0f9f536e647b..b7d457cea03f 100644 --- a/fs/nfs/nfs42proc.c +++ b/fs/nfs/nfs42proc.c @@ -156,11 +156,20 @@ static ssize_t _nfs42_proc_copy(struct file *src, loff_t pos_src, if (status) return status; + status = nfs_filemap_write_and_wait_range(file_inode(src)->i_mapping, + pos_src, pos_src + (loff_t)count - 1); + if (status) + return status; + status = nfs4_set_rw_stateid(&args.dst_stateid, dst_lock->open_context, dst_lock, FMODE_WRITE); if (status) return status; + status = nfs_sync_inode(dst_inode); + if (status) + return status; + status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0); if (status == -ENOTSUPP) |