From: Trond Myklebust <trondmy@xxxxxxxxx> commit a25e3726b32c746c0098125d4c7463bb84df72bb upstream. The NFSv4.2 CLONE operation has implicit persistence requirements on the target file, since there is no protocol requirement that the client issue a separate operation to persist data. For that reason, we should call vfs_fsync_range() on the destination file after a successful call to vfs_clone_file_range(). Fixes: ffa0160a1039 ("nfsd: implement the NFSv4.2 CLONE operation") Signed-off-by: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx> Cc: stable@xxxxxxxxxxxxxxx # v4.5+ Signed-off-by: J. Bruce Fields <bfields@xxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- fs/nfsd/nfs4proc.c | 3 ++- fs/nfsd/vfs.c | 8 +++++++- fs/nfsd/vfs.h | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -1083,7 +1083,8 @@ nfsd4_clone(struct svc_rqst *rqstp, stru goto out; status = nfsd4_clone_file_range(src, clone->cl_src_pos, - dst, clone->cl_dst_pos, clone->cl_count); + dst, clone->cl_dst_pos, clone->cl_count, + EX_ISSYNC(cstate->current_fh.fh_export)); fput(dst); fput(src); --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -552,7 +552,7 @@ __be32 nfsd4_set_nfs4_label(struct svc_r #endif __be32 nfsd4_clone_file_range(struct file *src, u64 src_pos, struct file *dst, - u64 dst_pos, u64 count) + u64 dst_pos, u64 count, bool sync) { loff_t cloned; @@ -561,6 +561,12 @@ __be32 nfsd4_clone_file_range(struct fil return nfserrno(cloned); if (count && cloned != count) return nfserrno(-EINVAL); + if (sync) { + loff_t dst_end = count ? dst_pos + count - 1 : LLONG_MAX; + int status = vfs_fsync_range(dst, dst_pos, dst_end, 0); + if (status < 0) + return nfserrno(status); + } return 0; } --- a/fs/nfsd/vfs.h +++ b/fs/nfsd/vfs.h @@ -58,7 +58,7 @@ __be32 nfsd4_set_nfs4_label(str __be32 nfsd4_vfs_fallocate(struct svc_rqst *, struct svc_fh *, struct file *, loff_t, loff_t, int); __be32 nfsd4_clone_file_range(struct file *, u64, struct file *, - u64, u64); + u64, u64, bool); #endif /* CONFIG_NFSD_V4 */ __be32 nfsd_create_locked(struct svc_rqst *, struct svc_fh *, char *name, int len, struct iattr *attrs,