aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/export.c
diff options
context:
space:
mode:
authorDavid Woodhouse <David.Woodhouse@intel.com>2008-08-19 17:33:04 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:06 -0400
commitd54a83901055bb0bffca64fa09fce4d897274870 (patch)
tree1fb297e08014eaf28416f4e4fe2058d1e6bb6e1b /fs/btrfs/export.c
parent2d4d9fbd6efa858dfa009518fca1ab85a73fd848 (diff)
Clean up btrfs_get_parent() a little more, fix a free-after-free bug
Date: Tue, 19 Aug 2008 22:33:04 +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.c31
1 files changed, 18 insertions, 13 deletions
diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c
index 36cbc6872fd0..292b0b24c302 100644
--- a/fs/btrfs/export.c
+++ b/fs/btrfs/export.c
@@ -165,23 +165,32 @@ static struct dentry *btrfs_get_parent(struct dentry *child)
165 key.offset = (u64)-1; 165 key.offset = (u64)-1;
166 166
167 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); 167 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
168 if (ret < 0) {
169 /* Error */
170 btrfs_free_path(path);
171 return ERR_PTR(ret);
172 }
168 leaf = path->nodes[0]; 173 leaf = path->nodes[0];
169 slot = path->slots[0]; 174 slot = path->slots[0];
170 if (ret < 0 || slot == 0) { 175 if (ret) {
171 btrfs_free_path(path); 176 /* btrfs_search_slot() returns the slot where we'd want to
172 goto out; 177 insert a backref for parent inode #0xFFFFFFFFFFFFFFFF.
178 The _real_ backref, telling us what the parent inode
179 _actually_ is, will be in the slot _before_ the one
180 that btrfs_search_slot() returns. */
181 if (!slot) {
182 /* Unless there is _no_ key in the tree before... */
183 btrfs_free_path(path);
184 return ERR_PTR(-EIO);
185 }
186 slot--;
173 } 187 }
174 /* btrfs_search_slot() returns the slot where we'd want to insert
175 an INODE_REF_KEY for parent inode #0xFFFFFFFFFFFFFFFF. The _real_
176 one, telling us what the parent inode _actually_ is, will be in
177 the slot _before_ the one that btrfs_search_slot() returns. */
178 slot--;
179 188
180 btrfs_item_key_to_cpu(leaf, &key, slot); 189 btrfs_item_key_to_cpu(leaf, &key, slot);
181 btrfs_free_path(path); 190 btrfs_free_path(path);
182 191
183 if (key.objectid != dir->i_ino || key.type != BTRFS_INODE_REF_KEY) 192 if (key.objectid != dir->i_ino || key.type != BTRFS_INODE_REF_KEY)
184 goto out; 193 return ERR_PTR(-EINVAL);
185 194
186 objectid = key.offset; 195 objectid = key.offset;
187 196
@@ -201,10 +210,6 @@ static struct dentry *btrfs_get_parent(struct dentry *child)
201 parent = ERR_PTR(-ENOMEM); 210 parent = ERR_PTR(-ENOMEM);
202 211
203 return parent; 212 return parent;
204
205out:
206 btrfs_free_path(path);
207 return ERR_PTR(-EINVAL);
208} 213}
209 214
210const struct export_operations btrfs_export_ops = { 215const struct export_operations btrfs_export_ops = {