Hubert Kario
2012-Feb-13 23:52 UTC
Cross-subvolume reflink copy (BTRFS_IOC_CLONE over subvolume boundaries)
It''s been nearly a year since the patches needed to implement a reflinked copy between subvolumes have been posted (http://permalink.gmane.org/gmane.comp.file-systems.btrfs/9865 ) and I still get "Invalid cross-device link" error with Linux 3.2.4 while I try to do a cp --reflink between subvolumes. This is a *very* useful feature to have (think offline file-level deduplication for one thing). From what I was able to find in the archives, the only objection (userland operation crossing subvolume boundaries) was rebutted by Chris Mason. Is there something else that I missed? Regards, -- Hubert Kario QBS - Quality Business Software 02-656 Warszawa, ul. Ksawerów 30/85 tel. +48 (22) 646-61-51, 646-74-24 www.qbs.com.pl -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Jérôme Poulin
2012-Feb-14 02:47 UTC
Re: Cross-subvolume reflink copy (BTRFS_IOC_CLONE over subvolume boundaries)
On Mon, Feb 13, 2012 at 6:52 PM, Hubert Kario <hka@qbs.com.pl> wrote:> It''s been nearly a year since the patches needed to implement a reflinked copy > between subvolumes have been posted > (http://permalink.gmane.org/gmane.comp.file-systems.btrfs/9865 ) and I still > get "Invalid cross-device link" error with Linux 3.2.4 while I try to do a cp > --reflink between subvolumes.I am still keeping this patch up-to-date in my personal kernel repo. Here is the diff from current for-linus BTRFS-Allow-cross-subvolume-BTRFS_IOC_CLONE.patch diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 0b06a5c..05dc644 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -2203,6 +2203,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, { struct inode *inode = fdentry(file)->d_inode; struct btrfs_root *root = BTRFS_I(inode)->root; + struct btrfs_root *srcroot; struct file *src_file; struct inode *src; struct btrfs_trans_handle *trans; @@ -2245,6 +2246,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, } src = src_file->f_dentry->d_inode; + srcroot = BTRFS_I(src)->root; ret = -EINVAL; if (src == inode) @@ -2264,11 +2266,11 @@ 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; - buf = vmalloc(btrfs_level_size(root, 0)); + buf = vmalloc(btrfs_level_size(srcroot, 0)); if (!buf) goto out_fput; @@ -2338,13 +2340,13 @@ 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, srcroot, &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(srcroot, path); if (ret < 0) goto out; if (ret > 0) -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html