diff options
author | David Woodhouse <David.Woodhouse@intel.com> | 2008-08-19 17:20:17 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:06 -0400 |
commit | 2d4d9fbd6efa858dfa009518fca1ab85a73fd848 (patch) | |
tree | 81ac4d533be6eac033b551f20e6ee0b8a57c63b9 | |
parent | 615f996fb8185a0bc02812ebd72cb77ded5645f1 (diff) |
Btrfs: Fix NFS exporting of subvol roots.
Date: Tue, 19 Aug 2008 22:20:17 +0100
btrfs_lookup_fs_root() only finds subvol roots which have already been
seen and put into the cache. For btrfs_get_dentry() we actually have to
go to the medium -- so use btrfs_read_fs_root_no_name() instead.
In btrfs_get_parent(), notice when we've hit the root of the
subvolume and return the real root instead.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>
-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); |