Vasily Tarasov: > Just to clarify, by "the fix won't be included in next Monday release" you > mean that you won't push this change to the public git until then? > > Sorry, I'm not too familiar with Aufs release policy...
Basically I release or used to release aufs every Monday. Needless to say, when there is nothing changed, the release will be skipped. I am testing for every release which takes several days. Now I am testing the patch I've sent (and found a problem). The whole test won't complete before next Monday. That's why "the fix won't be included in next Monday release." Here is a refined one. If you build aufs module by yourself. Use this. J. R. Okajima commit eaa5a0db8e6977c884cb0d3c99f30c91d3aaba50 Author: J. R. Okajima <hooanon...@gmail.com> Date: Fri Jun 9 07:44:36 2017 +0900 aufs: bugfix, copy-up using clone_file_range() on XFS branch XFS has its version and older one doesn't support clone_file_range(). It simply returns EOPNOTSUPP. Additionally XFS acquires inode_lock for a normal read(). This commit fixes the error path after trying clone_file_range(). Reported-by: Vasily Tarasov <tara...@vasily.name> See-also: http://www.mail-archive.com/aufs-users@lists.sourceforge.net/msg05498.html Signed-off-by: J. R. Okajima <hooanon...@gmail.com> diff --git a/fs/aufs/cpup.c b/fs/aufs/cpup.c index 125fef6..dd9f90a 100644 --- a/fs/aufs/cpup.c +++ b/fs/aufs/cpup.c @@ -352,6 +352,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. @@ -402,25 +455,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) ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot