mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
nfsd: Ensure exclusion between CLONE and WRITE errors
Ensure that we can distinguish between synchronous CLONE and WRITE errors, and that we can assign them correctly. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
This commit is contained in:
parent
b66ae6dd0c
commit
1b28d756b2
1 changed files with 18 additions and 7 deletions
|
@ -536,22 +536,33 @@ __be32 nfsd4_clone_file_range(struct nfsd_file *nf_src, u64 src_pos,
|
||||||
struct file *src = nf_src->nf_file;
|
struct file *src = nf_src->nf_file;
|
||||||
struct file *dst = nf_dst->nf_file;
|
struct file *dst = nf_dst->nf_file;
|
||||||
loff_t cloned;
|
loff_t cloned;
|
||||||
|
__be32 ret = 0;
|
||||||
|
|
||||||
|
down_write(&nf_dst->nf_rwsem);
|
||||||
cloned = vfs_clone_file_range(src, src_pos, dst, dst_pos, count, 0);
|
cloned = vfs_clone_file_range(src, src_pos, dst, dst_pos, count, 0);
|
||||||
if (cloned < 0)
|
if (cloned < 0) {
|
||||||
return nfserrno(cloned);
|
ret = nfserrno(cloned);
|
||||||
if (count && cloned != count)
|
goto out_err;
|
||||||
return nfserrno(-EINVAL);
|
}
|
||||||
|
if (count && cloned != count) {
|
||||||
|
ret = nfserrno(-EINVAL);
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
if (sync) {
|
if (sync) {
|
||||||
loff_t dst_end = count ? dst_pos + count - 1 : LLONG_MAX;
|
loff_t dst_end = count ? dst_pos + count - 1 : LLONG_MAX;
|
||||||
int status = vfs_fsync_range(dst, dst_pos, dst_end, 0);
|
int status = vfs_fsync_range(dst, dst_pos, dst_end, 0);
|
||||||
|
|
||||||
if (!status)
|
if (!status)
|
||||||
status = commit_inode_metadata(file_inode(src));
|
status = commit_inode_metadata(file_inode(src));
|
||||||
if (status < 0)
|
if (status < 0) {
|
||||||
return nfserrno(status);
|
nfsd_reset_boot_verifier(net_generic(nf_dst->nf_net,
|
||||||
|
nfsd_net_id));
|
||||||
|
ret = nfserrno(status);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
out_err:
|
||||||
|
up_write(&nf_dst->nf_rwsem);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t nfsd_copy_file_range(struct file *src, u64 src_pos, struct file *dst,
|
ssize_t nfsd_copy_file_range(struct file *src, u64 src_pos, struct file *dst,
|
||||||
|
|
Loading…
Add table
Reference in a new issue