Skip to content

Commit

Permalink
fs: allow cross-vfsmount reflink/dedupe
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Josef Bacik authored and David Sterba committed Mar 14, 2022
1 parent ae460f0 commit 9f5710b
Show file tree
Hide file tree
Showing 2 changed files with 1 addition and 10 deletions.
4 changes: 0 additions & 4 deletions fs/ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
}
Expand Down
7 changes: 1 addition & 6 deletions fs/remap_range.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 9f5710b

Please sign in to comment.