Skip to contentSkip to conversation

Cross-subvolume reflink copy (BTRFS_IOC_CLONE over subvolume boundaries)

DISCUSSION Hubert Kario 2 participants 2 messages Feb 13, 2012 – Feb 14, 2012 Btrfs file system

lore
Share & tools
lore
#0 lore raw

It's been nearly a year since the patches needed to implement a reflink= ed copy=20
between subvolumes have been posted=20
(http://permalink.gmane.org/gmane.comp.file-systems.btrfs/9865 ) and I = still=20
get "Invalid cross-device link" error with Linux 3.2.4 while I try to d=
o a cp=20
--reflink between subvolumes.

This is a *very* useful feature to have (think offline file-level dedup= lication=20
for one thing).

=46rom what I was able to find in the archives, the only objection (use= rland=20
operation crossing subvolume boundaries) was rebutted by Chris Mason.=20

Is there something else that I missed?

Regards,
--=20
Hubert Kario
QBS - Quality Business Software
02-656 Warszawa, ul. Ksawer=F3w 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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#1 lore raw
Quoted 5 lines · Hubert Kario

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

fs/btrfs/ioctl.c +0 -0
index 0b06a5c..05dc644 100644
@@ -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)