[PATCH v2 zesty 1/2] UBUNTU: SAUCE: aufs: for v4.5, use vfs_clone_file_range() in copy-up
Seth Forshee
seth.forshee at canonical.com
Thu Aug 17 13:09:31 UTC 2017
From: "J. R. Okajima" <hooanon05g at gmail.com>
BugLink: http://bugs.launchpad.net/bugs/1709749
In mainline, ioctl(FICLONE) is introduced by the commit
04b38d6 2015-12-07 vfs: pull btrfs clone API to vfs layer
so are vfs_clone_file_ranage() and f_op->clone_file_ranage().
Compared to copy_file_range(2), cloning doesn't return with the partial
success. Using this method in aufs copy-up, the speed will be improved.
But unfortunately this method is supported by nfs4.2, btrfs and cifs
only (currently). Additionally, linux nfs server 4.2 implementation
simply calls vfs_clone_file_ranage(), which means if the backend fs
doesn't support this operation, it returns EOPNOTSUPP.
So the benefit is rather limited, but it must be a good thing.
Signed-off-by: J. R. Okajima <hooanon05g at gmail.com>
(backported from commit b4d3dcc92a13d53952fe6e9a640201ef87475302
https://github.com/sfjro/aufs4-standalone.git)
[saf: Resolved conflicts based primarily on resolution found in
fd18affa818115edad7e1b7472f26ac4d73e73a1]
Signed-off-by: Seth Forshee <seth.forshee at canonical.com>
---
fs/aufs/cpup.c | 25 ++++++++++++++++++++++---
fs/aufs/vfsub.h | 16 ++++++++++++++++
2 files changed, 38 insertions(+), 3 deletions(-)
diff --git a/fs/aufs/cpup.c b/fs/aufs/cpup.c
index 7112866b30ba..48e4d8511553 100644
--- a/fs/aufs/cpup.c
+++ b/fs/aufs/cpup.c
@@ -393,7 +393,7 @@ static int au_cp_regular(struct au_cp_generic *cpg)
.label = &&out_src
}
};
- struct super_block *sb;
+ struct super_block *sb, *h_src_sb;
struct inode *h_src_inode;
struct task_struct *tsk = current;
@@ -411,9 +411,28 @@ static int au_cp_regular(struct au_cp_generic *cpg)
/* try stopping to update while we copyup */
h_src_inode = d_inode(file[SRC].dentry);
- if (!au_test_nfs(h_src_inode->i_sb))
+ h_src_sb = h_src_inode->i_sb;
+ if (!au_test_nfs(h_src_sb))
IMustLock(h_src_inode);
- err = au_copy_file(file[DST].file, file[SRC].file, cpg->len);
+
+ if (h_src_sb != file_inode(file[DST].file)->i_sb
+ || !file[DST].file->f_op->clone_file_range)
+ err = au_copy_file(file[DST].file, file[SRC].file, cpg->len);
+ else {
+ if (!au_test_nfs(h_src_sb)) {
+ inode_unlock(h_src_inode);
+ err = vfsub_clone_file_range(file[SRC].file,
+ file[DST].file, cpg->len);
+ inode_lock(h_src_inode);
+ } else
+ err = vfsub_clone_file_range(file[SRC].file,
+ file[DST].file, cpg->len);
+ if (unlikely(err == -EOPNOTSUPP && au_test_nfs(h_src_sb)))
+ /* the backend fs on NFS may not support cloning */
+ err = au_copy_file(file[DST].file, file[SRC].file,
+ cpg->len);
+ AuTraceErr(err);
+ }
/* i wonder if we had O_NO_DELAY_FPUT flag */
if (tsk->flags & PF_KTHREAD)
diff --git a/fs/aufs/vfsub.h b/fs/aufs/vfsub.h
index 8fae3d491ddf..71d2bc47d5c9 100644
--- a/fs/aufs/vfsub.h
+++ b/fs/aufs/vfsub.h
@@ -266,6 +266,22 @@ int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
struct file *h_file);
int vfsub_fsync(struct file *file, struct path *path, int datasync);
+/*
+ * re-use branch fs's ioctl(FICLONE) while aufs itself doesn't support such
+ * ioctl.
+ */
+static inline int vfsub_clone_file_range(struct file *src, struct file *dst,
+ u64 len)
+{
+ int err;
+
+ lockdep_off();
+ err = vfs_clone_file_range(src, 0, dst, 0, len);
+ lockdep_on();
+
+ return err;
+}
+
/* ---------------------------------------------------------------------- */
static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin)
--
2.11.0
More information about the kernel-team
mailing list