diff options
author | David Woodhouse <David.Woodhouse@intel.com> | 2008-08-19 22:20:17 +0100 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:06 -0400 |
commit | 2d4d9fbd6efa858dfa009518fca1ab85a73fd848 (patch) | |
tree | 81ac4d533be6eac033b551f20e6ee0b8a57c63b9 /fs/btrfs/export.c | |
parent | 615f996fb8185a0bc02812ebd72cb77ded5645f1 (diff) | |
download | op-kernel-dev-2d4d9fbd6efa858dfa009518fca1ab85a73fd848.zip op-kernel-dev-2d4d9fbd6efa858dfa009518fca1ab85a73fd848.tar.gz |
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>
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 a913b9b..36cbc68 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, struct dentry *result; struct btrfs_key key; + key.objectid = root_objectid; + btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); + key.offset = (u64)-1; + + root = btrfs_read_fs_root_no_name(btrfs_sb(sb)->fs_info, &key); + if (IS_ERR(root)) + return ERR_CAST(root); + key.objectid = objectid; btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); key.offset = 0; - root = btrfs_lookup_fs_root(btrfs_sb(sb)->fs_info, root_objectid); inode = btrfs_iget(sb, &key, root, NULL); if (IS_ERR(inode)) return (void *)inode; @@ -178,6 +185,10 @@ static struct dentry *btrfs_get_parent(struct dentry *child) objectid = key.offset; + /* If we are already at the root of a subvol, return the real root */ + if (objectid == dir->i_ino) + return dget(dir->i_sb->s_root); + /* Build a new key for the inode item */ key.objectid = objectid; btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); |