Skip to content

Commit

Permalink
btrfs: allow cross-subvolume file clone
Browse files Browse the repository at this point in the history
Lift the EXDEV condition and allow different root trees for files being
cloned, then pass source inode's root when searching for extents.
Cloning is not allowed to cross vfsmounts, ie. when two subvolumes from
one filesystem are mounted separately.

Signed-off-by: David Sterba <dsterba@suse.cz>
  • Loading branch information
kdave authored and Alexander Block committed Jul 25, 2012
1 parent 28a33cb commit 362a20c
Showing 1 changed file with 8 additions and 3 deletions.
11 changes: 8 additions & 3 deletions fs/btrfs/ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -2340,6 +2340,10 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
goto out_drop_write;
}

ret = -EXDEV;
if (src_file->f_path.mnt != file->f_path.mnt)
goto out_fput;

src = src_file->f_dentry->d_inode;

ret = -EINVAL;
Expand All @@ -2360,7 +2364,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
goto out_fput;

ret = -EXDEV;
if (src->i_sb != inode->i_sb || BTRFS_I(src)->root != root)
if (src->i_sb != inode->i_sb)
goto out_fput;

ret = -ENOMEM;
Expand Down Expand Up @@ -2434,13 +2438,14 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
* note the key will change type as we walk through the
* tree.
*/
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
ret = btrfs_search_slot(NULL, BTRFS_I(src)->root, &key, path,
0, 0);
if (ret < 0)
goto out;

nritems = btrfs_header_nritems(path->nodes[0]);
if (path->slots[0] >= nritems) {
ret = btrfs_next_leaf(root, path);
ret = btrfs_next_leaf(BTRFS_I(src)->root, path);
if (ret < 0)
goto out;
if (ret > 0)
Expand Down

0 comments on commit 362a20c

Please sign in to comment.