]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blobdiff - fs/aufs/cpup.c
UBUNTU: SAUCE: aufs: for v4.5, use vfs_clone_file_range() in copy-up
[mirror_ubuntu-zesty-kernel.git] / fs / aufs / cpup.c
index 7112866b30ba232317577bc4e0e3c17e4f40de26..48e4d851155378c066ec79a67676beb5b0560497 100644 (file)
@@ -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)