linux-nfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] nfsd: Clone should commit src file metadata too
@ 2019-12-18 17:37 Trond Myklebust
  2019-12-18 19:49 ` Dave Chinner
  0 siblings, 1 reply; 3+ messages in thread
From: Trond Myklebust @ 2019-12-18 17:37 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: Dave Chinner, linux-nfs

vfs_clone_file_range() can modify the metadata on the source file too,
so we need to commit that to stable storage as well.

Reported-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
---
 fs/nfsd/vfs.c | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index f0bca0e87d0c..bc7f330c2a79 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -280,19 +280,25 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name,
  * Commit metadata changes to stable storage.
  */
 static int
-commit_metadata(struct svc_fh *fhp)
+commit_inode_metadata(struct inode *inode)
 {
-	struct inode *inode = d_inode(fhp->fh_dentry);
 	const struct export_operations *export_ops = inode->i_sb->s_export_op;
 
-	if (!EX_ISSYNC(fhp->fh_export))
-		return 0;
-
 	if (export_ops->commit_metadata)
 		return export_ops->commit_metadata(inode);
 	return sync_inode_metadata(inode, 1);
 }
 
+static int
+commit_metadata(struct svc_fh *fhp)
+{
+	struct inode *inode = d_inode(fhp->fh_dentry);
+
+	if (!EX_ISSYNC(fhp->fh_export))
+		return 0;
+	return commit_inode_metadata(inode);
+}
+
 /*
  * Go over the attributes and take care of the small differences between
  * NFS semantics and what Linux expects.
@@ -536,7 +542,10 @@ __be32 nfsd4_clone_file_range(struct file *src, u64 src_pos, struct file *dst,
 		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);
+		int status = commit_inode_metadata(file_inode(src));
+
+		if (!status)
+			status = vfs_fsync_range(dst, dst_pos, dst_end, 0);
 		if (status < 0)
 			return nfserrno(status);
 	}
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] nfsd: Clone should commit src file metadata too
  2019-12-18 17:37 [PATCH] nfsd: Clone should commit src file metadata too Trond Myklebust
@ 2019-12-18 19:49 ` Dave Chinner
  2019-12-18 20:01   ` Trond Myklebust
  0 siblings, 1 reply; 3+ messages in thread
From: Dave Chinner @ 2019-12-18 19:49 UTC (permalink / raw)
  To: Trond Myklebust; +Cc: J. Bruce Fields, linux-nfs

On Wed, Dec 18, 2019 at 12:37:52PM -0500, Trond Myklebust wrote:
> vfs_clone_file_range() can modify the metadata on the source file too,
> so we need to commit that to stable storage as well.
> 
> Reported-by: Dave Chinner <david@fromorbit.com>
> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
> ---
>  fs/nfsd/vfs.c | 21 +++++++++++++++------
>  1 file changed, 15 insertions(+), 6 deletions(-)
> 
> diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
> index f0bca0e87d0c..bc7f330c2a79 100644
> --- a/fs/nfsd/vfs.c
> +++ b/fs/nfsd/vfs.c
> @@ -280,19 +280,25 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name,
>   * Commit metadata changes to stable storage.
>   */
>  static int
> -commit_metadata(struct svc_fh *fhp)
> +commit_inode_metadata(struct inode *inode)
>  {
> -	struct inode *inode = d_inode(fhp->fh_dentry);
>  	const struct export_operations *export_ops = inode->i_sb->s_export_op;
>  
> -	if (!EX_ISSYNC(fhp->fh_export))
> -		return 0;
> -
>  	if (export_ops->commit_metadata)
>  		return export_ops->commit_metadata(inode);
>  	return sync_inode_metadata(inode, 1);
>  }
>  
> +static int
> +commit_metadata(struct svc_fh *fhp)
> +{
> +	struct inode *inode = d_inode(fhp->fh_dentry);
> +
> +	if (!EX_ISSYNC(fhp->fh_export))
> +		return 0;
> +	return commit_inode_metadata(inode);
> +}
> +
>  /*
>   * Go over the attributes and take care of the small differences between
>   * NFS semantics and what Linux expects.
> @@ -536,7 +542,10 @@ __be32 nfsd4_clone_file_range(struct file *src, u64 src_pos, struct file *dst,
>  		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);
> +		int status = commit_inode_metadata(file_inode(src));
> +
> +		if (!status)
> +			status = vfs_fsync_range(dst, dst_pos, dst_end, 0);

Hmmm.  Seeing as the source and destination inode were modified in
the same transaction on XFS, we only need one journal write to flush
them both. However, commit+fsync ends up doing:

	journal write (src+dst metadata)
	writeback data (dst data)
	  -> can dirty dst metadata
	journal write (dst metadata) or device cache flush (dst data)

So either way, we end up having to do multiple device cache flushes
and possibly multiple journal writes.

IOWs, This would be much more efficient as:

	fsync(dst)
	commit_inode_metadata(src)

as it would end up as:

	writeback data (dst data)
	journal write(src+dst metadata)

and the call to commit_inode_metadata(src) ends up being a no-op
with almost no overhead...

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] nfsd: Clone should commit src file metadata too
  2019-12-18 19:49 ` Dave Chinner
@ 2019-12-18 20:01   ` Trond Myklebust
  0 siblings, 0 replies; 3+ messages in thread
From: Trond Myklebust @ 2019-12-18 20:01 UTC (permalink / raw)
  To: david; +Cc: linux-nfs, bfields

On Thu, 2019-12-19 at 06:49 +1100, Dave Chinner wrote:
> 
> IOWs, This would be much more efficient as:
> 
> 	fsync(dst)
> 	commit_inode_metadata(src)
> 
> as it would end up as:
> 
> 	writeback data (dst data)
> 	journal write(src+dst metadata)
> 
> and the call to commit_inode_metadata(src) ends up being a no-op
> with almost no overhead...
> 

Thanks Dave! Fixed up in v2.

Cheers
  Trond
-- 
Trond Myklebust
Linux NFS client maintainer, Hammerspace
trond.myklebust@hammerspace.com



^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2019-12-18 20:01 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-18 17:37 [PATCH] nfsd: Clone should commit src file metadata too Trond Myklebust
2019-12-18 19:49 ` Dave Chinner
2019-12-18 20:01   ` Trond Myklebust

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).