diff options
author | David Woodhouse <David.Woodhouse@intel.com> | 2008-08-18 17:50:22 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:06 -0400 |
commit | 87acb4ef9b2991e1c453b78d71bce2ef994ef1ff (patch) | |
tree | 6c39d71ec4cbdf2cf95742b5b908ac1d882ea4d2 /fs/btrfs/export.c | |
parent | 32d48fa1af1fe066a6a4798e6f5a50ac6a3ce4a3 (diff) |
Simplify btrfs_get_parent(), fix use-after-free bug
Date: Mon, 18 Aug 2008 22:50:22 +0100
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 | 26 |
1 files changed, 11 insertions, 15 deletions
diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c index 797b4cbc3786..a913b9befe68 100644 --- a/fs/btrfs/export.c +++ b/fs/btrfs/export.c | |||
@@ -147,7 +147,6 @@ static struct dentry *btrfs_get_parent(struct dentry *child) | |||
147 | struct btrfs_key key; | 147 | struct btrfs_key key; |
148 | struct btrfs_path *path; | 148 | struct btrfs_path *path; |
149 | struct extent_buffer *leaf; | 149 | struct extent_buffer *leaf; |
150 | u32 nritems; | ||
151 | int slot; | 150 | int slot; |
152 | u64 objectid; | 151 | u64 objectid; |
153 | int ret; | 152 | int ret; |
@@ -156,27 +155,24 @@ static struct dentry *btrfs_get_parent(struct dentry *child) | |||
156 | 155 | ||
157 | key.objectid = dir->i_ino; | 156 | key.objectid = dir->i_ino; |
158 | btrfs_set_key_type(&key, BTRFS_INODE_REF_KEY); | 157 | btrfs_set_key_type(&key, BTRFS_INODE_REF_KEY); |
159 | key.offset = 0; | 158 | key.offset = (u64)-1; |
160 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | ||
161 | BUG_ON(ret == 0); | ||
162 | ret = 0; | ||
163 | 159 | ||
160 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | ||
164 | leaf = path->nodes[0]; | 161 | leaf = path->nodes[0]; |
165 | slot = path->slots[0]; | 162 | slot = path->slots[0]; |
166 | nritems = btrfs_header_nritems(leaf); | 163 | if (ret < 0 || slot == 0) { |
167 | if (slot >= nritems) { | 164 | btrfs_free_path(path); |
168 | ret = btrfs_next_leaf(root, path); | 165 | goto out; |
169 | if (ret) { | ||
170 | btrfs_free_path(path); | ||
171 | goto out; | ||
172 | } | ||
173 | leaf = path->nodes[0]; | ||
174 | slot = path->slots[0]; | ||
175 | } | 166 | } |
167 | /* btrfs_search_slot() returns the slot where we'd want to insert | ||
168 | an INODE_REF_KEY for parent inode #0xFFFFFFFFFFFFFFFF. The _real_ | ||
169 | one, telling us what the parent inode _actually_ is, will be in | ||
170 | the slot _before_ the one that btrfs_search_slot() returns. */ | ||
171 | slot--; | ||
176 | 172 | ||
173 | btrfs_item_key_to_cpu(leaf, &key, slot); | ||
177 | btrfs_free_path(path); | 174 | btrfs_free_path(path); |
178 | 175 | ||
179 | btrfs_item_key_to_cpu(leaf, &key, slot); | ||
180 | if (key.objectid != dir->i_ino || key.type != BTRFS_INODE_REF_KEY) | 176 | if (key.objectid != dir->i_ino || key.type != BTRFS_INODE_REF_KEY) |
181 | goto out; | 177 | goto out; |
182 | 178 | ||