All of lore.kernel.org
 help / color / mirror / Atom feed
From: Amir Goldstein <amir73il@gmail.com>
To: Miklos Szeredi <miklos@szeredi.hu>,
	"Darrick J . Wong" <darrick.wong@oracle.com>
Cc: linux-unionfs@vger.kernel.org, linux-xfs@vger.kernel.org,
	linux-fsdevel@vger.kernel.org,
	Amir Goldstein <amir73il@gmail.com>
Subject: [PATCH] ovl: use copy_file_range for copy up if possible
Date: Thu,  8 Sep 2016 18:29:54 +0300	[thread overview]
Message-ID: <1473348594-31425-1-git-send-email-amir73il@gmail.com> (raw)

When copying up within the same fs, try to use f_op->copy_file_range().
This becomes very efficient when lower and upper are on the same fs
with file reflink support.

Tested correct behavior when lower and upper are on:
1. same ext4 (copy)
2. same xfs + reflink patches + mkfs.xfs (copy)
3. same xfs + reflink patches + mkfs.xfs -m reflink=1 (clone)
4. different xfs + reflink patches + mkfs.xfs -m reflink=1 (copy)

Verified that all the overlay xfstests pass in the 'same xfs+reflink'
setup.

For comparison, on my laptop, xfstest overlay/001 (copy up of large
sparse files) takes less than 1 second in the xfs reflink setup vs.
25 seconds on the rest of the setups.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
 fs/overlayfs/copy_up.c | 28 +++++++++++++++++++++++++---
 1 file changed, 25 insertions(+), 3 deletions(-)

diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
index 43fdc27..400567b 100644
--- a/fs/overlayfs/copy_up.c
+++ b/fs/overlayfs/copy_up.c
@@ -121,6 +121,7 @@ static int ovl_copy_up_data(struct path *old, struct path *new, loff_t len)
 	struct file *new_file;
 	loff_t old_pos = 0;
 	loff_t new_pos = 0;
+	int try_copy_file = 0;
 	int error = 0;
 
 	if (len == 0)
@@ -136,6 +137,13 @@ static int ovl_copy_up_data(struct path *old, struct path *new, loff_t len)
 		goto out_fput;
 	}
 
+	/*
+	 * When copying up within the same fs, try to use fs's copy_file_range
+	 */
+	if (file_inode(old_file)->i_sb == file_inode(new_file)->i_sb) {
+		try_copy_file = (new_file->f_op->copy_file_range != NULL);
+	}
+
 	/* FIXME: copy up sparse files efficiently */
 	while (len) {
 		size_t this_len = OVL_COPY_UP_CHUNK_SIZE;
@@ -149,9 +157,23 @@ static int ovl_copy_up_data(struct path *old, struct path *new, loff_t len)
 			break;
 		}
 
-		bytes = do_splice_direct(old_file, &old_pos,
-					 new_file, &new_pos,
-					 this_len, SPLICE_F_MOVE);
+		if (try_copy_file) {
+			bytes = new_file->f_op->copy_file_range(
+					old_file, old_pos,
+					new_file, new_pos,
+					len, 0);
+			if (bytes == -EOPNOTSUPP) {
+				try_copy_file = 0;
+				continue;
+			} else if (bytes > 0) {
+				old_pos += bytes;
+				new_pos += bytes;
+			}
+		} else {
+			bytes = do_splice_direct(old_file, &old_pos,
+					new_file, &new_pos,
+					this_len, SPLICE_F_MOVE);
+		}
 		if (bytes <= 0) {
 			error = bytes;
 			break;
-- 
2.7.4

             reply	other threads:[~2016-09-08 15:31 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-08 15:29 Amir Goldstein [this message]
2016-09-08 20:25 ` [PATCH] ovl: use copy_file_range for copy up if possible Dave Chinner
2016-09-09  7:31   ` Amir Goldstein
2016-09-09  7:54     ` Dave Chinner
2016-09-09  8:27       ` Amir Goldstein
2016-09-09 23:52         ` Dave Chinner
2016-09-10  7:40           ` Christoph Hellwig
2016-09-10 18:15             ` Amir Goldstein
2016-09-10 18:54           ` Amir Goldstein
2016-09-11 22:11             ` Dave Chinner
2016-09-12  6:52               ` Amir Goldstein
2016-09-12 15:37                 ` Amir Goldstein
2016-09-12 15:06 ` [PATCH v2 0/4] ovl: efficient copy up by reflink Amir Goldstein
2016-09-12 15:06   ` [PATCH v2 1/4] vfs: allow vfs_clone_file_range() across mount points Amir Goldstein
2016-09-12 15:06   ` [PATCH v2 2/4] ovl: use vfs_clone_file_range() for copy up if possible Amir Goldstein
2016-09-13  0:02     ` Dave Chinner
2016-09-13  6:47       ` Amir Goldstein
2016-09-12 15:06   ` [PATCH v2 3/4] vfs: allow vfs_copy_file_range() across file systems Amir Goldstein
2016-09-13  0:08     ` Dave Chinner
2016-09-13  7:01       ` Amir Goldstein
2016-09-12 15:06   ` [PATCH v2 4/4] ovl: use vfs_copy_file_range() to copy up file data Amir Goldstein
2016-09-13  0:11     ` Dave Chinner
2016-09-13  7:26       ` Amir Goldstein
2016-09-14 12:43         ` Amir Goldstein

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1473348594-31425-1-git-send-email-amir73il@gmail.com \
    --to=amir73il@gmail.com \
    --cc=darrick.wong@oracle.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-unionfs@vger.kernel.org \
    --cc=linux-xfs@vger.kernel.org \
    --cc=miklos@szeredi.hu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.