From: Chris Mason Date: Thu, 26 Jun 2008 14:34:20 +0000 (-0400) Subject: Btrfs: Fix deadlock while searching for dead roots on mount X-Git-Tag: firefly_0821_release~15789^2~11^2~55^2~56^2~30^2~130 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=a7a16fd772620605c76e8ac8bdbc8ccc9e3df1a0;p=firefly-linux-kernel-4.4.55.git 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 --- 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, struct btrfs_item *item; struct btrfs_root_item *ri; struct btrfs_key key; + struct btrfs_key found_key; struct btrfs_path *path; int ret; u32 nritems; @@ -166,6 +167,8 @@ int btrfs_find_dead_roots(struct btrfs_root *root, u64 objectid, path = btrfs_alloc_path(); if (!path) return -ENOMEM; + +again: ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); if (ret < 0) goto err; @@ -196,7 +199,11 @@ int btrfs_find_dead_roots(struct btrfs_root *root, u64 objectid, if (btrfs_disk_root_refs(leaf, ri) != 0) goto next; - dead_root = btrfs_read_fs_root_no_radix(root->fs_info, &key); + memcpy(&found_key, &key, sizeof(key)); + key.offset++; + btrfs_release_path(root, path); + dead_root = btrfs_read_fs_root_no_radix(root->fs_info, + &found_key); if (IS_ERR(dead_root)) { ret = PTR_ERR(dead_root); goto err; @@ -206,6 +213,7 @@ int btrfs_find_dead_roots(struct btrfs_root *root, u64 objectid, &root->fs_info->dead_roots); if (ret) goto err; + goto again; next: slot++; path->slots[0]++;