aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-06-26 10:34:20 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:04 -0400
commita7a16fd772620605c76e8ac8bdbc8ccc9e3df1a0 (patch)
tree5dc173d7653ba4819ce1c853b9e84293422edf90 /fs/btrfs
parentf9efa9c784aa3b801feb367f72c6867d26fb348e (diff)
Btrfs: Fix deadlock while searching for dead roots on mount
btrfs_find_dead_roots called btrfs_read_fs_root_no_radix, which means we end up calling btrfs_search_slot with a path already held. The fix is to remember the key inside btrfs_find_dead_roots and drop the path. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/root-tree.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c
index 8bf21ba0a43b..a5c0e98b5aeb 100644
--- a/fs/btrfs/root-tree.c
+++ b/fs/btrfs/root-tree.c
@@ -154,6 +154,7 @@ int btrfs_find_dead_roots(struct btrfs_root *root, u64 objectid,
154 struct btrfs_item *item; 154 struct btrfs_item *item;
155 struct btrfs_root_item *ri; 155 struct btrfs_root_item *ri;
156 struct btrfs_key key; 156 struct btrfs_key key;
157 struct btrfs_key found_key;
157 struct btrfs_path *path; 158 struct btrfs_path *path;
158 int ret; 159 int ret;
159 u32 nritems; 160 u32 nritems;
@@ -166,6 +167,8 @@ int btrfs_find_dead_roots(struct btrfs_root *root, u64 objectid,
166 path = btrfs_alloc_path(); 167 path = btrfs_alloc_path();
167 if (!path) 168 if (!path)
168 return -ENOMEM; 169 return -ENOMEM;
170
171again:
169 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); 172 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
170 if (ret < 0) 173 if (ret < 0)
171 goto err; 174 goto err;
@@ -196,7 +199,11 @@ int btrfs_find_dead_roots(struct btrfs_root *root, u64 objectid,
196 if (btrfs_disk_root_refs(leaf, ri) != 0) 199 if (btrfs_disk_root_refs(leaf, ri) != 0)
197 goto next; 200 goto next;
198 201
199 dead_root = btrfs_read_fs_root_no_radix(root->fs_info, &key); 202 memcpy(&found_key, &key, sizeof(key));
203 key.offset++;
204 btrfs_release_path(root, path);
205 dead_root = btrfs_read_fs_root_no_radix(root->fs_info,
206 &found_key);
200 if (IS_ERR(dead_root)) { 207 if (IS_ERR(dead_root)) {
201 ret = PTR_ERR(dead_root); 208 ret = PTR_ERR(dead_root);
202 goto err; 209 goto err;
@@ -206,6 +213,7 @@ int btrfs_find_dead_roots(struct btrfs_root *root, u64 objectid,
206 &root->fs_info->dead_roots); 213 &root->fs_info->dead_roots);
207 if (ret) 214 if (ret)
208 goto err; 215 goto err;
216 goto again;
209next: 217next:
210 slot++; 218 slot++;
211 path->slots[0]++; 219 path->slots[0]++;