]> git.baikalelectronics.ru Git - kernel.git/commitdiff
fs: allow cross-vfsmount reflink/dedupe
authorJosef Bacik <josef@toxicpanda.com>
Fri, 18 Feb 2022 14:38:14 +0000 (09:38 -0500)
committerDavid Sterba <dsterba@suse.com>
Mon, 14 Mar 2022 12:13:53 +0000 (13:13 +0100)
Currently we disallow reflink and dedupe if the two files aren't on the
same vfsmount.  However we really only need to disallow it if they're
not on the same super block.  It is very common for btrfs to have a main
subvolume that is mounted and then different subvolumes mounted at
different locations.  It's allowed to reflink between these volumes, but
the vfsmount check disallows this.  Instead fix dedupe to check for the
same superblock, and simply remove the vfsmount check for reflink as it
already does the superblock check.

Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/ioctl.c
fs/remap_range.c

index 1ed097e94af2dd093c3af3fc826aa6270c307337..090bf47606aba5ec14ff02622e2d1f6c0b723bb2 100644 (file)
@@ -236,9 +236,6 @@ static long ioctl_file_clone(struct file *dst_file, unsigned long srcfd,
 
        if (!src_file.file)
                return -EBADF;
-       ret = -EXDEV;
-       if (src_file.file->f_path.mnt != dst_file->f_path.mnt)
-               goto fdput;
        cloned = vfs_clone_file_range(src_file.file, off, dst_file, destoff,
                                      olen, 0);
        if (cloned < 0)
@@ -247,7 +244,6 @@ static long ioctl_file_clone(struct file *dst_file, unsigned long srcfd,
                ret = -EINVAL;
        else
                ret = 0;
-fdput:
        fdput(src_file);
        return ret;
 }
index 231159682907dfbf265b22951db9190ea7eb4678..bc5fb006dc7986b7255b860eb96b1da02f853c27 100644 (file)
@@ -362,11 +362,6 @@ loff_t do_clone_file_range(struct file *file_in, loff_t pos_in,
 
        WARN_ON_ONCE(remap_flags & REMAP_FILE_DEDUP);
 
-       /*
-        * FICLONE/FICLONERANGE ioctls enforce that src and dest files are on
-        * the same mount. Practically, they only need to be on the same file
-        * system.
-        */
        if (file_inode(file_in)->i_sb != file_inode(file_out)->i_sb)
                return -EXDEV;
 
@@ -458,7 +453,7 @@ loff_t vfs_dedupe_file_range_one(struct file *src_file, loff_t src_pos,
                goto out_drop_write;
 
        ret = -EXDEV;
-       if (src_file->f_path.mnt != dst_file->f_path.mnt)
+       if (file_inode(src_file)->i_sb != file_inode(dst_file)->i_sb)
                goto out_drop_write;
 
        ret = -EISDIR;