From: Josef Bacik josef@toxicpanda.com
[ Upstream commit 932fd26df8125a5b14438563c4d3e33f59ba80f7 ]
We look up the fs root in various places in here when recovering from a crashed relcoation. Make sure we hold a ref on the root whenever we look them up.
Signed-off-by: Josef Bacik josef@toxicpanda.com Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/btrfs/relocation.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index f98913061a40c..377cf3785fbbd 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -4428,6 +4428,12 @@ int btrfs_recover_relocation(struct btrfs_root *root) err = ret; goto out; } + } else { + if (!btrfs_grab_fs_root(fs_root)) { + err = -ENOENT; + goto out; + } + btrfs_put_fs_root(fs_root); } }
@@ -4477,10 +4483,15 @@ int btrfs_recover_relocation(struct btrfs_root *root) list_add_tail(&reloc_root->root_list, &reloc_roots); goto out_free; } + if (!btrfs_grab_fs_root(fs_root)) { + err = -ENOENT; + goto out_free; + }
err = __add_reloc_root(reloc_root); BUG_ON(err < 0); /* -ENOMEM or logic error */ fs_root->reloc_root = reloc_root; + btrfs_put_fs_root(fs_root); }
err = btrfs_commit_transaction(trans); @@ -4508,10 +4519,14 @@ int btrfs_recover_relocation(struct btrfs_root *root) if (err == 0) { /* cleanup orphan inode in data relocation tree */ fs_root = read_fs_root(fs_info, BTRFS_DATA_RELOC_TREE_OBJECTID); - if (IS_ERR(fs_root)) + if (IS_ERR(fs_root)) { err = PTR_ERR(fs_root); - else - err = btrfs_orphan_cleanup(fs_root); + } else { + if (btrfs_grab_fs_root(fs_root)) { + err = btrfs_orphan_cleanup(fs_root); + btrfs_put_fs_root(fs_root); + } + } } return err; }