[PATCH zesty 2/2] aufs: bugfix, for v4.10, copy-up on XFS branch

Seth Forshee seth.forshee at canonical.com
Mon Aug 14 12:44:32 UTC 2017


From: "J. R. Okajima" <hooanon05g at gmail.com>

BugLink: http://bugs.launchpad.net/bugs/1709749

The commit for linux-v4.10
	6552321 2016-11-30 xfs: remove i_iolock and use i_rwsem in the
				VFS inode instead
broke aufs' copy-up because XFS acquires inode_lock for a normal read().
Additionally XFS has its version and older one doesn't support
clone_file_range().
This commit fixes the error path after trying clone_file_range().

Reported-by: Vasily Tarasov <tarasov at vasily.name>
See-also: http://www.mail-archive.com/aufs-users@lists.sourceforge.net/msg05498.html
Signed-off-by: J. R. Okajima <hooanon05g at gmail.com>
(cherry picked from commit e34c81ff96415c64ca827ec30e7935454d26c1d3
 https://github.com/sfjro/aufs4-standalone.git)
Signed-off-by: Seth Forshee <seth.forshee at canonical.com>
---
 fs/aufs/cpup.c | 73 +++++++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 54 insertions(+), 19 deletions(-)

diff --git a/fs/aufs/cpup.c b/fs/aufs/cpup.c
index 48e4d8511553..76cbf949cdca 100644
--- a/fs/aufs/cpup.c
+++ b/fs/aufs/cpup.c
@@ -365,6 +365,59 @@ int au_copy_file(struct file *dst, struct file *src, loff_t len)
 	return err;
 }
 
+static int au_do_copy(struct file *dst, struct file *src, loff_t len)
+{
+	int err;
+	struct super_block *h_src_sb;
+	struct inode *h_src_inode;
+
+	h_src_inode = file_inode(src);
+	h_src_sb = h_src_inode->i_sb;
+
+	/* XFS acquires inode_lock */
+	if (!au_test_xfs(h_src_sb))
+		err = au_copy_file(dst, src, len);
+	else {
+		inode_unlock(h_src_inode);
+		err = au_copy_file(dst, src, len);
+		inode_lock(h_src_inode);
+	}
+
+	return err;
+}
+
+static int au_clone_or_copy(struct file *dst, struct file *src, loff_t len)
+{
+	int err;
+	struct super_block *h_src_sb;
+	struct inode *h_src_inode;
+
+	h_src_inode = file_inode(src);
+	h_src_sb = h_src_inode->i_sb;
+	if (h_src_sb != file_inode(dst)->i_sb
+	    || !dst->f_op->clone_file_range) {
+		err = au_do_copy(dst, src, len);
+		goto out;
+	}
+
+	if (!au_test_nfs(h_src_sb)) {
+		inode_unlock(h_src_inode);
+		err = vfsub_clone_file_range(src, dst, len);
+		inode_lock(h_src_inode);
+	} else
+		err = vfsub_clone_file_range(src, dst, len);
+	/* older XFS has a condition in cloning */
+	if (unlikely(err != -EOPNOTSUPP))
+		goto out;
+
+	/* the backend fs on NFS may not support cloning */
+	err = au_do_copy(dst, src, len);
+
+out:
+	AuTraceErr(err);
+	return err;
+}
+
 /*
  * to support a sparse file which is opened with O_APPEND,
  * we need to close the file.
@@ -414,25 +467,7 @@ static int au_cp_regular(struct au_cp_generic *cpg)
 	h_src_sb = h_src_inode->i_sb;
 	if (!au_test_nfs(h_src_sb))
 		IMustLock(h_src_inode);
-
-	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);
-	}
+	err = au_clone_or_copy(file[DST].file, file[SRC].file, cpg->len);
 
 	/* i wonder if we had O_NO_DELAY_FPUT flag */
 	if (tsk->flags & PF_KTHREAD)
-- 
2.11.0





More information about the kernel-team mailing list