Skip to content

Commit a25e372

Browse files
trondmyJ. Bruce Fields
authored andcommitted
nfsd: Ensure CLONE persists data and metadata changes to the target file
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: ffa0160 ("nfsd: implement the NFSv4.2 CLONE operation") Signed-off-by: Trond Myklebust <[email protected]> Cc: [email protected] # v4.5+ Signed-off-by: J. Bruce Fields <[email protected]>
1 parent 8729aab commit a25e372

File tree

3 files changed

+10
-3
lines changed

3 files changed

+10
-3
lines changed

fs/nfsd/nfs4proc.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1077,7 +1077,8 @@ nfsd4_clone(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
10771077
goto out;
10781078

10791079
status = nfsd4_clone_file_range(src->nf_file, clone->cl_src_pos,
1080-
dst->nf_file, clone->cl_dst_pos, clone->cl_count);
1080+
dst->nf_file, clone->cl_dst_pos, clone->cl_count,
1081+
EX_ISSYNC(cstate->current_fh.fh_export));
10811082

10821083
nfsd_file_put(dst);
10831084
nfsd_file_put(src);

fs/nfsd/vfs.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ __be32 nfsd4_set_nfs4_label(struct svc_rqst *rqstp, struct svc_fh *fhp,
525525
#endif
526526

527527
__be32 nfsd4_clone_file_range(struct file *src, u64 src_pos, struct file *dst,
528-
u64 dst_pos, u64 count)
528+
u64 dst_pos, u64 count, bool sync)
529529
{
530530
loff_t cloned;
531531

@@ -534,6 +534,12 @@ __be32 nfsd4_clone_file_range(struct file *src, u64 src_pos, struct file *dst,
534534
return nfserrno(cloned);
535535
if (count && cloned != count)
536536
return nfserrno(-EINVAL);
537+
if (sync) {
538+
loff_t dst_end = count ? dst_pos + count - 1 : LLONG_MAX;
539+
int status = vfs_fsync_range(dst, dst_pos, dst_end, 0);
540+
if (status < 0)
541+
return nfserrno(status);
542+
}
537543
return 0;
538544
}
539545

fs/nfsd/vfs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ __be32 nfsd4_set_nfs4_label(struct svc_rqst *, struct svc_fh *,
5656
__be32 nfsd4_vfs_fallocate(struct svc_rqst *, struct svc_fh *,
5757
struct file *, loff_t, loff_t, int);
5858
__be32 nfsd4_clone_file_range(struct file *, u64, struct file *,
59-
u64, u64);
59+
u64, u64, bool);
6060
#endif /* CONFIG_NFSD_V4 */
6161
__be32 nfsd_create_locked(struct svc_rqst *, struct svc_fh *,
6262
char *name, int len, struct iattr *attrs,

0 commit comments

Comments
 (0)