diff options
Diffstat (limited to 'fs/btrfs/export.c')
-rw-r--r-- | fs/btrfs/export.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c index a913b9befe68..36cbc6872fd0 100644 --- a/fs/btrfs/export.c +++ b/fs/btrfs/export.c | |||
@@ -71,11 +71,18 @@ static struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid, | |||
71 | struct dentry *result; | 71 | struct dentry *result; |
72 | struct btrfs_key key; | 72 | struct btrfs_key key; |
73 | 73 | ||
74 | key.objectid = root_objectid; | ||
75 | btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); | ||
76 | key.offset = (u64)-1; | ||
77 | |||
78 | root = btrfs_read_fs_root_no_name(btrfs_sb(sb)->fs_info, &key); | ||
79 | if (IS_ERR(root)) | ||
80 | return ERR_CAST(root); | ||
81 | |||
74 | key.objectid = objectid; | 82 | key.objectid = objectid; |
75 | btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); | 83 | btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); |
76 | key.offset = 0; | 84 | key.offset = 0; |
77 | 85 | ||
78 | root = btrfs_lookup_fs_root(btrfs_sb(sb)->fs_info, root_objectid); | ||
79 | inode = btrfs_iget(sb, &key, root, NULL); | 86 | inode = btrfs_iget(sb, &key, root, NULL); |
80 | if (IS_ERR(inode)) | 87 | if (IS_ERR(inode)) |
81 | return (void *)inode; | 88 | return (void *)inode; |
@@ -178,6 +185,10 @@ static struct dentry *btrfs_get_parent(struct dentry *child) | |||
178 | 185 | ||
179 | objectid = key.offset; | 186 | objectid = key.offset; |
180 | 187 | ||
188 | /* If we are already at the root of a subvol, return the real root */ | ||
189 | if (objectid == dir->i_ino) | ||
190 | return dget(dir->i_sb->s_root); | ||
191 | |||
181 | /* Build a new key for the inode item */ | 192 | /* Build a new key for the inode item */ |
182 | key.objectid = objectid; | 193 | key.objectid = objectid; |
183 | btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); | 194 | btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); |