linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/44][v5] Cleanup how we handle root refs, part 1
@ 2020-01-24 14:32 Josef Bacik
  2020-01-24 14:32 ` [PATCH 01/44] btrfs: push __setup_root into btrfs_alloc_root Josef Bacik
                   ` (45 more replies)
  0 siblings, 46 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs

v4->v5:
- split out the btrfs_free_fs_info() moving around into it's own patch.
- updated a comment in btrfs_get_root() to describe why we are initializing part
  of the fs_info

v3->v4:
- "btrfs: hold a ref on the root in build_backref_tree" I fixed it so the
  backref nodes hold the ref for their respective roots, but I missed a case
  where we grab the reloc_root, and thus freed the reloc root too soon and it
  resulted in tears when I ran my stress testing on my tiny box.

v2->v3:
- Rebased onto the latest misc-next, so the snapshot aware defrag related
  patches got dropped.

v1->v2:
- Fixed a error missed put in an error condition in relink_extent_backref
- Added "btrfs: make the init of static elements in fs_info" so that we could
  clean up fs_info init and make the leak detectors work for the self tests.

-- original email --
In testing with the recent fsstress I stumbled upon a deadlock in how we deal
with disappearing subvolumes.  We sort of half-ass a srcu lock to protect us,
but it's used inconsistently so doesn't really provide us with actual
protection, mostly it just makes us feel good.

In order to do away with this srcu thing we need to have proper ref counting for
our roots.  We currently refcount them, but only to handle the actual kfree, it
doesn't really control the lifetime of the root.  And again, this is not done in
any sort of consistent manner so it doesn't actually protect us.

This is the first set of patches, and yes I realize there are a lot of them.
Most of them are just "hold a ref on the root" in all of the call sites that
called btrfs_read_fs_root*() variations.  Now that we're going to actually hold
references to roots we need to make sure we put the reference when we're done
with them, so these patches go through each callsite and make sure we drop the
references appropriately.

Then there's a variety of cleanups and consolidations to make things clearer and
make it so we only have 1 place to get roots.

Finally there's the root leak detection patch.  I used this with a bunch of
testing to make sure I was never leaking roots with these patches.  I've been
testing these for several weeks cleaning up all the corners, so they should be
in relatively good shape.  Most of the patches are small so straightforward to
review.

This is just part 1, this is the prep work we need to make the root lifetime a
little saner, and will allow us to drop the subvol srcu, as well as the inode
rbtree.  It doesn't really fundamentally change how roots are handled other than
making the refcounting actually protect us from freeing the root while we're
using it.  That work will come later.  Thanks,

Josef



^ permalink raw reply	[flat|nested] 63+ messages in thread

* [PATCH 01/44] btrfs: push __setup_root into btrfs_alloc_root
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-02-04 22:05   ` David Sterba
  2020-01-24 14:32 ` [PATCH 02/44] btrfs: move fs root init stuff into btrfs_init_fs_root Josef Bacik
                   ` (44 subsequent siblings)
  45 siblings, 1 reply; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs; +Cc: Nikolay Borisov

There's no reason to not init the root at alloc time, and with later
patches it actually causes problems if we error out mounting the fs
before the tree_root is init'ed because we expect it to have a valid ref
count.  Fix this by pushing __setup_root into btrfs_alloc_root.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
---
 fs/btrfs/disk-io.c | 34 +++++++++++++---------------------
 1 file changed, 13 insertions(+), 21 deletions(-)

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 5ce2801f8388..1dc33e95052b 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1130,6 +1130,7 @@ static void __setup_root(struct btrfs_root *root, struct btrfs_fs_info *fs_info,
 			 u64 objectid)
 {
 	bool dummy = test_bit(BTRFS_FS_STATE_DUMMY_FS_INFO, &fs_info->fs_state);
+	root->fs_info = fs_info;
 	root->node = NULL;
 	root->commit_root = NULL;
 	root->state = 0;
@@ -1198,11 +1199,11 @@ static void __setup_root(struct btrfs_root *root, struct btrfs_fs_info *fs_info,
 }
 
 static struct btrfs_root *btrfs_alloc_root(struct btrfs_fs_info *fs_info,
-		gfp_t flags)
+					   u64 objectid, gfp_t flags)
 {
 	struct btrfs_root *root = kzalloc(sizeof(*root), flags);
 	if (root)
-		root->fs_info = fs_info;
+		__setup_root(root, fs_info, objectid);
 	return root;
 }
 
@@ -1215,12 +1216,11 @@ struct btrfs_root *btrfs_alloc_dummy_root(struct btrfs_fs_info *fs_info)
 	if (!fs_info)
 		return ERR_PTR(-EINVAL);
 
-	root = btrfs_alloc_root(fs_info, GFP_KERNEL);
+	root = btrfs_alloc_root(fs_info, BTRFS_ROOT_TREE_OBJECTID, GFP_KERNEL);
 	if (!root)
 		return ERR_PTR(-ENOMEM);
 
 	/* We don't use the stripesize in selftest, set it as sectorsize */
-	__setup_root(root, fs_info, BTRFS_ROOT_TREE_OBJECTID);
 	root->alloc_bytenr = 0;
 
 	return root;
@@ -1244,12 +1244,11 @@ struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans,
 	 * context to avoid deadlock if reclaim happens.
 	 */
 	nofs_flag = memalloc_nofs_save();
-	root = btrfs_alloc_root(fs_info, GFP_KERNEL);
+	root = btrfs_alloc_root(fs_info, objectid, GFP_KERNEL);
 	memalloc_nofs_restore(nofs_flag);
 	if (!root)
 		return ERR_PTR(-ENOMEM);
 
-	__setup_root(root, fs_info, objectid);
 	root->root_key.objectid = objectid;
 	root->root_key.type = BTRFS_ROOT_ITEM_KEY;
 	root->root_key.offset = 0;
@@ -1309,12 +1308,10 @@ static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans,
 	struct btrfs_root *root;
 	struct extent_buffer *leaf;
 
-	root = btrfs_alloc_root(fs_info, GFP_NOFS);
+	root = btrfs_alloc_root(fs_info, BTRFS_TREE_LOG_OBJECTID, GFP_NOFS);
 	if (!root)
 		return ERR_PTR(-ENOMEM);
 
-	__setup_root(root, fs_info, BTRFS_TREE_LOG_OBJECTID);
-
 	root->root_key.objectid = BTRFS_TREE_LOG_OBJECTID;
 	root->root_key.type = BTRFS_ROOT_ITEM_KEY;
 	root->root_key.offset = BTRFS_TREE_LOG_OBJECTID;
@@ -1401,14 +1398,12 @@ static struct btrfs_root *btrfs_read_tree_root(struct btrfs_root *tree_root,
 	if (!path)
 		return ERR_PTR(-ENOMEM);
 
-	root = btrfs_alloc_root(fs_info, GFP_NOFS);
+	root = btrfs_alloc_root(fs_info, key->objectid, GFP_NOFS);
 	if (!root) {
 		ret = -ENOMEM;
 		goto alloc_fail;
 	}
 
-	__setup_root(root, fs_info, key->objectid);
-
 	ret = btrfs_find_root(tree_root, key, path,
 			      &root->root_item, &root->root_key);
 	if (ret) {
@@ -2208,12 +2203,11 @@ static int btrfs_replay_log(struct btrfs_fs_info *fs_info,
 		return -EIO;
 	}
 
-	log_tree_root = btrfs_alloc_root(fs_info, GFP_KERNEL);
+	log_tree_root = btrfs_alloc_root(fs_info, BTRFS_TREE_LOG_OBJECTID,
+					 GFP_KERNEL);
 	if (!log_tree_root)
 		return -ENOMEM;
 
-	__setup_root(log_tree_root, fs_info, BTRFS_TREE_LOG_OBJECTID);
-
 	log_tree_root->node = read_tree_block(fs_info, bytenr,
 					      fs_info->generation + 1,
 					      level, NULL);
@@ -2645,8 +2639,10 @@ int __cold open_ctree(struct super_block *sb,
 	int clear_free_space_tree = 0;
 	int level;
 
-	tree_root = fs_info->tree_root = btrfs_alloc_root(fs_info, GFP_KERNEL);
-	chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info, GFP_KERNEL);
+	tree_root = fs_info->tree_root = btrfs_alloc_root(fs_info,
+					BTRFS_ROOT_TREE_OBJECTID, GFP_KERNEL);
+	chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info,
+					BTRFS_CHUNK_TREE_OBJECTID, GFP_KERNEL);
 	if (!tree_root || !chunk_root) {
 		err = -ENOMEM;
 		goto fail;
@@ -2825,8 +2821,6 @@ int __cold open_ctree(struct super_block *sb,
 		goto fail_alloc;
 	}
 
-	__setup_root(tree_root, fs_info, BTRFS_ROOT_TREE_OBJECTID);
-
 	invalidate_bdev(fs_devices->latest_bdev);
 
 	/*
@@ -3022,8 +3016,6 @@ int __cold open_ctree(struct super_block *sb,
 	generation = btrfs_super_chunk_root_generation(disk_super);
 	level = btrfs_super_chunk_root_level(disk_super);
 
-	__setup_root(chunk_root, fs_info, BTRFS_CHUNK_TREE_OBJECTID);
-
 	chunk_root->node = read_tree_block(fs_info,
 					   btrfs_super_chunk_root(disk_super),
 					   generation, level, NULL);
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 02/44] btrfs: move fs root init stuff into btrfs_init_fs_root
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
  2020-01-24 14:32 ` [PATCH 01/44] btrfs: push __setup_root into btrfs_alloc_root Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:32 ` [PATCH 03/44] btrfs: make btrfs_find_orphan_roots use btrfs_get_fs_root Josef Bacik
                   ` (43 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs; +Cc: Nikolay Borisov

We have a helper for reading fs roots that just reads the fs root off
the disk and then sets REF_COWS and init's the inheritable flags.  Move
this into btrfs_init_fs_root so we can later get rid of this helper and
consolidate all of the fs root reading into one helper.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
---
 fs/btrfs/disk-io.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 1dc33e95052b..2d378aafb70b 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1445,12 +1445,6 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_root *tree_root,
 	root = btrfs_read_tree_root(tree_root, location);
 	if (IS_ERR(root))
 		return root;
-
-	if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) {
-		set_bit(BTRFS_ROOT_REF_COWS, &root->state);
-		btrfs_check_and_init_root_item(&root->root_item);
-	}
-
 	return root;
 }
 
@@ -1474,6 +1468,11 @@ int btrfs_init_fs_root(struct btrfs_root *root)
 	}
 	root->subv_writers = writers;
 
+	if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) {
+		set_bit(BTRFS_ROOT_REF_COWS, &root->state);
+		btrfs_check_and_init_root_item(&root->root_item);
+	}
+
 	btrfs_init_free_ino_ctl(root);
 	spin_lock_init(&root->ino_cache_lock);
 	init_waitqueue_head(&root->ino_cache_wait);
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 03/44] btrfs: make btrfs_find_orphan_roots use btrfs_get_fs_root
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
  2020-01-24 14:32 ` [PATCH 01/44] btrfs: push __setup_root into btrfs_alloc_root Josef Bacik
  2020-01-24 14:32 ` [PATCH 02/44] btrfs: move fs root init stuff into btrfs_init_fs_root Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:32 ` [PATCH 04/44] btrfs: export and use btrfs_read_tree_root Josef Bacik
                   ` (42 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs; +Cc: Nikolay Borisov

btrfs_find_orphan_roots has this weird thing where it looks up the root
in cache to see if it is there before just reading the root.  But the
read it uses just reads the root, it doesn't do any of the init work, we
do that by hand here.  But this is unnecessary, all we really want is to
see if the root still exists and add it to the dead roots list to be
cleaned up, otherwise we delete the orphan item.

Fix this by just using btrfs_get_fs_root directly with check_ref set to
false so we get the orphan root items.  Then we just handle in cache and
out of cache roots the same, add them to the dead roots list and carry
on.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
---
 fs/btrfs/root-tree.c | 37 +++----------------------------------
 1 file changed, 3 insertions(+), 34 deletions(-)

diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c
index 612411c74550..094a71c54fa1 100644
--- a/fs/btrfs/root-tree.c
+++ b/fs/btrfs/root-tree.c
@@ -255,25 +255,7 @@ int btrfs_find_orphan_roots(struct btrfs_fs_info *fs_info)
 		root_key.objectid = key.offset;
 		key.offset++;
 
-		/*
-		 * The root might have been inserted already, as before we look
-		 * for orphan roots, log replay might have happened, which
-		 * triggers a transaction commit and qgroup accounting, which
-		 * in turn reads and inserts fs roots while doing backref
-		 * walking.
-		 */
-		root = btrfs_lookup_fs_root(fs_info, root_key.objectid);
-		if (root) {
-			WARN_ON(!test_bit(BTRFS_ROOT_ORPHAN_ITEM_INSERTED,
-					  &root->state));
-			if (btrfs_root_refs(&root->root_item) == 0) {
-				set_bit(BTRFS_ROOT_DEAD_TREE, &root->state);
-				btrfs_add_dead_root(root);
-			}
-			continue;
-		}
-
-		root = btrfs_read_fs_root(tree_root, &root_key);
+		root = btrfs_get_fs_root(fs_info, &root_key, false);
 		err = PTR_ERR_OR_ZERO(root);
 		if (err && err != -ENOENT) {
 			break;
@@ -300,21 +282,8 @@ int btrfs_find_orphan_roots(struct btrfs_fs_info *fs_info)
 			continue;
 		}
 
-		err = btrfs_init_fs_root(root);
-		if (err) {
-			btrfs_free_fs_root(root);
-			break;
-		}
-
-		set_bit(BTRFS_ROOT_ORPHAN_ITEM_INSERTED, &root->state);
-
-		err = btrfs_insert_fs_root(fs_info, root);
-		if (err) {
-			BUG_ON(err == -EEXIST);
-			btrfs_free_fs_root(root);
-			break;
-		}
-
+		WARN_ON(!test_bit(BTRFS_ROOT_ORPHAN_ITEM_INSERTED,
+				  &root->state));
 		if (btrfs_root_refs(&root->root_item) == 0) {
 			set_bit(BTRFS_ROOT_DEAD_TREE, &root->state);
 			btrfs_add_dead_root(root);
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 04/44] btrfs: export and use btrfs_read_tree_root
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (2 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 03/44] btrfs: make btrfs_find_orphan_roots use btrfs_get_fs_root Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:32 ` [PATCH 05/44] btrfs: make relocation use btrfs_read_tree_root() Josef Bacik
                   ` (41 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs; +Cc: Nikolay Borisov

log-tree uses btrfs_read_fs_root to load its log, but this just calls
btrfs_read_tree_root.  We don't save the log roots in our root cache, so
just export this helper and use it in the logging code.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
---
 fs/btrfs/disk-io.c  | 4 ++--
 fs/btrfs/disk-io.h  | 2 ++
 fs/btrfs/tree-log.c | 2 +-
 3 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 2d378aafb70b..136a4d9d5fed 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1384,8 +1384,8 @@ int btrfs_add_log_tree(struct btrfs_trans_handle *trans,
 	return 0;
 }
 
-static struct btrfs_root *btrfs_read_tree_root(struct btrfs_root *tree_root,
-					       struct btrfs_key *key)
+struct btrfs_root *btrfs_read_tree_root(struct btrfs_root *tree_root,
+					struct btrfs_key *key)
 {
 	struct btrfs_root *root;
 	struct btrfs_fs_info *fs_info = tree_root->fs_info;
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
index 8c2d6cf1ce59..158fec0eeef2 100644
--- a/fs/btrfs/disk-io.h
+++ b/fs/btrfs/disk-io.h
@@ -58,6 +58,8 @@ struct buffer_head *btrfs_read_dev_super(struct block_device *bdev);
 int btrfs_read_dev_one_super(struct block_device *bdev, int copy_num,
 			struct buffer_head **bh_ret);
 int btrfs_commit_super(struct btrfs_fs_info *fs_info);
+struct btrfs_root *btrfs_read_tree_root(struct btrfs_root *tree_root,
+					struct btrfs_key *key);
 struct btrfs_root *btrfs_read_fs_root(struct btrfs_root *tree_root,
 				      struct btrfs_key *location);
 int btrfs_init_fs_root(struct btrfs_root *root);
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index a2bae5c230e1..e6e4b00cb46c 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -6101,7 +6101,7 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
 		if (found_key.objectid != BTRFS_TREE_LOG_OBJECTID)
 			break;
 
-		log = btrfs_read_fs_root(log_root_tree, &found_key);
+		log = btrfs_read_tree_root(log_root_tree, &found_key);
 		if (IS_ERR(log)) {
 			ret = PTR_ERR(log);
 			btrfs_handle_fs_error(fs_info, ret,
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 05/44] btrfs: make relocation use btrfs_read_tree_root()
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (3 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 04/44] btrfs: export and use btrfs_read_tree_root Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:32 ` [PATCH 06/44] btrfs: kill btrfs_read_fs_root Josef Bacik
                   ` (40 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs; +Cc: Nikolay Borisov

Relocation has it's special roots, we don't want to save these in the
root cache either, so swap it to use btrfs_read_tree_roo().  However the
reloc root does need REF_COWS set, so make sure we set it everywhere we
use this helper, as it no longer does the REF_COWS setting.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
---
 fs/btrfs/relocation.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 995d4b8b1cfd..aa3aa8e0c0ea 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -1447,8 +1447,9 @@ static struct btrfs_root *create_reloc_root(struct btrfs_trans_handle *trans,
 	BUG_ON(ret);
 	kfree(root_item);
 
-	reloc_root = btrfs_read_fs_root(fs_info->tree_root, &root_key);
+	reloc_root = btrfs_read_tree_root(fs_info->tree_root, &root_key);
 	BUG_ON(IS_ERR(reloc_root));
+	set_bit(BTRFS_ROOT_REF_COWS, &reloc_root->state);
 	reloc_root->last_trans = trans->transid;
 	return reloc_root;
 }
@@ -4537,12 +4538,13 @@ int btrfs_recover_relocation(struct btrfs_root *root)
 		    key.type != BTRFS_ROOT_ITEM_KEY)
 			break;
 
-		reloc_root = btrfs_read_fs_root(root, &key);
+		reloc_root = btrfs_read_tree_root(root, &key);
 		if (IS_ERR(reloc_root)) {
 			err = PTR_ERR(reloc_root);
 			goto out;
 		}
 
+		set_bit(BTRFS_ROOT_REF_COWS, &reloc_root->state);
 		list_add(&reloc_root->root_list, &reloc_roots);
 
 		if (btrfs_root_refs(&reloc_root->root_item) > 0) {
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 06/44] btrfs: kill btrfs_read_fs_root
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (4 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 05/44] btrfs: make relocation use btrfs_read_tree_root() Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:32 ` [PATCH 07/44] btrfs: kill the btrfs_read_fs_root_no_name helper Josef Bacik
                   ` (39 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs; +Cc: Nikolay Borisov

All helpers should either be using btrfs_get_fs_root() or
btrfs_read_tree_root().

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
---
 fs/btrfs/disk-io.c | 13 +------------
 fs/btrfs/disk-io.h |  2 --
 2 files changed, 1 insertion(+), 14 deletions(-)

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 136a4d9d5fed..99755d013dab 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1437,17 +1437,6 @@ struct btrfs_root *btrfs_read_tree_root(struct btrfs_root *tree_root,
 	goto out;
 }
 
-struct btrfs_root *btrfs_read_fs_root(struct btrfs_root *tree_root,
-				      struct btrfs_key *location)
-{
-	struct btrfs_root *root;
-
-	root = btrfs_read_tree_root(tree_root, location);
-	if (IS_ERR(root))
-		return root;
-	return root;
-}
-
 int btrfs_init_fs_root(struct btrfs_root *root)
 {
 	int ret;
@@ -1568,7 +1557,7 @@ struct btrfs_root *btrfs_get_fs_root(struct btrfs_fs_info *fs_info,
 		return root;
 	}
 
-	root = btrfs_read_fs_root(fs_info->tree_root, location);
+	root = btrfs_read_tree_root(fs_info->tree_root, location);
 	if (IS_ERR(root))
 		return root;
 
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
index 158fec0eeef2..4e43bd37f9c5 100644
--- a/fs/btrfs/disk-io.h
+++ b/fs/btrfs/disk-io.h
@@ -60,8 +60,6 @@ int btrfs_read_dev_one_super(struct block_device *bdev, int copy_num,
 int btrfs_commit_super(struct btrfs_fs_info *fs_info);
 struct btrfs_root *btrfs_read_tree_root(struct btrfs_root *tree_root,
 					struct btrfs_key *key);
-struct btrfs_root *btrfs_read_fs_root(struct btrfs_root *tree_root,
-				      struct btrfs_key *location);
 int btrfs_init_fs_root(struct btrfs_root *root);
 struct btrfs_root *btrfs_lookup_fs_root(struct btrfs_fs_info *fs_info,
 					u64 root_id);
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 07/44] btrfs: kill the btrfs_read_fs_root_no_name helper
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (5 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 06/44] btrfs: kill btrfs_read_fs_root Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:32 ` [PATCH 08/44] btrfs: make the fs root init functions static Josef Bacik
                   ` (38 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs; +Cc: Nikolay Borisov

All this does is call btrfs_get_fs_root() with check_ref == true.  Just
use btrfs_get_fs_root() so we don't have a bunch of different helpers
that do the same thing.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
---
 fs/btrfs/disk-io.c     |  2 +-
 fs/btrfs/disk-io.h     |  6 ------
 fs/btrfs/export.c      |  2 +-
 fs/btrfs/file.c        |  2 +-
 fs/btrfs/inode.c       |  2 +-
 fs/btrfs/ioctl.c       | 12 ++++++------
 fs/btrfs/scrub.c       |  2 +-
 fs/btrfs/send.c        |  4 ++--
 fs/btrfs/super.c       |  2 +-
 fs/btrfs/transaction.c |  2 +-
 fs/btrfs/tree-log.c    |  2 +-
 fs/btrfs/volumes.c     |  2 +-
 12 files changed, 17 insertions(+), 23 deletions(-)

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 99755d013dab..d13791ccb4f6 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -3176,7 +3176,7 @@ int __cold open_ctree(struct super_block *sb,
 	location.type = BTRFS_ROOT_ITEM_KEY;
 	location.offset = 0;
 
-	fs_info->fs_root = btrfs_read_fs_root_no_name(fs_info, &location);
+	fs_info->fs_root = btrfs_get_fs_root(fs_info, &location, true);
 	if (IS_ERR(fs_info->fs_root)) {
 		err = PTR_ERR(fs_info->fs_root);
 		btrfs_warn(fs_info, "failed to read fs tree: %d", err);
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
index 4e43bd37f9c5..c2e765edf034 100644
--- a/fs/btrfs/disk-io.h
+++ b/fs/btrfs/disk-io.h
@@ -70,12 +70,6 @@ void btrfs_free_fs_roots(struct btrfs_fs_info *fs_info);
 struct btrfs_root *btrfs_get_fs_root(struct btrfs_fs_info *fs_info,
 				     struct btrfs_key *key,
 				     bool check_ref);
-static inline struct btrfs_root *
-btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info,
-			   struct btrfs_key *location)
-{
-	return btrfs_get_fs_root(fs_info, location, true);
-}
 
 int btrfs_cleanup_fs_roots(struct btrfs_fs_info *fs_info);
 void btrfs_btree_balance_dirty(struct btrfs_fs_info *fs_info);
diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c
index 72e312cae69d..08cd8c4a02a5 100644
--- a/fs/btrfs/export.c
+++ b/fs/btrfs/export.c
@@ -77,7 +77,7 @@ static struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid,
 
 	index = srcu_read_lock(&fs_info->subvol_srcu);
 
-	root = btrfs_read_fs_root_no_name(fs_info, &key);
+	root = btrfs_get_fs_root(fs_info, &key, true);
 	if (IS_ERR(root)) {
 		err = PTR_ERR(root);
 		goto fail;
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index a16da274c9aa..565ae8404e1c 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -287,7 +287,7 @@ static int __btrfs_run_defrag_inode(struct btrfs_fs_info *fs_info,
 
 	index = srcu_read_lock(&fs_info->subvol_srcu);
 
-	inode_root = btrfs_read_fs_root_no_name(fs_info, &key);
+	inode_root = btrfs_get_fs_root(fs_info, &key, true);
 	if (IS_ERR(inode_root)) {
 		ret = PTR_ERR(inode_root);
 		goto cleanup;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 6d2bb58d277a..8cd1b11c3151 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -5021,7 +5021,7 @@ static int fixup_tree_root_location(struct btrfs_fs_info *fs_info,
 
 	btrfs_release_path(path);
 
-	new_root = btrfs_read_fs_root_no_name(fs_info, location);
+	new_root = btrfs_get_fs_root(fs_info, location, true);
 	if (IS_ERR(new_root)) {
 		err = PTR_ERR(new_root);
 		goto out;
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 0fa1c386d020..958c0245c363 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -666,7 +666,7 @@ static noinline int create_subvol(struct inode *dir,
 		goto fail;
 
 	key.offset = (u64)-1;
-	new_root = btrfs_read_fs_root_no_name(fs_info, &key);
+	new_root = btrfs_get_fs_root(fs_info, &key, true);
 	if (IS_ERR(new_root)) {
 		ret = PTR_ERR(new_root);
 		btrfs_abort_transaction(trans, ret);
@@ -2179,7 +2179,7 @@ static noinline int search_ioctl(struct inode *inode,
 		key.objectid = sk->tree_id;
 		key.type = BTRFS_ROOT_ITEM_KEY;
 		key.offset = (u64)-1;
-		root = btrfs_read_fs_root_no_name(info, &key);
+		root = btrfs_get_fs_root(info, &key, true);
 		if (IS_ERR(root)) {
 			btrfs_free_path(path);
 			return PTR_ERR(root);
@@ -2314,7 +2314,7 @@ static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info,
 	key.objectid = tree_id;
 	key.type = BTRFS_ROOT_ITEM_KEY;
 	key.offset = (u64)-1;
-	root = btrfs_read_fs_root_no_name(info, &key);
+	root = btrfs_get_fs_root(info, &key, true);
 	if (IS_ERR(root)) {
 		ret = PTR_ERR(root);
 		goto out;
@@ -2408,7 +2408,7 @@ static int btrfs_search_path_in_tree_user(struct inode *inode,
 		key.objectid = treeid;
 		key.type = BTRFS_ROOT_ITEM_KEY;
 		key.offset = (u64)-1;
-		root = btrfs_read_fs_root_no_name(fs_info, &key);
+		root = btrfs_get_fs_root(fs_info, &key, true);
 		if (IS_ERR(root)) {
 			ret = PTR_ERR(root);
 			goto out;
@@ -2653,7 +2653,7 @@ static int btrfs_ioctl_get_subvol_info(struct file *file, void __user *argp)
 	key.objectid = BTRFS_I(inode)->root->root_key.objectid;
 	key.type = BTRFS_ROOT_ITEM_KEY;
 	key.offset = (u64)-1;
-	root = btrfs_read_fs_root_no_name(fs_info, &key);
+	root = btrfs_get_fs_root(fs_info, &key, true);
 	if (IS_ERR(root)) {
 		ret = PTR_ERR(root);
 		goto out;
@@ -3980,7 +3980,7 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp)
 	location.type = BTRFS_ROOT_ITEM_KEY;
 	location.offset = (u64)-1;
 
-	new_root = btrfs_read_fs_root_no_name(fs_info, &location);
+	new_root = btrfs_get_fs_root(fs_info, &location, true);
 	if (IS_ERR(new_root)) {
 		ret = PTR_ERR(new_root);
 		goto out;
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index 22cf69e6e5bc..b5f420456439 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -653,7 +653,7 @@ static int scrub_print_warning_inode(u64 inum, u64 offset, u64 root,
 	root_key.objectid = root;
 	root_key.type = BTRFS_ROOT_ITEM_KEY;
 	root_key.offset = (u64)-1;
-	local_root = btrfs_read_fs_root_no_name(fs_info, &root_key);
+	local_root = btrfs_get_fs_root(fs_info, &root_key, true);
 	if (IS_ERR(local_root)) {
 		ret = PTR_ERR(local_root);
 		goto err;
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 091e5bc8c7ea..57eae56dd743 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -7194,7 +7194,7 @@ long btrfs_ioctl_send(struct file *mnt_file, struct btrfs_ioctl_send_args *arg)
 
 			index = srcu_read_lock(&fs_info->subvol_srcu);
 
-			clone_root = btrfs_read_fs_root_no_name(fs_info, &key);
+			clone_root = btrfs_get_fs_root(fs_info, &key, true);
 			if (IS_ERR(clone_root)) {
 				srcu_read_unlock(&fs_info->subvol_srcu, index);
 				ret = PTR_ERR(clone_root);
@@ -7233,7 +7233,7 @@ long btrfs_ioctl_send(struct file *mnt_file, struct btrfs_ioctl_send_args *arg)
 
 		index = srcu_read_lock(&fs_info->subvol_srcu);
 
-		sctx->parent_root = btrfs_read_fs_root_no_name(fs_info, &key);
+		sctx->parent_root = btrfs_get_fs_root(fs_info, &key, true);
 		if (IS_ERR(sctx->parent_root)) {
 			srcu_read_unlock(&fs_info->subvol_srcu, index);
 			ret = PTR_ERR(sctx->parent_root);
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index a906315efd19..3118bc01321e 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -1096,7 +1096,7 @@ static char *get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info,
 		key.objectid = subvol_objectid;
 		key.type = BTRFS_ROOT_ITEM_KEY;
 		key.offset = (u64)-1;
-		fs_root = btrfs_read_fs_root_no_name(fs_info, &key);
+		fs_root = btrfs_get_fs_root(fs_info, &key, true);
 		if (IS_ERR(fs_root)) {
 			ret = PTR_ERR(fs_root);
 			goto err;
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 55d8fd68775a..e194d3e4e3a9 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -1631,7 +1631,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
 	}
 
 	key.offset = (u64)-1;
-	pending->snap = btrfs_read_fs_root_no_name(fs_info, &key);
+	pending->snap = btrfs_get_fs_root(fs_info, &key, true);
 	if (IS_ERR(pending->snap)) {
 		ret = PTR_ERR(pending->snap);
 		btrfs_abort_transaction(trans, ret);
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index e6e4b00cb46c..db803765b500 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -6113,7 +6113,7 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
 		tmp_key.type = BTRFS_ROOT_ITEM_KEY;
 		tmp_key.offset = (u64)-1;
 
-		wc.replay_dest = btrfs_read_fs_root_no_name(fs_info, &tmp_key);
+		wc.replay_dest = btrfs_get_fs_root(fs_info, &tmp_key, true);
 		if (IS_ERR(wc.replay_dest)) {
 			ret = PTR_ERR(wc.replay_dest);
 
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 3d5714bf2e32..ce3eff93c366 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -4375,7 +4375,7 @@ static int btrfs_check_uuid_tree_entry(struct btrfs_fs_info *fs_info,
 	key.objectid = subid;
 	key.type = BTRFS_ROOT_ITEM_KEY;
 	key.offset = (u64)-1;
-	subvol_root = btrfs_read_fs_root_no_name(fs_info, &key);
+	subvol_root = btrfs_get_fs_root(fs_info, &key, true);
 	if (IS_ERR(subvol_root)) {
 		ret = PTR_ERR(subvol_root);
 		if (ret == -ENOENT)
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 08/44] btrfs: make the fs root init functions static
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (6 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 07/44] btrfs: kill the btrfs_read_fs_root_no_name helper Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:32 ` [PATCH 09/44] btrfs: handle NULL roots in btrfs_put/btrfs_grab_fs_root Josef Bacik
                   ` (37 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs; +Cc: Nikolay Borisov

Now that the orphan cleanup stuff doesn't use this directly we can just
make them static.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
---
 fs/btrfs/disk-io.c | 6 +++---
 fs/btrfs/disk-io.h | 3 ---
 2 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index d13791ccb4f6..f030ff87ed18 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1437,7 +1437,7 @@ struct btrfs_root *btrfs_read_tree_root(struct btrfs_root *tree_root,
 	goto out;
 }
 
-int btrfs_init_fs_root(struct btrfs_root *root)
+static int btrfs_init_fs_root(struct btrfs_root *root)
 {
 	int ret;
 	struct btrfs_subvolume_writers *writers;
@@ -1488,8 +1488,8 @@ int btrfs_init_fs_root(struct btrfs_root *root)
 	return ret;
 }
 
-struct btrfs_root *btrfs_lookup_fs_root(struct btrfs_fs_info *fs_info,
-					u64 root_id)
+static struct btrfs_root *btrfs_lookup_fs_root(struct btrfs_fs_info *fs_info,
+					       u64 root_id)
 {
 	struct btrfs_root *root;
 
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
index c2e765edf034..7aa1c7a3a115 100644
--- a/fs/btrfs/disk-io.h
+++ b/fs/btrfs/disk-io.h
@@ -60,9 +60,6 @@ int btrfs_read_dev_one_super(struct block_device *bdev, int copy_num,
 int btrfs_commit_super(struct btrfs_fs_info *fs_info);
 struct btrfs_root *btrfs_read_tree_root(struct btrfs_root *tree_root,
 					struct btrfs_key *key);
-int btrfs_init_fs_root(struct btrfs_root *root);
-struct btrfs_root *btrfs_lookup_fs_root(struct btrfs_fs_info *fs_info,
-					u64 root_id);
 int btrfs_insert_fs_root(struct btrfs_fs_info *fs_info,
 			 struct btrfs_root *root);
 void btrfs_free_fs_roots(struct btrfs_fs_info *fs_info);
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 09/44] btrfs: handle NULL roots in btrfs_put/btrfs_grab_fs_root
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (7 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 08/44] btrfs: make the fs root init functions static Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:32 ` [PATCH 10/44] btrfs: hold a ref on fs roots while they're in the radix tree Josef Bacik
                   ` (36 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs; +Cc: Nikolay Borisov

We want to use this for dropping all roots, and in some error cases we
may not have a root, so handle this to make the cleanup code easier.
Make btrfs_grab_fs_root the same so we can use it in cases where the
root may not exist (like the quota root).

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
---
 fs/btrfs/disk-io.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
index 7aa1c7a3a115..8add2e14aab1 100644
--- a/fs/btrfs/disk-io.h
+++ b/fs/btrfs/disk-io.h
@@ -88,6 +88,8 @@ struct btrfs_root *btrfs_alloc_dummy_root(struct btrfs_fs_info *fs_info);
  */
 static inline struct btrfs_root *btrfs_grab_fs_root(struct btrfs_root *root)
 {
+	if (!root)
+		return NULL;
 	if (refcount_inc_not_zero(&root->refs))
 		return root;
 	return NULL;
@@ -95,6 +97,8 @@ static inline struct btrfs_root *btrfs_grab_fs_root(struct btrfs_root *root)
 
 static inline void btrfs_put_fs_root(struct btrfs_root *root)
 {
+	if (!root)
+		return;
 	if (refcount_dec_and_test(&root->refs))
 		kfree(root);
 }
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 10/44] btrfs: hold a ref on fs roots while they're in the radix tree
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (8 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 09/44] btrfs: handle NULL roots in btrfs_put/btrfs_grab_fs_root Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:32 ` [PATCH 11/44] btrfs: hold a ref on the root in resolve_indirect_ref Josef Bacik
                   ` (35 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs; +Cc: Nikolay Borisov

If we're sitting in the radix tree, we should probably have a ref for
the radix tree.  Grab a ref on the root when we insert it, and drop it
when it gets deleted.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
---
 fs/btrfs/disk-io.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index f030ff87ed18..5f672f016ed8 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1513,8 +1513,10 @@ int btrfs_insert_fs_root(struct btrfs_fs_info *fs_info,
 	ret = radix_tree_insert(&fs_info->fs_roots_radix,
 				(unsigned long)root->root_key.objectid,
 				root);
-	if (ret == 0)
+	if (ret == 0) {
+		btrfs_grab_fs_root(root);
 		set_bit(BTRFS_ROOT_IN_RADIX, &root->state);
+	}
 	spin_unlock(&fs_info->fs_roots_radix_lock);
 	radix_tree_preload_end();
 
@@ -3814,6 +3816,8 @@ void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info,
 	spin_lock(&fs_info->fs_roots_radix_lock);
 	radix_tree_delete(&fs_info->fs_roots_radix,
 			  (unsigned long)root->root_key.objectid);
+	if (test_and_clear_bit(BTRFS_ROOT_IN_RADIX, &root->state))
+		btrfs_put_fs_root(root);
 	spin_unlock(&fs_info->fs_roots_radix_lock);
 
 	if (btrfs_root_refs(&root->root_item) == 0)
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 11/44] btrfs: hold a ref on the root in resolve_indirect_ref
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (9 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 10/44] btrfs: hold a ref on fs roots while they're in the radix tree Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:32 ` [PATCH 12/44] btrfs: hold a root ref in btrfs_get_dentry Josef Bacik
                   ` (34 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs

We're looking up a random root, we need to hold a ref on it while we're
using it.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/backref.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index e5d85311d5d5..193747b6e1f9 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -524,7 +524,13 @@ static int resolve_indirect_ref(struct btrfs_fs_info *fs_info,
 	if (IS_ERR(root)) {
 		srcu_read_unlock(&fs_info->subvol_srcu, index);
 		ret = PTR_ERR(root);
-		goto out;
+		goto out_free;
+	}
+
+	if (!btrfs_grab_fs_root(root)) {
+		srcu_read_unlock(&fs_info->subvol_srcu, index);
+		ret = -ENOENT;
+		goto out_free;
 	}
 
 	if (btrfs_is_testing(fs_info)) {
@@ -577,6 +583,8 @@ static int resolve_indirect_ref(struct btrfs_fs_info *fs_info,
 	ret = add_all_parents(root, path, parents, ref, level, time_seq,
 			      extent_item_pos, total_refs, ignore_offset);
 out:
+	btrfs_put_fs_root(root);
+out_free:
 	path->lowest_level = 0;
 	btrfs_release_path(path);
 	return ret;
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 12/44] btrfs: hold a root ref in btrfs_get_dentry
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (10 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 11/44] btrfs: hold a ref on the root in resolve_indirect_ref Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:32 ` [PATCH 13/44] btrfs: hold a ref on the root in __btrfs_run_defrag_inode Josef Bacik
                   ` (33 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs

Looking up the inode we need to search the root, make sure we hold a
reference on that root while we're doing the lookup.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/export.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c
index 08cd8c4a02a5..eba6c6d27bad 100644
--- a/fs/btrfs/export.c
+++ b/fs/btrfs/export.c
@@ -82,12 +82,17 @@ static struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid,
 		err = PTR_ERR(root);
 		goto fail;
 	}
+	if (!btrfs_grab_fs_root(root)) {
+		err = -ENOENT;
+		goto fail;
+	}
 
 	key.objectid = objectid;
 	key.type = BTRFS_INODE_ITEM_KEY;
 	key.offset = 0;
 
 	inode = btrfs_iget(sb, &key, root);
+	btrfs_put_fs_root(root);
 	if (IS_ERR(inode)) {
 		err = PTR_ERR(inode);
 		goto fail;
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 13/44] btrfs: hold a ref on the root in __btrfs_run_defrag_inode
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (11 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 12/44] btrfs: hold a root ref in btrfs_get_dentry Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:32 ` [PATCH 14/44] btrfs: hold a ref on the root in fixup_tree_root_location Josef Bacik
                   ` (32 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs

We are looking up an arbitrary inode, we need to hold a ref on the root
while we're doing this.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/file.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 565ae8404e1c..3abc7986052b 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -292,11 +292,16 @@ static int __btrfs_run_defrag_inode(struct btrfs_fs_info *fs_info,
 		ret = PTR_ERR(inode_root);
 		goto cleanup;
 	}
+	if (!btrfs_grab_fs_root(inode_root)) {
+		ret = -ENOENT;
+		goto cleanup;
+	}
 
 	key.objectid = defrag->ino;
 	key.type = BTRFS_INODE_ITEM_KEY;
 	key.offset = 0;
 	inode = btrfs_iget(fs_info->sb, &key, inode_root);
+	btrfs_put_fs_root(inode_root);
 	if (IS_ERR(inode)) {
 		ret = PTR_ERR(inode);
 		goto cleanup;
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 14/44] btrfs: hold a ref on the root in fixup_tree_root_location
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (12 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 13/44] btrfs: hold a ref on the root in __btrfs_run_defrag_inode Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:32 ` [PATCH 15/44] btrfs: hold a ref on the root in create_subvol Josef Bacik
                   ` (31 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs

Looking up the inode from an arbitrary tree means we need to hold a ref
on that root.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/inode.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 8cd1b11c3151..85104886c1e7 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -5026,6 +5026,10 @@ static int fixup_tree_root_location(struct btrfs_fs_info *fs_info,
 		err = PTR_ERR(new_root);
 		goto out;
 	}
+	if (!btrfs_grab_fs_root(new_root)) {
+		err = -ENOENT;
+		goto out;
+	}
 
 	*sub_root = new_root;
 	location->objectid = btrfs_root_dirid(&new_root->root_item);
@@ -5268,6 +5272,8 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)
 	} else {
 		inode = btrfs_iget(dir->i_sb, &location, sub_root);
 	}
+	if (root != sub_root)
+		btrfs_put_fs_root(sub_root);
 	srcu_read_unlock(&fs_info->subvol_srcu, index);
 
 	if (!IS_ERR(inode) && root != sub_root) {
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 15/44] btrfs: hold a ref on the root in create_subvol
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (13 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 14/44] btrfs: hold a ref on the root in fixup_tree_root_location Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:32 ` [PATCH 16/44] btrfs: hold a ref on the root in search_ioctl Josef Bacik
                   ` (30 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs

We're creating the new root here, but we should hold the ref until after
we've initialized the inode for it.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/ioctl.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 958c0245c363..b1d74cb09cb4 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -672,10 +672,16 @@ static noinline int create_subvol(struct inode *dir,
 		btrfs_abort_transaction(trans, ret);
 		goto fail;
 	}
+	if (!btrfs_grab_fs_root(new_root)) {
+		ret = -ENOENT;
+		btrfs_abort_transaction(trans, ret);
+		goto fail;
+	}
 
 	btrfs_record_root_in_trans(trans, new_root);
 
 	ret = btrfs_create_subvol_root(trans, new_root, root, new_dirid);
+	btrfs_put_fs_root(new_root);
 	if (ret) {
 		/* We potentially lose an unused inode item here */
 		btrfs_abort_transaction(trans, ret);
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 16/44] btrfs: hold a ref on the root in search_ioctl
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (14 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 15/44] btrfs: hold a ref on the root in create_subvol Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:32 ` [PATCH 17/44] btrfs: hold a ref on the root in btrfs_search_path_in_tree Josef Bacik
                   ` (29 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs

We lookup a arbitrary fs root, we need to hold a ref on that root.  If
we're using our own inodes root then grab a ref on that as well to make
the cleanup easier.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/ioctl.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index b1d74cb09cb4..62dd06b65686 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -2180,7 +2180,7 @@ static noinline int search_ioctl(struct inode *inode,
 
 	if (sk->tree_id == 0) {
 		/* search the root of the inode that was passed */
-		root = BTRFS_I(inode)->root;
+		root = btrfs_grab_fs_root(BTRFS_I(inode)->root);
 	} else {
 		key.objectid = sk->tree_id;
 		key.type = BTRFS_ROOT_ITEM_KEY;
@@ -2190,6 +2190,10 @@ static noinline int search_ioctl(struct inode *inode,
 			btrfs_free_path(path);
 			return PTR_ERR(root);
 		}
+		if (!btrfs_grab_fs_root(root)) {
+			btrfs_free_path(path);
+			return -ENOENT;
+		}
 	}
 
 	key.objectid = sk->min_objectid;
@@ -2214,6 +2218,7 @@ static noinline int search_ioctl(struct inode *inode,
 		ret = 0;
 err:
 	sk->nr_items = num_found;
+	btrfs_put_fs_root(root);
 	btrfs_free_path(path);
 	return ret;
 }
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 17/44] btrfs: hold a ref on the root in btrfs_search_path_in_tree
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (15 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 16/44] btrfs: hold a ref on the root in search_ioctl Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-02-05 14:30   ` David Sterba
  2020-01-24 14:32 ` [PATCH 18/44] btrfs: hold a ref on the root in btrfs_search_path_in_tree_user Josef Bacik
                   ` (28 subsequent siblings)
  45 siblings, 1 reply; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs

We look up an arbitrary fs root, we need to hold a ref on it while we're
doing our search.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/ioctl.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 62dd06b65686..c721b4fce1c0 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -2328,6 +2328,12 @@ static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info,
 	root = btrfs_get_fs_root(info, &key, true);
 	if (IS_ERR(root)) {
 		ret = PTR_ERR(root);
+		root = NULL;
+		goto out;
+	}
+	if (!btrfs_grab_fs_root(root)) {
+		ret = -ENOENT;
+		root = NULL;
 		goto out;
 	}
 
@@ -2378,6 +2384,8 @@ static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info,
 	name[total_len] = '\0';
 	ret = 0;
 out:
+	if (root)
+		btrfs_put_fs_root(root);
 	btrfs_free_path(path);
 	return ret;
 }
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 18/44] btrfs: hold a ref on the root in btrfs_search_path_in_tree_user
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (16 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 17/44] btrfs: hold a ref on the root in btrfs_search_path_in_tree Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-02-05 14:37   ` David Sterba
  2020-01-24 14:32 ` [PATCH 19/44] btrfs: hold a ref on the root in btrfs_ioctl_get_subvol_info Josef Bacik
                   ` (27 subsequent siblings)
  45 siblings, 1 reply; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs

We can wander into a different root, so grab a ref on the root we look
up.  Later on we make root = fs_info->tree_root so we need this separate
out label to make sure we do the right cleanup only in the case we're
looking up a different root.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/ioctl.c | 28 ++++++++++++++++++----------
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index c721b4fce1c0..5fffa1b6f685 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -2432,6 +2432,10 @@ static int btrfs_search_path_in_tree_user(struct inode *inode,
 			ret = PTR_ERR(root);
 			goto out;
 		}
+		if (!btrfs_grab_fs_root(root)) {
+			ret = -ENOENT;
+			goto out;
+		}
 
 		key.objectid = dirid;
 		key.type = BTRFS_INODE_REF_KEY;
@@ -2439,15 +2443,15 @@ static int btrfs_search_path_in_tree_user(struct inode *inode,
 		while (1) {
 			ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
 			if (ret < 0) {
-				goto out;
+				goto out_put;
 			} else if (ret > 0) {
 				ret = btrfs_previous_item(root, path, dirid,
 							  BTRFS_INODE_REF_KEY);
 				if (ret < 0) {
-					goto out;
+					goto out_put;
 				} else if (ret > 0) {
 					ret = -ENOENT;
-					goto out;
+					goto out_put;
 				}
 			}
 
@@ -2461,7 +2465,7 @@ static int btrfs_search_path_in_tree_user(struct inode *inode,
 			total_len += len + 1;
 			if (ptr < args->path) {
 				ret = -ENAMETOOLONG;
-				goto out;
+				goto out_put;
 			}
 
 			*(ptr + len) = '/';
@@ -2472,10 +2476,10 @@ static int btrfs_search_path_in_tree_user(struct inode *inode,
 			ret = btrfs_previous_item(root, path, dirid,
 						  BTRFS_INODE_ITEM_KEY);
 			if (ret < 0) {
-				goto out;
+				goto out_put;
 			} else if (ret > 0) {
 				ret = -ENOENT;
-				goto out;
+				goto out_put;
 			}
 
 			leaf = path->nodes[0];
@@ -2483,26 +2487,26 @@ static int btrfs_search_path_in_tree_user(struct inode *inode,
 			btrfs_item_key_to_cpu(leaf, &key2, slot);
 			if (key2.objectid != dirid) {
 				ret = -ENOENT;
-				goto out;
+				goto out_put;
 			}
 
 			temp_inode = btrfs_iget(sb, &key2, root);
 			if (IS_ERR(temp_inode)) {
 				ret = PTR_ERR(temp_inode);
-				goto out;
+				goto out_put;
 			}
 			ret = inode_permission(temp_inode, MAY_READ | MAY_EXEC);
 			iput(temp_inode);
 			if (ret) {
 				ret = -EACCES;
-				goto out;
+				goto out_put;
 			}
 
 			if (key.offset == upper_limit.objectid)
 				break;
 			if (key.objectid == BTRFS_FIRST_FREE_OBJECTID) {
 				ret = -EACCES;
-				goto out;
+				goto out_put;
 			}
 
 			btrfs_release_path(path);
@@ -2513,6 +2517,7 @@ static int btrfs_search_path_in_tree_user(struct inode *inode,
 
 		memmove(args->path, ptr, total_len);
 		args->path[total_len] = '\0';
+		btrfs_put_fs_root(root);
 		btrfs_release_path(path);
 	}
 
@@ -2551,6 +2556,9 @@ static int btrfs_search_path_in_tree_user(struct inode *inode,
 out:
 	btrfs_free_path(path);
 	return ret;
+out_put:
+	btrfs_put_fs_root(root);
+	goto out;
 }
 
 static noinline int btrfs_ioctl_ino_lookup(struct file *file,
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 19/44] btrfs: hold a ref on the root in btrfs_ioctl_get_subvol_info
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (17 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 18/44] btrfs: hold a ref on the root in btrfs_search_path_in_tree_user Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:32 ` [PATCH 20/44] btrfs: hold ref on root in btrfs_ioctl_default_subvol Josef Bacik
                   ` (26 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs

We look up whatever root userspace has given us, we need to hold a ref
throughout this operation.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/ioctl.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 5fffa1b6f685..7d30c7821490 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -2683,6 +2683,10 @@ static int btrfs_ioctl_get_subvol_info(struct file *file, void __user *argp)
 	root = btrfs_get_fs_root(fs_info, &key, true);
 	if (IS_ERR(root)) {
 		ret = PTR_ERR(root);
+		goto out_free;
+	}
+	if (!btrfs_grab_fs_root(root)) {
+		ret = -ENOENT;
 		goto out;
 	}
 	root_item = &root->root_item;
@@ -2760,6 +2764,8 @@ static int btrfs_ioctl_get_subvol_info(struct file *file, void __user *argp)
 		ret = -EFAULT;
 
 out:
+	btrfs_put_fs_root(root);
+out_free:
 	btrfs_free_path(path);
 	kzfree(subvol_info);
 	return ret;
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 20/44] btrfs: hold ref on root in btrfs_ioctl_default_subvol
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (18 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 19/44] btrfs: hold a ref on the root in btrfs_ioctl_get_subvol_info Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:32 ` [PATCH 21/44] btrfs: hold a ref on the root in build_backref_tree Josef Bacik
                   ` (25 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs

We look up an arbitrary fs root here, we need to hold a ref on the root
for the duration.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/ioctl.c | 22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 7d30c7821490..69c39b3d15a5 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -3987,7 +3987,7 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp)
 	struct btrfs_root *new_root;
 	struct btrfs_dir_item *di;
 	struct btrfs_trans_handle *trans;
-	struct btrfs_path *path;
+	struct btrfs_path *path = NULL;
 	struct btrfs_key location;
 	struct btrfs_disk_key disk_key;
 	u64 objectid = 0;
@@ -4018,44 +4018,50 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp)
 		ret = PTR_ERR(new_root);
 		goto out;
 	}
-	if (!is_fstree(new_root->root_key.objectid)) {
+	if (!btrfs_grab_fs_root(root)) {
 		ret = -ENOENT;
 		goto out;
 	}
+	if (!is_fstree(new_root->root_key.objectid)) {
+		ret = -ENOENT;
+		goto out_free;
+	}
 
 	path = btrfs_alloc_path();
 	if (!path) {
 		ret = -ENOMEM;
-		goto out;
+		goto out_free;
 	}
 	path->leave_spinning = 1;
 
 	trans = btrfs_start_transaction(root, 1);
 	if (IS_ERR(trans)) {
-		btrfs_free_path(path);
 		ret = PTR_ERR(trans);
-		goto out;
+		goto out_free;
 	}
 
 	dir_id = btrfs_super_root_dir(fs_info->super_copy);
 	di = btrfs_lookup_dir_item(trans, fs_info->tree_root, path,
 				   dir_id, "default", 7, 1);
 	if (IS_ERR_OR_NULL(di)) {
-		btrfs_free_path(path);
+		btrfs_release_path(path);
 		btrfs_end_transaction(trans);
 		btrfs_err(fs_info,
 			  "Umm, you don't have the default diritem, this isn't going to work");
 		ret = -ENOENT;
-		goto out;
+		goto out_free;
 	}
 
 	btrfs_cpu_key_to_disk(&disk_key, &new_root->root_key);
 	btrfs_set_dir_item_key(path->nodes[0], di, &disk_key);
 	btrfs_mark_buffer_dirty(path->nodes[0]);
-	btrfs_free_path(path);
+	btrfs_release_path(path);
 
 	btrfs_set_fs_incompat(fs_info, DEFAULT_SUBVOL);
 	btrfs_end_transaction(trans);
+out_free:
+	btrfs_put_fs_root(new_root);
+	btrfs_free_path(path);
 out:
 	mnt_drop_write_file(file);
 	return ret;
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 21/44] btrfs: hold a ref on the root in build_backref_tree
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (19 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 20/44] btrfs: hold ref on root in btrfs_ioctl_default_subvol Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-02-05 14:46   ` David Sterba
  2020-01-24 14:32 ` [PATCH 22/44] btrfs: hold a ref on the root in prepare_to_merge Josef Bacik
                   ` (24 subsequent siblings)
  45 siblings, 1 reply; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs

This is trickier than the previous conversions.  We have backref_node's
that need to hold onto their root for their lifetime.  Do the read of
the root and grab the ref.  If at any point we don't use the root we
discard it, however if we use it in our backref node we don't free it
until we free the backref node.  Any time we switch the root's for the
backref node we need to drop our ref on the old root and grab the ref on
the new root, and if we dupe a node we need to get a ref on the root
there as well.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/relocation.c | 39 ++++++++++++++++++++++++++++++---------
 1 file changed, 30 insertions(+), 9 deletions(-)

diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index aa3aa8e0c0ea..990595a27a15 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -256,6 +256,8 @@ static void free_backref_node(struct backref_cache *cache,
 {
 	if (node) {
 		cache->nr_nodes--;
+		if (node->root)
+			btrfs_put_fs_root(node->root);
 		kfree(node);
 	}
 }
@@ -589,7 +591,7 @@ static struct btrfs_root *find_reloc_root(struct reloc_control *rc,
 		root = (struct btrfs_root *)node->data;
 	}
 	spin_unlock(&rc->reloc_root_tree.lock);
-	return root;
+	return btrfs_grab_fs_root(root);
 }
 
 static int is_cowonly_root(u64 root_objectid)
@@ -891,6 +893,10 @@ struct backref_node *build_backref_tree(struct reloc_control *rc,
 			err = PTR_ERR(root);
 			goto out;
 		}
+		if (!btrfs_grab_fs_root(root)) {
+			err = -ENOENT;
+			goto out;
+		}
 
 		if (!test_bit(BTRFS_ROOT_REF_COWS, &root->state))
 			cur->cowonly = 1;
@@ -899,10 +905,12 @@ struct backref_node *build_backref_tree(struct reloc_control *rc,
 			/* tree root */
 			ASSERT(btrfs_root_bytenr(&root->root_item) ==
 			       cur->bytenr);
-			if (should_ignore_root(root))
+			if (should_ignore_root(root)) {
+				btrfs_put_fs_root(root);
 				list_add(&cur->list, &useless);
-			else
+			} else {
 				cur->root = root;
+			}
 			break;
 		}
 
@@ -915,6 +923,7 @@ struct backref_node *build_backref_tree(struct reloc_control *rc,
 		ret = btrfs_search_slot(NULL, root, node_key, path2, 0, 0);
 		path2->lowest_level = 0;
 		if (ret < 0) {
+			btrfs_put_fs_root(root);
 			err = ret;
 			goto out;
 		}
@@ -930,6 +939,7 @@ struct backref_node *build_backref_tree(struct reloc_control *rc,
 				  root->root_key.objectid,
 				  node_key->objectid, node_key->type,
 				  node_key->offset);
+			btrfs_put_fs_root(root);
 			err = -ENOENT;
 			goto out;
 		}
@@ -941,15 +951,18 @@ struct backref_node *build_backref_tree(struct reloc_control *rc,
 			if (!path2->nodes[level]) {
 				ASSERT(btrfs_root_bytenr(&root->root_item) ==
 				       lower->bytenr);
-				if (should_ignore_root(root))
+				if (should_ignore_root(root)) {
+					btrfs_put_fs_root(root);
 					list_add(&lower->list, &useless);
-				else
+				} else {
 					lower->root = root;
+				}
 				break;
 			}
 
 			edge = alloc_backref_edge(cache);
 			if (!edge) {
+				btrfs_put_fs_root(root);
 				err = -ENOMEM;
 				goto out;
 			}
@@ -959,6 +972,7 @@ struct backref_node *build_backref_tree(struct reloc_control *rc,
 			if (!rb_node) {
 				upper = alloc_backref_node(cache);
 				if (!upper) {
+					btrfs_put_fs_root(root);
 					free_backref_edge(cache, edge);
 					err = -ENOMEM;
 					goto out;
@@ -1006,8 +1020,10 @@ struct backref_node *build_backref_tree(struct reloc_control *rc,
 			edge->node[LOWER] = lower;
 			edge->node[UPPER] = upper;
 
-			if (rb_node)
+			if (rb_node) {
+				btrfs_put_fs_root(root);
 				break;
+			}
 			lower = upper;
 			upper = NULL;
 		}
@@ -1244,7 +1260,8 @@ static int clone_backref_node(struct btrfs_trans_handle *trans,
 	new_node->level = node->level;
 	new_node->lowest = node->lowest;
 	new_node->checked = 1;
-	new_node->root = dest;
+	new_node->root = btrfs_grab_fs_root(dest);
+	ASSERT(new_node->root);
 
 	if (!node->lowest) {
 		list_for_each_entry(edge, &node->lower, list[UPPER]) {
@@ -2622,7 +2639,9 @@ struct btrfs_root *select_reloc_root(struct btrfs_trans_handle *trans,
 			BUG_ON(next->new_bytenr);
 			BUG_ON(!list_empty(&next->list));
 			next->new_bytenr = root->node->start;
-			next->root = root;
+			btrfs_put_fs_root(next->root);
+			next->root = btrfs_grab_fs_root(root);
+			ASSERT(next->root);
 			list_add_tail(&next->list,
 				      &rc->backref_cache.changed);
 			__mark_block_processed(rc, next);
@@ -3094,7 +3113,9 @@ static int relocate_tree_block(struct btrfs_trans_handle *trans,
 			btrfs_record_root_in_trans(trans, root);
 			root = root->reloc_root;
 			node->new_bytenr = root->node->start;
-			node->root = root;
+			btrfs_put_fs_root(node->root);
+			node->root = btrfs_grab_fs_root(root);
+			ASSERT(node->root);
 			list_add_tail(&node->list, &rc->backref_cache.changed);
 		} else {
 			path->lowest_level = node->level;
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 22/44] btrfs: hold a ref on the root in prepare_to_merge
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (20 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 21/44] btrfs: hold a ref on the root in build_backref_tree Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-02-05 14:52   ` David Sterba
  2020-01-24 14:32 ` [PATCH 23/44] btrfs: hold a ref on the root in merge_reloc_roots Josef Bacik
                   ` (23 subsequent siblings)
  45 siblings, 1 reply; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs

We look up the reloc roots corresponding root, we need to hold a ref on
that root.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/relocation.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 990595a27a15..53df57b59bc3 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -2474,6 +2474,8 @@ int prepare_to_merge(struct reloc_control *rc, int err)
 		list_del_init(&reloc_root->root_list);
 
 		root = read_fs_root(fs_info, reloc_root->root_key.offset);
+		if (!btrfs_grab_fs_root(root))
+			BUG();
 		BUG_ON(IS_ERR(root));
 		BUG_ON(root->reloc_root != reloc_root);
 
@@ -2486,6 +2488,7 @@ int prepare_to_merge(struct reloc_control *rc, int err)
 		btrfs_update_reloc_root(trans, root);
 
 		list_add(&reloc_root->root_list, &reloc_roots);
+		btrfs_put_fs_root(root);
 	}
 
 	list_splice(&reloc_roots, &rc->reloc_roots);
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 23/44] btrfs: hold a ref on the root in merge_reloc_roots
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (21 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 22/44] btrfs: hold a ref on the root in prepare_to_merge Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:32 ` [PATCH 24/44] btrfs: hold a ref on the root in record_reloc_root_in_trans Josef Bacik
                   ` (22 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs

We look up the corresponding root for the reloc root, we need to hold a
ref while we're messing with it.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/relocation.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 53df57b59bc3..79430a4245b5 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -2546,10 +2546,13 @@ void merge_reloc_roots(struct reloc_control *rc)
 		if (btrfs_root_refs(&reloc_root->root_item) > 0) {
 			root = read_fs_root(fs_info,
 					    reloc_root->root_key.offset);
+			if (!btrfs_grab_fs_root(root))
+				BUG();
 			BUG_ON(IS_ERR(root));
 			BUG_ON(root->reloc_root != reloc_root);
 
 			ret = merge_reloc_root(rc, root);
+			btrfs_put_fs_root(root);
 			if (ret) {
 				if (list_empty(&reloc_root->root_list))
 					list_add_tail(&reloc_root->root_list,
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 24/44] btrfs: hold a ref on the root in record_reloc_root_in_trans
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (22 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 23/44] btrfs: hold a ref on the root in merge_reloc_roots Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:32 ` [PATCH 25/44] btrfs: hold a ref on the root in find_data_references Josef Bacik
                   ` (21 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs

We are recording this root in the transaction, so we need to hold a ref
on it until we do that.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/relocation.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 79430a4245b5..9b61fdc89af7 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -2604,15 +2604,20 @@ static int record_reloc_root_in_trans(struct btrfs_trans_handle *trans,
 {
 	struct btrfs_fs_info *fs_info = reloc_root->fs_info;
 	struct btrfs_root *root;
+	int ret;
 
 	if (reloc_root->last_trans == trans->transid)
 		return 0;
 
 	root = read_fs_root(fs_info, reloc_root->root_key.offset);
+	if (!btrfs_grab_fs_root(root))
+		BUG();
 	BUG_ON(IS_ERR(root));
 	BUG_ON(root->reloc_root != reloc_root);
+	ret = btrfs_record_root_in_trans(trans, root);
+	btrfs_put_fs_root(root);
 
-	return btrfs_record_root_in_trans(trans, root);
+	return ret;
 }
 
 static noinline_for_stack
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 25/44] btrfs: hold a ref on the root in find_data_references
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (23 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 24/44] btrfs: hold a ref on the root in record_reloc_root_in_trans Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:32 ` [PATCH 26/44] btrfs: hold a ref on the root in create_reloc_inode Josef Bacik
                   ` (20 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs

We're looking up the data references for the bytenr in a root, we need
to hold a ref on that root while we're doing that.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/relocation.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 9b61fdc89af7..0c75ae09a3a8 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -3708,7 +3708,11 @@ static int find_data_references(struct reloc_control *rc,
 	root = read_fs_root(fs_info, ref_root);
 	if (IS_ERR(root)) {
 		err = PTR_ERR(root);
-		goto out;
+		goto out_free;
+	}
+	if (!btrfs_grab_fs_root(root)) {
+		err = -ENOENT;
+		goto out_free;
 	}
 
 	key.objectid = ref_objectid;
@@ -3821,6 +3825,8 @@ static int find_data_references(struct reloc_control *rc,
 
 	}
 out:
+	btrfs_put_fs_root(root);
+out_free:
 	btrfs_free_path(path);
 	return err;
 }
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 26/44] btrfs: hold a ref on the root in create_reloc_inode
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (24 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 25/44] btrfs: hold a ref on the root in find_data_references Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:32 ` [PATCH 27/44] btrfs: hold a ref on the root in btrfs_recover_relocation Josef Bacik
                   ` (19 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs

We're creating a reloc inode in the data reloc tree, we need to hold a
ref on the root while we're doing that.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/relocation.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 0c75ae09a3a8..9531739b5a8c 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -4308,10 +4308,14 @@ struct inode *create_reloc_inode(struct btrfs_fs_info *fs_info,
 	root = read_fs_root(fs_info, BTRFS_DATA_RELOC_TREE_OBJECTID);
 	if (IS_ERR(root))
 		return ERR_CAST(root);
+	if (!btrfs_grab_fs_root(root))
+		return ERR_PTR(-ENOENT);
 
 	trans = btrfs_start_transaction(root, 6);
-	if (IS_ERR(trans))
+	if (IS_ERR(trans)) {
+		btrfs_put_fs_root(root);
 		return ERR_CAST(trans);
+	}
 
 	err = btrfs_find_free_objectid(root, &objectid);
 	if (err)
@@ -4329,6 +4333,7 @@ struct inode *create_reloc_inode(struct btrfs_fs_info *fs_info,
 
 	err = btrfs_orphan_add(trans, BTRFS_I(inode));
 out:
+	btrfs_put_fs_root(root);
 	btrfs_end_transaction(trans);
 	btrfs_btree_balance_dirty(fs_info);
 	if (err) {
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 27/44] btrfs: hold a ref on the root in btrfs_recover_relocation
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (25 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 26/44] btrfs: hold a ref on the root in create_reloc_inode Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-02-05 15:00   ` David Sterba
  2020-02-06 16:26   ` David Sterba
  2020-01-24 14:32 ` [PATCH 28/44] btrfs: push grab_fs_root into read_fs_root Josef Bacik
                   ` (18 subsequent siblings)
  45 siblings, 2 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs

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>
---
 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 9531739b5a8c..81f383df8f63 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -4593,6 +4593,10 @@ int btrfs_recover_relocation(struct btrfs_root *root)
 		if (btrfs_root_refs(&reloc_root->root_item) > 0) {
 			fs_root = read_fs_root(fs_info,
 					       reloc_root->root_key.offset);
+			if (!btrfs_grab_fs_root(fs_root)) {
+				err = -ENOENT;
+				goto out;
+			}
 			if (IS_ERR(fs_root)) {
 				ret = PTR_ERR(fs_root);
 				if (ret != -ENOENT) {
@@ -4604,6 +4608,8 @@ int btrfs_recover_relocation(struct btrfs_root *root)
 					err = ret;
 					goto out;
 				}
+			} else {
+				btrfs_put_fs_root(fs_root);
 			}
 		}
 
@@ -4653,10 +4659,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);
@@ -4688,10 +4699,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;
 }
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 28/44] btrfs: push grab_fs_root into read_fs_root
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (26 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 27/44] btrfs: hold a ref on the root in btrfs_recover_relocation Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:32 ` [PATCH 29/44] btrfs: hold a ref for the root in btrfs_find_orphan_roots Josef Bacik
                   ` (17 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs

All of relocation uses read_fs_root to lookup fs roots, so push the
btrfs_grab_fs_root() up into that helper and remove the individual
calls.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/relocation.c | 38 +++++++++-----------------------------
 1 file changed, 9 insertions(+), 29 deletions(-)

diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 81f383df8f63..d166cc742f75 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -613,6 +613,7 @@ static struct btrfs_root *read_fs_root(struct btrfs_fs_info *fs_info,
 					u64 root_objectid)
 {
 	struct btrfs_key key;
+	struct btrfs_root *root;
 
 	key.objectid = root_objectid;
 	key.type = BTRFS_ROOT_ITEM_KEY;
@@ -621,7 +622,12 @@ static struct btrfs_root *read_fs_root(struct btrfs_fs_info *fs_info,
 	else
 		key.offset = (u64)-1;
 
-	return btrfs_get_fs_root(fs_info, &key, false);
+	root = btrfs_get_fs_root(fs_info, &key, false);
+	if (IS_ERR(root))
+		return root;
+	if (!btrfs_grab_fs_root(root))
+		return ERR_PTR(-ENOENT);
+	return root;
 }
 
 static noinline_for_stack
@@ -893,10 +899,6 @@ struct backref_node *build_backref_tree(struct reloc_control *rc,
 			err = PTR_ERR(root);
 			goto out;
 		}
-		if (!btrfs_grab_fs_root(root)) {
-			err = -ENOENT;
-			goto out;
-		}
 
 		if (!test_bit(BTRFS_ROOT_REF_COWS, &root->state))
 			cur->cowonly = 1;
@@ -2474,8 +2476,6 @@ int prepare_to_merge(struct reloc_control *rc, int err)
 		list_del_init(&reloc_root->root_list);
 
 		root = read_fs_root(fs_info, reloc_root->root_key.offset);
-		if (!btrfs_grab_fs_root(root))
-			BUG();
 		BUG_ON(IS_ERR(root));
 		BUG_ON(root->reloc_root != reloc_root);
 
@@ -2546,8 +2546,6 @@ void merge_reloc_roots(struct reloc_control *rc)
 		if (btrfs_root_refs(&reloc_root->root_item) > 0) {
 			root = read_fs_root(fs_info,
 					    reloc_root->root_key.offset);
-			if (!btrfs_grab_fs_root(root))
-				BUG();
 			BUG_ON(IS_ERR(root));
 			BUG_ON(root->reloc_root != reloc_root);
 
@@ -2610,8 +2608,6 @@ static int record_reloc_root_in_trans(struct btrfs_trans_handle *trans,
 		return 0;
 
 	root = read_fs_root(fs_info, reloc_root->root_key.offset);
-	if (!btrfs_grab_fs_root(root))
-		BUG();
 	BUG_ON(IS_ERR(root));
 	BUG_ON(root->reloc_root != reloc_root);
 	ret = btrfs_record_root_in_trans(trans, root);
@@ -3710,10 +3706,6 @@ static int find_data_references(struct reloc_control *rc,
 		err = PTR_ERR(root);
 		goto out_free;
 	}
-	if (!btrfs_grab_fs_root(root)) {
-		err = -ENOENT;
-		goto out_free;
-	}
 
 	key.objectid = ref_objectid;
 	key.type = BTRFS_EXTENT_DATA_KEY;
@@ -4308,8 +4300,6 @@ struct inode *create_reloc_inode(struct btrfs_fs_info *fs_info,
 	root = read_fs_root(fs_info, BTRFS_DATA_RELOC_TREE_OBJECTID);
 	if (IS_ERR(root))
 		return ERR_CAST(root);
-	if (!btrfs_grab_fs_root(root))
-		return ERR_PTR(-ENOENT);
 
 	trans = btrfs_start_transaction(root, 6);
 	if (IS_ERR(trans)) {
@@ -4593,10 +4583,6 @@ int btrfs_recover_relocation(struct btrfs_root *root)
 		if (btrfs_root_refs(&reloc_root->root_item) > 0) {
 			fs_root = read_fs_root(fs_info,
 					       reloc_root->root_key.offset);
-			if (!btrfs_grab_fs_root(fs_root)) {
-				err = -ENOENT;
-				goto out;
-			}
 			if (IS_ERR(fs_root)) {
 				ret = PTR_ERR(fs_root);
 				if (ret != -ENOENT) {
@@ -4659,10 +4645,6 @@ 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 */
@@ -4702,10 +4684,8 @@ int btrfs_recover_relocation(struct btrfs_root *root)
 		if (IS_ERR(fs_root)) {
 			err = PTR_ERR(fs_root);
 		} else {
-			if (btrfs_grab_fs_root(fs_root)) {
-				err = btrfs_orphan_cleanup(fs_root);
-				btrfs_put_fs_root(fs_root);
-			}
+			err = btrfs_orphan_cleanup(fs_root);
+			btrfs_put_fs_root(fs_root);
 		}
 	}
 	return err;
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 29/44] btrfs: hold a ref for the root in btrfs_find_orphan_roots
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (27 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 28/44] btrfs: push grab_fs_root into read_fs_root Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-02-05 15:06   ` David Sterba
  2020-01-24 14:32 ` [PATCH 30/44] btrfs: hold a ref on the root in scrub_print_warning_inode Josef Bacik
                   ` (16 subsequent siblings)
  45 siblings, 1 reply; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs

We lookup roots for every orphan item we have, we need to hold a ref on
the root while we're doing this work.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/root-tree.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c
index 094a71c54fa1..25842527fd42 100644
--- a/fs/btrfs/root-tree.c
+++ b/fs/btrfs/root-tree.c
@@ -257,6 +257,8 @@ int btrfs_find_orphan_roots(struct btrfs_fs_info *fs_info)
 
 		root = btrfs_get_fs_root(fs_info, &root_key, false);
 		err = PTR_ERR_OR_ZERO(root);
+		if (!err && !btrfs_grab_fs_root(root))
+			err = -ENOENT;
 		if (err && err != -ENOENT) {
 			break;
 		} else if (err == -ENOENT) {
@@ -288,6 +290,7 @@ int btrfs_find_orphan_roots(struct btrfs_fs_info *fs_info)
 			set_bit(BTRFS_ROOT_DEAD_TREE, &root->state);
 			btrfs_add_dead_root(root);
 		}
+		btrfs_put_fs_root(root);
 	}
 
 	btrfs_free_path(path);
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 30/44] btrfs: hold a ref on the root in scrub_print_warning_inode
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (28 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 29/44] btrfs: hold a ref for the root in btrfs_find_orphan_roots Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:32 ` [PATCH 31/44] btrfs: hold a ref on the root in btrfs_ioctl_send Josef Bacik
                   ` (15 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs

We look up the root for the bytenr that is failing, so we need to hold a
ref on the root for that operation.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/scrub.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index b5f420456439..f9ee327d7978 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -658,6 +658,10 @@ static int scrub_print_warning_inode(u64 inum, u64 offset, u64 root,
 		ret = PTR_ERR(local_root);
 		goto err;
 	}
+	if (!btrfs_grab_fs_root(local_root)) {
+		ret = -ENOENT;
+		goto err;
+	}
 
 	/*
 	 * this makes the path point to (inum INODE_ITEM ioff)
@@ -668,6 +672,7 @@ static int scrub_print_warning_inode(u64 inum, u64 offset, u64 root,
 
 	ret = btrfs_search_slot(NULL, local_root, &key, swarn->path, 0, 0);
 	if (ret) {
+		btrfs_put_fs_root(local_root);
 		btrfs_release_path(swarn->path);
 		goto err;
 	}
@@ -688,6 +693,7 @@ static int scrub_print_warning_inode(u64 inum, u64 offset, u64 root,
 	ipath = init_ipath(4096, local_root, swarn->path);
 	memalloc_nofs_restore(nofs_flag);
 	if (IS_ERR(ipath)) {
+		btrfs_put_fs_root(local_root);
 		ret = PTR_ERR(ipath);
 		ipath = NULL;
 		goto err;
@@ -711,6 +717,7 @@ static int scrub_print_warning_inode(u64 inum, u64 offset, u64 root,
 				  min(isize - offset, (u64)PAGE_SIZE), nlink,
 				  (char *)(unsigned long)ipath->fspath->val[i]);
 
+	btrfs_put_fs_root(local_root);
 	free_ipath(ipath);
 	return 0;
 
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 31/44] btrfs: hold a ref on the root in btrfs_ioctl_send
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (29 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 30/44] btrfs: hold a ref on the root in scrub_print_warning_inode Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-02-05 15:16   ` David Sterba
  2020-01-24 14:32 ` [PATCH 32/44] btrfs: hold a ref on the root in get_subvol_name_from_objectid Josef Bacik
                   ` (14 subsequent siblings)
  45 siblings, 1 reply; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs

We lookup all the clone roots and the parent root for send, so we need
to hold refs on all of these roots while we're processing them.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/send.c | 28 ++++++++++++++++++++++++----
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 57eae56dd743..ee2fc9ea9d7e 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -7200,11 +7200,17 @@ long btrfs_ioctl_send(struct file *mnt_file, struct btrfs_ioctl_send_args *arg)
 				ret = PTR_ERR(clone_root);
 				goto out;
 			}
+			if (!btrfs_grab_fs_root(clone_root)) {
+				srcu_read_unlock(&fs_info->subvol_srcu, index);
+				ret = -ENOENT;
+				goto out;
+			}
 			spin_lock(&clone_root->root_item_lock);
 			if (!btrfs_root_readonly(clone_root) ||
 			    btrfs_root_dead(clone_root)) {
 				spin_unlock(&clone_root->root_item_lock);
 				srcu_read_unlock(&fs_info->subvol_srcu, index);
+				btrfs_put_fs_root(clone_root);
 				ret = -EPERM;
 				goto out;
 			}
@@ -7212,6 +7218,7 @@ long btrfs_ioctl_send(struct file *mnt_file, struct btrfs_ioctl_send_args *arg)
 				dedupe_in_progress_warn(clone_root);
 				spin_unlock(&clone_root->root_item_lock);
 				srcu_read_unlock(&fs_info->subvol_srcu, index);
+				btrfs_put_fs_root(clone_root);
 				ret = -EAGAIN;
 				goto out;
 			}
@@ -7239,6 +7246,12 @@ long btrfs_ioctl_send(struct file *mnt_file, struct btrfs_ioctl_send_args *arg)
 			ret = PTR_ERR(sctx->parent_root);
 			goto out;
 		}
+		if (!btrfs_grab_fs_root(sctx->parent_root)) {
+			srcu_read_unlock(&fs_info->subvol_srcu, index);
+			ret = -ENOENT;
+			sctx->parent_root = ERR_PTR(ret);
+			goto out;
+		}
 
 		spin_lock(&sctx->parent_root->root_item_lock);
 		sctx->parent_root->send_in_progress++;
@@ -7266,7 +7279,8 @@ long btrfs_ioctl_send(struct file *mnt_file, struct btrfs_ioctl_send_args *arg)
 	 * is behind the current send position. This is checked while searching
 	 * for possible clone sources.
 	 */
-	sctx->clone_roots[sctx->clone_roots_cnt++].root = sctx->send_root;
+	sctx->clone_roots[sctx->clone_roots_cnt++].root =
+		btrfs_grab_fs_root(sctx->send_root);
 
 	/* We do a bsearch later */
 	sort(sctx->clone_roots, sctx->clone_roots_cnt,
@@ -7351,18 +7365,24 @@ long btrfs_ioctl_send(struct file *mnt_file, struct btrfs_ioctl_send_args *arg)
 	}
 
 	if (sort_clone_roots) {
-		for (i = 0; i < sctx->clone_roots_cnt; i++)
+		for (i = 0; i < sctx->clone_roots_cnt; i++) {
 			btrfs_root_dec_send_in_progress(
 					sctx->clone_roots[i].root);
+			btrfs_put_fs_root(sctx->clone_roots[i].root);
+		}
 	} else {
-		for (i = 0; sctx && i < clone_sources_to_rollback; i++)
+		for (i = 0; sctx && i < clone_sources_to_rollback; i++) {
 			btrfs_root_dec_send_in_progress(
 					sctx->clone_roots[i].root);
+			btrfs_put_fs_root(sctx->clone_roots[i].root);
+		}
 
 		btrfs_root_dec_send_in_progress(send_root);
 	}
-	if (sctx && !IS_ERR_OR_NULL(sctx->parent_root))
+	if (sctx && !IS_ERR_OR_NULL(sctx->parent_root)) {
 		btrfs_root_dec_send_in_progress(sctx->parent_root);
+		btrfs_put_fs_root(sctx->parent_root);
+	}
 
 	kvfree(clone_sources_tmp);
 
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 32/44] btrfs: hold a ref on the root in get_subvol_name_from_objectid
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (30 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 31/44] btrfs: hold a ref on the root in btrfs_ioctl_send Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-02-05 15:19   ` David Sterba
  2020-01-24 14:32 ` [PATCH 33/44] btrfs: hold a ref on the root in create_pending_snapshot Josef Bacik
                   ` (13 subsequent siblings)
  45 siblings, 1 reply; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs

We lookup the name of a subvol which means we'll cross into different
roots.  Hold a ref while we're doing the look ups in the fs_root we're
searching.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/super.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 3118bc01321e..5c3a1b7de6ee 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -1101,6 +1101,10 @@ static char *get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info,
 			ret = PTR_ERR(fs_root);
 			goto err;
 		}
+		if (!btrfs_grab_fs_root(fs_root)) {
+			ret = -ENOENT;
+			goto err;
+		}
 
 		/*
 		 * Walk up the filesystem tree by inode refs until we hit the
@@ -1113,13 +1117,16 @@ static char *get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info,
 
 			ret = btrfs_search_slot(NULL, fs_root, &key, path, 0, 0);
 			if (ret < 0) {
+				btrfs_put_fs_root(fs_root);
 				goto err;
 			} else if (ret > 0) {
 				ret = btrfs_previous_item(fs_root, path, dirid,
 							  BTRFS_INODE_REF_KEY);
 				if (ret < 0) {
+					btrfs_put_fs_root(fs_root);
 					goto err;
 				} else if (ret > 0) {
+					btrfs_put_fs_root(fs_root);
 					ret = -ENOENT;
 					goto err;
 				}
@@ -1136,6 +1143,7 @@ static char *get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info,
 			ptr -= len + 1;
 			if (ptr < name) {
 				ret = -ENAMETOOLONG;
+				btrfs_put_fs_root(fs_root);
 				goto err;
 			}
 			read_extent_buffer(path->nodes[0], ptr + 1,
@@ -1143,6 +1151,7 @@ static char *get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info,
 			ptr[0] = '/';
 			btrfs_release_path(path);
 		}
+		btrfs_put_fs_root(fs_root);
 	}
 
 	btrfs_free_path(path);
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 33/44] btrfs: hold a ref on the root in create_pending_snapshot
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (31 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 32/44] btrfs: hold a ref on the root in get_subvol_name_from_objectid Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:32 ` [PATCH 34/44] btrfs: hold a ref on the root in btrfs_recover_log_trees Josef Bacik
                   ` (12 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs

We create the snapshot and then use it for a bunch of things, we need to
hold a ref on it while we're messing with it.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/ioctl.c       | 1 +
 fs/btrfs/transaction.c | 6 ++++++
 2 files changed, 7 insertions(+)

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 69c39b3d15a5..47953d022328 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -875,6 +875,7 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
 	d_instantiate(dentry, inode);
 	ret = 0;
 fail:
+	btrfs_put_fs_root(pending_snapshot->snap);
 	btrfs_subvolume_release_metadata(fs_info, &pending_snapshot->block_rsv);
 dec_and_free:
 	if (snapshot_force_cow)
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index e194d3e4e3a9..7008def3391b 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -1637,6 +1637,12 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
 		btrfs_abort_transaction(trans, ret);
 		goto fail;
 	}
+	if (!btrfs_grab_fs_root(pending->snap)) {
+		ret = -ENOENT;
+		pending->snap = NULL;
+		btrfs_abort_transaction(trans, ret);
+		goto fail;
+	}
 
 	ret = btrfs_reloc_post_snapshot(trans, pending);
 	if (ret) {
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 34/44] btrfs: hold a ref on the root in btrfs_recover_log_trees
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (32 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 33/44] btrfs: hold a ref on the root in create_pending_snapshot Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:32 ` [PATCH 35/44] btrfs: hold a ref on the root in btrfs_check_uuid_tree_entry Josef Bacik
                   ` (11 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs

We replay the log into arbitrary fs roots, hold a ref on the root while
we're doing this.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/tree-log.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index db803765b500..5b05419a0f4c 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -6114,6 +6114,10 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
 		tmp_key.offset = (u64)-1;
 
 		wc.replay_dest = btrfs_get_fs_root(fs_info, &tmp_key, true);
+		if (!IS_ERR(wc.replay_dest)) {
+			if (!btrfs_grab_fs_root(wc.replay_dest))
+				wc.replay_dest = ERR_PTR(-ENOENT);
+		}
 		if (IS_ERR(wc.replay_dest)) {
 			ret = PTR_ERR(wc.replay_dest);
 
@@ -6170,6 +6174,7 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
 		}
 
 		wc.replay_dest->log_root = NULL;
+		btrfs_put_fs_root(wc.replay_dest);
 		free_extent_buffer(log->node);
 		free_extent_buffer(log->commit_root);
 		kfree(log);
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 35/44] btrfs: hold a ref on the root in btrfs_check_uuid_tree_entry
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (33 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 34/44] btrfs: hold a ref on the root in btrfs_recover_log_trees Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:32 ` [PATCH 36/44] btrfs: move free_fs_info Josef Bacik
                   ` (10 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs

We lookup the uuid of arbitrary subvolumes, hold a ref on the root while
we're doing this.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/volumes.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index ce3eff93c366..527b0b41ebdc 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -4382,6 +4382,10 @@ static int btrfs_check_uuid_tree_entry(struct btrfs_fs_info *fs_info,
 			ret = 1;
 		goto out;
 	}
+	if (!btrfs_grab_fs_root(subvol_root)) {
+		ret = 1;
+		goto out;
+	}
 
 	switch (type) {
 	case BTRFS_UUID_KEY_SUBVOL:
@@ -4394,7 +4398,7 @@ static int btrfs_check_uuid_tree_entry(struct btrfs_fs_info *fs_info,
 			ret = 1;
 		break;
 	}
-
+	btrfs_put_fs_root(subvol_root);
 out:
 	return ret;
 }
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 36/44] btrfs: move free_fs_info
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (34 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 35/44] btrfs: hold a ref on the root in btrfs_check_uuid_tree_entry Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:52   ` Nikolay Borisov
  2020-01-24 14:32 ` [PATCH 37/44] btrfs: hold a ref on the root in open_ctree Josef Bacik
                   ` (9 subsequent siblings)
  45 siblings, 1 reply; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs

We're going to start freeing roots and doing other complicated things in
free_fs_info, so we need to move it to disk-io.c and export it in order
to use things lik btrfs_put_fs_root().

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/ctree.h   | 17 -----------------
 fs/btrfs/disk-io.c | 18 ++++++++++++++++++
 fs/btrfs/disk-io.h |  1 +
 fs/btrfs/super.c   |  6 +++---
 4 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index f90b82050d2d..68510af4cacf 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -2697,23 +2697,6 @@ static inline int btrfs_need_cleaner_sleep(struct btrfs_fs_info *fs_info)
 	return fs_info->sb->s_flags & SB_RDONLY || btrfs_fs_closing(fs_info);
 }
 
-static inline void free_fs_info(struct btrfs_fs_info *fs_info)
-{
-	kfree(fs_info->balance_ctl);
-	kfree(fs_info->delayed_root);
-	kfree(fs_info->extent_root);
-	kfree(fs_info->tree_root);
-	kfree(fs_info->chunk_root);
-	kfree(fs_info->dev_root);
-	kfree(fs_info->csum_root);
-	kfree(fs_info->quota_root);
-	kfree(fs_info->uuid_root);
-	kfree(fs_info->free_space_root);
-	kfree(fs_info->super_copy);
-	kfree(fs_info->super_for_commit);
-	kvfree(fs_info);
-}
-
 /* tree mod log functions from ctree.c */
 u64 btrfs_get_tree_mod_seq(struct btrfs_fs_info *fs_info,
 			   struct seq_list *elem);
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 5f672f016ed8..c605be6ba889 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1523,6 +1523,24 @@ int btrfs_insert_fs_root(struct btrfs_fs_info *fs_info,
 	return ret;
 }
 
+void btrfs_free_fs_info(struct btrfs_fs_info *fs_info)
+{
+	kfree(fs_info->balance_ctl);
+	kfree(fs_info->delayed_root);
+	kfree(fs_info->extent_root);
+	kfree(fs_info->tree_root);
+	kfree(fs_info->chunk_root);
+	kfree(fs_info->dev_root);
+	kfree(fs_info->csum_root);
+	kfree(fs_info->quota_root);
+	kfree(fs_info->uuid_root);
+	kfree(fs_info->free_space_root);
+	kfree(fs_info->super_copy);
+	kfree(fs_info->super_for_commit);
+	kvfree(fs_info);
+}
+
+
 struct btrfs_root *btrfs_get_fs_root(struct btrfs_fs_info *fs_info,
 				     struct btrfs_key *location,
 				     bool check_ref)
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
index 8add2e14aab1..97e7ac474a52 100644
--- a/fs/btrfs/disk-io.h
+++ b/fs/btrfs/disk-io.h
@@ -68,6 +68,7 @@ struct btrfs_root *btrfs_get_fs_root(struct btrfs_fs_info *fs_info,
 				     struct btrfs_key *key,
 				     bool check_ref);
 
+void btrfs_free_fs_info(struct btrfs_fs_info *fs_info);
 int btrfs_cleanup_fs_roots(struct btrfs_fs_info *fs_info);
 void btrfs_btree_balance_dirty(struct btrfs_fs_info *fs_info);
 void btrfs_btree_balance_dirty_nodelay(struct btrfs_fs_info *fs_info);
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 5c3a1b7de6ee..0c81456df23e 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -1580,7 +1580,7 @@ static struct dentry *btrfs_mount_root(struct file_system_type *fs_type,
 
 	if (s->s_root) {
 		btrfs_close_devices(fs_devices);
-		free_fs_info(fs_info);
+		btrfs_free_fs_info(fs_info);
 		if ((flags ^ s->s_flags) & SB_RDONLY)
 			error = -EBUSY;
 	} else {
@@ -1603,7 +1603,7 @@ static struct dentry *btrfs_mount_root(struct file_system_type *fs_type,
 error_close_devices:
 	btrfs_close_devices(fs_devices);
 error_fs_info:
-	free_fs_info(fs_info);
+	btrfs_free_fs_info(fs_info);
 error_sec_opts:
 	security_free_mnt_opts(&new_sec_opts);
 	return ERR_PTR(error);
@@ -2169,7 +2169,7 @@ static void btrfs_kill_super(struct super_block *sb)
 {
 	struct btrfs_fs_info *fs_info = btrfs_sb(sb);
 	kill_anon_super(sb);
-	free_fs_info(fs_info);
+	btrfs_free_fs_info(fs_info);
 }
 
 static struct file_system_type btrfs_fs_type = {
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 37/44] btrfs: hold a ref on the root in open_ctree
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (35 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 36/44] btrfs: move free_fs_info Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:32 ` [PATCH 38/44] btrfs: use btrfs_put_fs_root to free roots always Josef Bacik
                   ` (8 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs

We lookup the fs_root and put it in our fs_info directly, we should hold
a ref on this root for the lifetime of the fs_info.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/disk-io.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index c605be6ba889..433c29ddfca7 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1537,6 +1537,7 @@ void btrfs_free_fs_info(struct btrfs_fs_info *fs_info)
 	kfree(fs_info->free_space_root);
 	kfree(fs_info->super_copy);
 	kfree(fs_info->super_for_commit);
+	btrfs_put_fs_root(fs_info->fs_root);
 	kvfree(fs_info);
 }
 
@@ -3203,6 +3204,13 @@ int __cold open_ctree(struct super_block *sb,
 		goto fail_qgroup;
 	}
 
+	if (!btrfs_grab_fs_root(fs_info->fs_root)) {
+		fs_info->fs_root = NULL;
+		err = -ENOENT;
+		btrfs_warn(fs_info, "failed to grab a ref on the fs tree");
+		goto fail_qgroup;
+	}
+
 	if (sb_rdonly(sb))
 		return 0;
 
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 38/44] btrfs: use btrfs_put_fs_root to free roots always
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (36 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 37/44] btrfs: hold a ref on the root in open_ctree Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:32 ` [PATCH 39/44] btrfs: push btrfs_grab_fs_root into btrfs_get_fs_root Josef Bacik
                   ` (7 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs; +Cc: Nikolay Borisov

If we are going to track leaked roots we need to free them all the same
way, so don't kfree() roots directly, use btrfs_put_fs_root.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
---
 fs/btrfs/disk-io.c           | 30 +++++++++++++++---------------
 fs/btrfs/free-space-tree.c   |  2 +-
 fs/btrfs/qgroup.c            |  4 ++--
 fs/btrfs/tests/btrfs-tests.c |  2 +-
 fs/btrfs/tree-log.c          |  8 ++++----
 5 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 433c29ddfca7..fa721ca1e732 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1297,7 +1297,7 @@ struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans,
 		free_extent_buffer(root->commit_root);
 		free_extent_buffer(leaf);
 	}
-	kfree(root);
+	btrfs_put_fs_root(root);
 
 	return ERR_PTR(ret);
 }
@@ -1328,7 +1328,7 @@ static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans,
 	leaf = btrfs_alloc_tree_block(trans, root, 0, BTRFS_TREE_LOG_OBJECTID,
 			NULL, 0, 0, 0);
 	if (IS_ERR(leaf)) {
-		kfree(root);
+		btrfs_put_fs_root(root);
 		return ERR_CAST(leaf);
 	}
 
@@ -1431,7 +1431,7 @@ struct btrfs_root *btrfs_read_tree_root(struct btrfs_root *tree_root,
 	return root;
 
 find_fail:
-	kfree(root);
+	btrfs_put_fs_root(root);
 alloc_fail:
 	root = ERR_PTR(ret);
 	goto out;
@@ -1527,17 +1527,17 @@ void btrfs_free_fs_info(struct btrfs_fs_info *fs_info)
 {
 	kfree(fs_info->balance_ctl);
 	kfree(fs_info->delayed_root);
-	kfree(fs_info->extent_root);
-	kfree(fs_info->tree_root);
-	kfree(fs_info->chunk_root);
-	kfree(fs_info->dev_root);
-	kfree(fs_info->csum_root);
-	kfree(fs_info->quota_root);
-	kfree(fs_info->uuid_root);
-	kfree(fs_info->free_space_root);
+	btrfs_put_fs_root(fs_info->extent_root);
+	btrfs_put_fs_root(fs_info->tree_root);
+	btrfs_put_fs_root(fs_info->chunk_root);
+	btrfs_put_fs_root(fs_info->dev_root);
+	btrfs_put_fs_root(fs_info->csum_root);
+	btrfs_put_fs_root(fs_info->quota_root);
+	btrfs_put_fs_root(fs_info->uuid_root);
+	btrfs_put_fs_root(fs_info->free_space_root);
+	btrfs_put_fs_root(fs_info->fs_root);
 	kfree(fs_info->super_copy);
 	kfree(fs_info->super_for_commit);
-	btrfs_put_fs_root(fs_info->fs_root);
 	kvfree(fs_info);
 }
 
@@ -2223,12 +2223,12 @@ static int btrfs_replay_log(struct btrfs_fs_info *fs_info,
 	if (IS_ERR(log_tree_root->node)) {
 		btrfs_warn(fs_info, "failed to read log tree");
 		ret = PTR_ERR(log_tree_root->node);
-		kfree(log_tree_root);
+		btrfs_put_fs_root(log_tree_root);
 		return ret;
 	} else if (!extent_buffer_uptodate(log_tree_root->node)) {
 		btrfs_err(fs_info, "failed to read log tree");
 		free_extent_buffer(log_tree_root->node);
-		kfree(log_tree_root);
+		btrfs_put_fs_root(log_tree_root);
 		return -EIO;
 	}
 	/* returns with log_tree_root freed on success */
@@ -2237,7 +2237,7 @@ static int btrfs_replay_log(struct btrfs_fs_info *fs_info,
 		btrfs_handle_fs_error(fs_info, ret,
 				      "Failed to recover log tree");
 		free_extent_buffer(log_tree_root->node);
-		kfree(log_tree_root);
+		btrfs_put_fs_root(log_tree_root);
 		return ret;
 	}
 
diff --git a/fs/btrfs/free-space-tree.c b/fs/btrfs/free-space-tree.c
index 258cb3fae17a..c79804c30b17 100644
--- a/fs/btrfs/free-space-tree.c
+++ b/fs/btrfs/free-space-tree.c
@@ -1253,7 +1253,7 @@ int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info)
 
 	free_extent_buffer(free_space_root->node);
 	free_extent_buffer(free_space_root->commit_root);
-	kfree(free_space_root);
+	btrfs_put_fs_root(free_space_root);
 
 	return btrfs_commit_transaction(trans);
 
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 98d9a50352d6..0845e56a1672 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -1040,7 +1040,7 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info)
 	if (ret) {
 		free_extent_buffer(quota_root->node);
 		free_extent_buffer(quota_root->commit_root);
-		kfree(quota_root);
+		btrfs_put_fs_root(quota_root);
 	}
 out:
 	if (ret) {
@@ -1106,7 +1106,7 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info)
 
 	free_extent_buffer(quota_root->node);
 	free_extent_buffer(quota_root->commit_root);
-	kfree(quota_root);
+	btrfs_put_fs_root(quota_root);
 
 end_trans:
 	ret = btrfs_end_transaction(trans);
diff --git a/fs/btrfs/tests/btrfs-tests.c b/fs/btrfs/tests/btrfs-tests.c
index c12b91ff5f56..27f5b662d2cb 100644
--- a/fs/btrfs/tests/btrfs-tests.c
+++ b/fs/btrfs/tests/btrfs-tests.c
@@ -228,7 +228,7 @@ void btrfs_free_dummy_root(struct btrfs_root *root)
 		/* One for allocate_extent_buffer */
 		free_extent_buffer(root->node);
 	}
-	kfree(root);
+	btrfs_put_fs_root(root);
 }
 
 struct btrfs_block_group *
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 5b05419a0f4c..f06ad415faf8 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -3284,7 +3284,7 @@ static void free_log_tree(struct btrfs_trans_handle *trans,
 	clear_extent_bits(&log->dirty_log_pages, 0, (u64)-1,
 			  EXTENT_DIRTY | EXTENT_NEW | EXTENT_NEED_WAIT);
 	free_extent_buffer(log->node);
-	kfree(log);
+	btrfs_put_fs_root(log);
 }
 
 /*
@@ -6138,7 +6138,7 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
 							log->node->len);
 			free_extent_buffer(log->node);
 			free_extent_buffer(log->commit_root);
-			kfree(log);
+			btrfs_put_fs_root(log);
 
 			if (!ret)
 				goto next;
@@ -6177,7 +6177,7 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
 		btrfs_put_fs_root(wc.replay_dest);
 		free_extent_buffer(log->node);
 		free_extent_buffer(log->commit_root);
-		kfree(log);
+		btrfs_put_fs_root(log);
 
 		if (ret)
 			goto error;
@@ -6211,7 +6211,7 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
 	free_extent_buffer(log_root_tree->node);
 	log_root_tree->log_root = NULL;
 	clear_bit(BTRFS_FS_LOG_RECOVERING, &fs_info->flags);
-	kfree(log_root_tree);
+	btrfs_put_fs_root(log_root_tree);
 
 	return 0;
 error:
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 39/44] btrfs: push btrfs_grab_fs_root into btrfs_get_fs_root
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (37 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 38/44] btrfs: use btrfs_put_fs_root to free roots always Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:32 ` [PATCH 40/44] btrfs: free more things in btrfs_free_fs_info Josef Bacik
                   ` (6 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs

Now that all callers of btrfs_get_fs_root are subsequently calling
btrfs_grab_fs_root and handling dropping the ref when they are done
appropriately, go ahead and push btrfs_grab_fs_root up into
btrfs_get_fs_root.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/backref.c     |  6 ------
 fs/btrfs/disk-io.c     | 45 ++++++++++++++++++++++++------------------
 fs/btrfs/export.c      |  4 ----
 fs/btrfs/file.c        |  4 ----
 fs/btrfs/inode.c       |  4 ----
 fs/btrfs/ioctl.c       | 26 ------------------------
 fs/btrfs/relocation.c  |  8 +-------
 fs/btrfs/root-tree.c   |  2 --
 fs/btrfs/scrub.c       |  4 ----
 fs/btrfs/send.c        | 11 -----------
 fs/btrfs/super.c       |  4 ----
 fs/btrfs/transaction.c |  6 ------
 fs/btrfs/tree-log.c    |  4 ----
 fs/btrfs/volumes.c     |  4 ----
 14 files changed, 27 insertions(+), 105 deletions(-)

diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index 193747b6e1f9..b69154d72529 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -527,12 +527,6 @@ static int resolve_indirect_ref(struct btrfs_fs_info *fs_info,
 		goto out_free;
 	}
 
-	if (!btrfs_grab_fs_root(root)) {
-		srcu_read_unlock(&fs_info->subvol_srcu, index);
-		ret = -ENOENT;
-		goto out_free;
-	}
-
 	if (btrfs_is_testing(fs_info)) {
 		srcu_read_unlock(&fs_info->subvol_srcu, index);
 		ret = -ENOENT;
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index fa721ca1e732..ac306807e5cd 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1496,6 +1496,8 @@ static struct btrfs_root *btrfs_lookup_fs_root(struct btrfs_fs_info *fs_info,
 	spin_lock(&fs_info->fs_roots_radix_lock);
 	root = radix_tree_lookup(&fs_info->fs_roots_radix,
 				 (unsigned long)root_id);
+	if (root)
+		root = btrfs_grab_fs_root(root);
 	spin_unlock(&fs_info->fs_roots_radix_lock);
 	return root;
 }
@@ -1552,29 +1554,31 @@ struct btrfs_root *btrfs_get_fs_root(struct btrfs_fs_info *fs_info,
 	int ret;
 
 	if (location->objectid == BTRFS_ROOT_TREE_OBJECTID)
-		return fs_info->tree_root;
+		return btrfs_grab_fs_root(fs_info->tree_root);
 	if (location->objectid == BTRFS_EXTENT_TREE_OBJECTID)
-		return fs_info->extent_root;
+		return btrfs_grab_fs_root(fs_info->extent_root);
 	if (location->objectid == BTRFS_CHUNK_TREE_OBJECTID)
-		return fs_info->chunk_root;
+		return btrfs_grab_fs_root(fs_info->chunk_root);
 	if (location->objectid == BTRFS_DEV_TREE_OBJECTID)
-		return fs_info->dev_root;
+		return btrfs_grab_fs_root(fs_info->dev_root);
 	if (location->objectid == BTRFS_CSUM_TREE_OBJECTID)
-		return fs_info->csum_root;
+		return btrfs_grab_fs_root(fs_info->csum_root);
 	if (location->objectid == BTRFS_QUOTA_TREE_OBJECTID)
-		return fs_info->quota_root ? fs_info->quota_root :
-					     ERR_PTR(-ENOENT);
+		return btrfs_grab_fs_root(fs_info->quota_root) ?
+			fs_info->quota_root : ERR_PTR(-ENOENT);
 	if (location->objectid == BTRFS_UUID_TREE_OBJECTID)
-		return fs_info->uuid_root ? fs_info->uuid_root :
-					    ERR_PTR(-ENOENT);
+		return btrfs_grab_fs_root(fs_info->uuid_root) ?
+			fs_info->uuid_root : ERR_PTR(-ENOENT);
 	if (location->objectid == BTRFS_FREE_SPACE_TREE_OBJECTID)
-		return fs_info->free_space_root ? fs_info->free_space_root :
-						  ERR_PTR(-ENOENT);
+		return btrfs_grab_fs_root(fs_info->free_space_root) ?
+			fs_info->free_space_root : ERR_PTR(-ENOENT);
 again:
 	root = btrfs_lookup_fs_root(fs_info, location->objectid);
 	if (root) {
-		if (check_ref && btrfs_root_refs(&root->root_item) == 0)
+		if (check_ref && btrfs_root_refs(&root->root_item) == 0) {
+			btrfs_put_fs_root(root);
 			return ERR_PTR(-ENOENT);
+		}
 		return root;
 	}
 
@@ -1607,8 +1611,18 @@ struct btrfs_root *btrfs_get_fs_root(struct btrfs_fs_info *fs_info,
 	if (ret == 0)
 		set_bit(BTRFS_ROOT_ORPHAN_ITEM_INSERTED, &root->state);
 
+	/*
+	 * All roots have two refs on them at all times, one for the mounted fs,
+	 * and one for being in the radix tree.  This way we only free the root
+	 * when we are unmounting or deleting the subvolume.  We get one ref
+	 * from __setup_root, one for inserting it into the radix tree, and then
+	 * we have the third for returning it, and the caller will put it when
+	 * it's done with the root.
+	 */
+	btrfs_grab_fs_root(root);
 	ret = btrfs_insert_fs_root(fs_info, root);
 	if (ret) {
+		btrfs_put_fs_root(root);
 		if (ret == -EEXIST) {
 			btrfs_free_fs_root(root);
 			goto again;
@@ -3204,13 +3218,6 @@ int __cold open_ctree(struct super_block *sb,
 		goto fail_qgroup;
 	}
 
-	if (!btrfs_grab_fs_root(fs_info->fs_root)) {
-		fs_info->fs_root = NULL;
-		err = -ENOENT;
-		btrfs_warn(fs_info, "failed to grab a ref on the fs tree");
-		goto fail_qgroup;
-	}
-
 	if (sb_rdonly(sb))
 		return 0;
 
diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c
index eba6c6d27bad..f07c2300ade2 100644
--- a/fs/btrfs/export.c
+++ b/fs/btrfs/export.c
@@ -82,10 +82,6 @@ static struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid,
 		err = PTR_ERR(root);
 		goto fail;
 	}
-	if (!btrfs_grab_fs_root(root)) {
-		err = -ENOENT;
-		goto fail;
-	}
 
 	key.objectid = objectid;
 	key.type = BTRFS_INODE_ITEM_KEY;
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 3abc7986052b..682f21ee6034 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -292,10 +292,6 @@ static int __btrfs_run_defrag_inode(struct btrfs_fs_info *fs_info,
 		ret = PTR_ERR(inode_root);
 		goto cleanup;
 	}
-	if (!btrfs_grab_fs_root(inode_root)) {
-		ret = -ENOENT;
-		goto cleanup;
-	}
 
 	key.objectid = defrag->ino;
 	key.type = BTRFS_INODE_ITEM_KEY;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 85104886c1e7..c01dc2790a40 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -5026,10 +5026,6 @@ static int fixup_tree_root_location(struct btrfs_fs_info *fs_info,
 		err = PTR_ERR(new_root);
 		goto out;
 	}
-	if (!btrfs_grab_fs_root(new_root)) {
-		err = -ENOENT;
-		goto out;
-	}
 
 	*sub_root = new_root;
 	location->objectid = btrfs_root_dirid(&new_root->root_item);
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 47953d022328..20861cabe6a1 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -672,11 +672,6 @@ static noinline int create_subvol(struct inode *dir,
 		btrfs_abort_transaction(trans, ret);
 		goto fail;
 	}
-	if (!btrfs_grab_fs_root(new_root)) {
-		ret = -ENOENT;
-		btrfs_abort_transaction(trans, ret);
-		goto fail;
-	}
 
 	btrfs_record_root_in_trans(trans, new_root);
 
@@ -2191,10 +2186,6 @@ static noinline int search_ioctl(struct inode *inode,
 			btrfs_free_path(path);
 			return PTR_ERR(root);
 		}
-		if (!btrfs_grab_fs_root(root)) {
-			btrfs_free_path(path);
-			return -ENOENT;
-		}
 	}
 
 	key.objectid = sk->min_objectid;
@@ -2332,11 +2323,6 @@ static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info,
 		root = NULL;
 		goto out;
 	}
-	if (!btrfs_grab_fs_root(root)) {
-		ret = -ENOENT;
-		root = NULL;
-		goto out;
-	}
 
 	key.objectid = dirid;
 	key.type = BTRFS_INODE_REF_KEY;
@@ -2433,10 +2419,6 @@ static int btrfs_search_path_in_tree_user(struct inode *inode,
 			ret = PTR_ERR(root);
 			goto out;
 		}
-		if (!btrfs_grab_fs_root(root)) {
-			ret = -ENOENT;
-			goto out;
-		}
 
 		key.objectid = dirid;
 		key.type = BTRFS_INODE_REF_KEY;
@@ -2686,10 +2668,6 @@ static int btrfs_ioctl_get_subvol_info(struct file *file, void __user *argp)
 		ret = PTR_ERR(root);
 		goto out_free;
 	}
-	if (!btrfs_grab_fs_root(root)) {
-		ret = -ENOENT;
-		goto out;
-	}
 	root_item = &root->root_item;
 
 	subvol_info->treeid = key.objectid;
@@ -4019,10 +3997,6 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp)
 		ret = PTR_ERR(new_root);
 		goto out;
 	}
-	if (!btrfs_grab_fs_root(root)) {
-		ret = -ENOENT;
-		goto out;
-	}
 	if (!is_fstree(new_root->root_key.objectid)) {
 		ret = -ENOENT;
 		goto out_free;
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index d166cc742f75..c08aeb83a8f7 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -613,7 +613,6 @@ static struct btrfs_root *read_fs_root(struct btrfs_fs_info *fs_info,
 					u64 root_objectid)
 {
 	struct btrfs_key key;
-	struct btrfs_root *root;
 
 	key.objectid = root_objectid;
 	key.type = BTRFS_ROOT_ITEM_KEY;
@@ -622,12 +621,7 @@ static struct btrfs_root *read_fs_root(struct btrfs_fs_info *fs_info,
 	else
 		key.offset = (u64)-1;
 
-	root = btrfs_get_fs_root(fs_info, &key, false);
-	if (IS_ERR(root))
-		return root;
-	if (!btrfs_grab_fs_root(root))
-		return ERR_PTR(-ENOENT);
-	return root;
+	return btrfs_get_fs_root(fs_info, &key, false);
 }
 
 static noinline_for_stack
diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c
index 25842527fd42..fca8334cb34d 100644
--- a/fs/btrfs/root-tree.c
+++ b/fs/btrfs/root-tree.c
@@ -257,8 +257,6 @@ int btrfs_find_orphan_roots(struct btrfs_fs_info *fs_info)
 
 		root = btrfs_get_fs_root(fs_info, &root_key, false);
 		err = PTR_ERR_OR_ZERO(root);
-		if (!err && !btrfs_grab_fs_root(root))
-			err = -ENOENT;
 		if (err && err != -ENOENT) {
 			break;
 		} else if (err == -ENOENT) {
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index f9ee327d7978..4f21f0b04a17 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -658,10 +658,6 @@ static int scrub_print_warning_inode(u64 inum, u64 offset, u64 root,
 		ret = PTR_ERR(local_root);
 		goto err;
 	}
-	if (!btrfs_grab_fs_root(local_root)) {
-		ret = -ENOENT;
-		goto err;
-	}
 
 	/*
 	 * this makes the path point to (inum INODE_ITEM ioff)
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index ee2fc9ea9d7e..5ef4c6f75ecd 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -7200,11 +7200,6 @@ long btrfs_ioctl_send(struct file *mnt_file, struct btrfs_ioctl_send_args *arg)
 				ret = PTR_ERR(clone_root);
 				goto out;
 			}
-			if (!btrfs_grab_fs_root(clone_root)) {
-				srcu_read_unlock(&fs_info->subvol_srcu, index);
-				ret = -ENOENT;
-				goto out;
-			}
 			spin_lock(&clone_root->root_item_lock);
 			if (!btrfs_root_readonly(clone_root) ||
 			    btrfs_root_dead(clone_root)) {
@@ -7246,12 +7241,6 @@ long btrfs_ioctl_send(struct file *mnt_file, struct btrfs_ioctl_send_args *arg)
 			ret = PTR_ERR(sctx->parent_root);
 			goto out;
 		}
-		if (!btrfs_grab_fs_root(sctx->parent_root)) {
-			srcu_read_unlock(&fs_info->subvol_srcu, index);
-			ret = -ENOENT;
-			sctx->parent_root = ERR_PTR(ret);
-			goto out;
-		}
 
 		spin_lock(&sctx->parent_root->root_item_lock);
 		sctx->parent_root->send_in_progress++;
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 0c81456df23e..8ce292a47634 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -1101,10 +1101,6 @@ static char *get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info,
 			ret = PTR_ERR(fs_root);
 			goto err;
 		}
-		if (!btrfs_grab_fs_root(fs_root)) {
-			ret = -ENOENT;
-			goto err;
-		}
 
 		/*
 		 * Walk up the filesystem tree by inode refs until we hit the
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 7008def3391b..e194d3e4e3a9 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -1637,12 +1637,6 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
 		btrfs_abort_transaction(trans, ret);
 		goto fail;
 	}
-	if (!btrfs_grab_fs_root(pending->snap)) {
-		ret = -ENOENT;
-		pending->snap = NULL;
-		btrfs_abort_transaction(trans, ret);
-		goto fail;
-	}
 
 	ret = btrfs_reloc_post_snapshot(trans, pending);
 	if (ret) {
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index f06ad415faf8..e7525689b1e8 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -6114,10 +6114,6 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
 		tmp_key.offset = (u64)-1;
 
 		wc.replay_dest = btrfs_get_fs_root(fs_info, &tmp_key, true);
-		if (!IS_ERR(wc.replay_dest)) {
-			if (!btrfs_grab_fs_root(wc.replay_dest))
-				wc.replay_dest = ERR_PTR(-ENOENT);
-		}
 		if (IS_ERR(wc.replay_dest)) {
 			ret = PTR_ERR(wc.replay_dest);
 
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 527b0b41ebdc..4a922b9f6e2c 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -4382,10 +4382,6 @@ static int btrfs_check_uuid_tree_entry(struct btrfs_fs_info *fs_info,
 			ret = 1;
 		goto out;
 	}
-	if (!btrfs_grab_fs_root(subvol_root)) {
-		ret = 1;
-		goto out;
-	}
 
 	switch (type) {
 	case BTRFS_UUID_KEY_SUBVOL:
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 40/44] btrfs: free more things in btrfs_free_fs_info
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (38 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 39/44] btrfs: push btrfs_grab_fs_root into btrfs_get_fs_root Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:32 ` [PATCH 41/44] btrfs: move fs_info init work into it's own helper function Josef Bacik
                   ` (5 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs

Things like the percpu_counters, the mapping_tree, and the csum hash can
all be free'd at btrfs_free_fs_info time, since the helpers all check if
the structure has been init'ed already.  This significantly cleans up
the error cases in open_ctree.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/disk-io.c | 60 +++++++++++++++++++---------------------------
 1 file changed, 24 insertions(+), 36 deletions(-)

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index ac306807e5cd..d8adc9c6d8ea 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -98,6 +98,12 @@ void __cold btrfs_end_io_wq_exit(void)
 	kmem_cache_destroy(btrfs_end_io_wq_cache);
 }
 
+static void btrfs_free_csum_hash(struct btrfs_fs_info *fs_info)
+{
+	if (fs_info->csum_shash)
+		crypto_free_shash(fs_info->csum_shash);
+}
+
 /*
  * async submit bios are used to offload expensive checksumming
  * onto the worker threads.  They checksum file and metadata bios
@@ -1527,6 +1533,13 @@ int btrfs_insert_fs_root(struct btrfs_fs_info *fs_info,
 
 void btrfs_free_fs_info(struct btrfs_fs_info *fs_info)
 {
+	percpu_counter_destroy(&fs_info->dirty_metadata_bytes);
+	percpu_counter_destroy(&fs_info->delalloc_bytes);
+	percpu_counter_destroy(&fs_info->dio_bytes);
+	percpu_counter_destroy(&fs_info->dev_replace.bio_counter);
+	btrfs_free_csum_hash(fs_info);
+	btrfs_free_stripe_hash_table(fs_info);
+	btrfs_free_ref_cache(fs_info);
 	kfree(fs_info->balance_ctl);
 	kfree(fs_info->delayed_root);
 	btrfs_put_fs_root(fs_info->extent_root);
@@ -2207,11 +2220,6 @@ static int btrfs_init_csum_hash(struct btrfs_fs_info *fs_info, u16 csum_type)
 	return 0;
 }
 
-static void btrfs_free_csum_hash(struct btrfs_fs_info *fs_info)
-{
-	crypto_free_shash(fs_info->csum_shash);
-}
-
 static int btrfs_replay_log(struct btrfs_fs_info *fs_info,
 			    struct btrfs_fs_devices *fs_devices)
 {
@@ -2686,7 +2694,7 @@ int __cold open_ctree(struct super_block *sb,
 	ret = percpu_counter_init(&fs_info->dirty_metadata_bytes, 0, GFP_KERNEL);
 	if (ret) {
 		err = ret;
-		goto fail_dio_bytes;
+		goto fail_srcu;
 	}
 	fs_info->dirty_metadata_batch = PAGE_SIZE *
 					(1 + ilog2(nr_cpu_ids));
@@ -2694,14 +2702,14 @@ int __cold open_ctree(struct super_block *sb,
 	ret = percpu_counter_init(&fs_info->delalloc_bytes, 0, GFP_KERNEL);
 	if (ret) {
 		err = ret;
-		goto fail_dirty_metadata_bytes;
+		goto fail_srcu;
 	}
 
 	ret = percpu_counter_init(&fs_info->dev_replace.bio_counter, 0,
 			GFP_KERNEL);
 	if (ret) {
 		err = ret;
-		goto fail_delalloc_bytes;
+		goto fail_srcu;
 	}
 
 	INIT_RADIX_TREE(&fs_info->fs_roots_radix, GFP_ATOMIC);
@@ -2769,7 +2777,7 @@ int __cold open_ctree(struct super_block *sb,
 	fs_info->btree_inode = new_inode(sb);
 	if (!fs_info->btree_inode) {
 		err = -ENOMEM;
-		goto fail_bio_counter;
+		goto fail_srcu;
 	}
 	mapping_set_gfp_mask(fs_info->btree_inode->i_mapping, GFP_NOFS);
 
@@ -2882,7 +2890,7 @@ int __cold open_ctree(struct super_block *sb,
 		btrfs_err(fs_info, "superblock checksum mismatch");
 		err = -EINVAL;
 		brelse(bh);
-		goto fail_csum;
+		goto fail_alloc;
 	}
 
 	/*
@@ -2919,11 +2927,11 @@ int __cold open_ctree(struct super_block *sb,
 	if (ret) {
 		btrfs_err(fs_info, "superblock contains fatal errors");
 		err = -EINVAL;
-		goto fail_csum;
+		goto fail_alloc;
 	}
 
 	if (!btrfs_super_root(disk_super))
-		goto fail_csum;
+		goto fail_alloc;
 
 	/* check FS state, whether FS is broken. */
 	if (btrfs_super_flags(disk_super) & BTRFS_SUPER_FLAG_ERROR)
@@ -2938,7 +2946,7 @@ int __cold open_ctree(struct super_block *sb,
 	ret = btrfs_parse_options(fs_info, options, sb->s_flags);
 	if (ret) {
 		err = ret;
-		goto fail_csum;
+		goto fail_alloc;
 	}
 
 	features = btrfs_super_incompat_flags(disk_super) &
@@ -2948,7 +2956,7 @@ int __cold open_ctree(struct super_block *sb,
 		    "cannot mount because of unsupported optional features (%llx)",
 		    features);
 		err = -EINVAL;
-		goto fail_csum;
+		goto fail_alloc;
 	}
 
 	features = btrfs_super_incompat_flags(disk_super);
@@ -2992,7 +3000,7 @@ int __cold open_ctree(struct super_block *sb,
 		btrfs_err(fs_info,
 "unequal nodesize/sectorsize (%u != %u) are not allowed for mixed block groups",
 			nodesize, sectorsize);
-		goto fail_csum;
+		goto fail_alloc;
 	}
 
 	/*
@@ -3008,7 +3016,7 @@ int __cold open_ctree(struct super_block *sb,
 	"cannot mount read-write because of unsupported optional features (%llx)",
 		       features);
 		err = -EINVAL;
-		goto fail_csum;
+		goto fail_alloc;
 	}
 
 	ret = btrfs_init_workqueues(fs_info, fs_devices);
@@ -3343,25 +3351,14 @@ int __cold open_ctree(struct super_block *sb,
 fail_sb_buffer:
 	btrfs_stop_all_workers(fs_info);
 	btrfs_free_block_groups(fs_info);
-fail_csum:
-	btrfs_free_csum_hash(fs_info);
 fail_alloc:
 fail_iput:
 	btrfs_mapping_tree_free(&fs_info->mapping_tree);
 
 	iput(fs_info->btree_inode);
-fail_bio_counter:
-	percpu_counter_destroy(&fs_info->dev_replace.bio_counter);
-fail_delalloc_bytes:
-	percpu_counter_destroy(&fs_info->delalloc_bytes);
-fail_dirty_metadata_bytes:
-	percpu_counter_destroy(&fs_info->dirty_metadata_bytes);
-fail_dio_bytes:
-	percpu_counter_destroy(&fs_info->dio_bytes);
 fail_srcu:
 	cleanup_srcu_struct(&fs_info->subvol_srcu);
 fail:
-	btrfs_free_stripe_hash_table(fs_info);
 	btrfs_close_devices(fs_info->fs_devices);
 	return err;
 }
@@ -4061,16 +4058,7 @@ void __cold close_ctree(struct btrfs_fs_info *fs_info)
 
 	btrfs_mapping_tree_free(&fs_info->mapping_tree);
 	btrfs_close_devices(fs_info->fs_devices);
-
-	percpu_counter_destroy(&fs_info->dirty_metadata_bytes);
-	percpu_counter_destroy(&fs_info->delalloc_bytes);
-	percpu_counter_destroy(&fs_info->dio_bytes);
-	percpu_counter_destroy(&fs_info->dev_replace.bio_counter);
 	cleanup_srcu_struct(&fs_info->subvol_srcu);
-
-	btrfs_free_csum_hash(fs_info);
-	btrfs_free_stripe_hash_table(fs_info);
-	btrfs_free_ref_cache(fs_info);
 }
 
 int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid,
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 41/44] btrfs: move fs_info init work into it's own helper function
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (39 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 40/44] btrfs: free more things in btrfs_free_fs_info Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:32 ` [PATCH 42/44] btrfs: make the init of static elements in fs_info separate Josef Bacik
                   ` (4 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs; +Cc: Nikolay Borisov

open_ctree mixes initialization of fs stuff and fs_info stuff, which
makes it confusing when doing things like adding the root leak
detection.  Make a separate function that init's all the static
structures inside of the fs_info needed for the fs to operate, and then
call that before we start setting up the fs_info to be mounted.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
---
 fs/btrfs/disk-io.c | 162 +++++++++++++++++++++++----------------------
 1 file changed, 83 insertions(+), 79 deletions(-)

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index d8adc9c6d8ea..b7e4313bdc6f 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2649,68 +2649,9 @@ static int __cold init_tree_roots(struct btrfs_fs_info *fs_info)
 	return ret;
 }
 
-int __cold open_ctree(struct super_block *sb,
-	       struct btrfs_fs_devices *fs_devices,
-	       char *options)
+static int init_fs_info(struct btrfs_fs_info *fs_info, struct super_block *sb)
 {
-	u32 sectorsize;
-	u32 nodesize;
-	u32 stripesize;
-	u64 generation;
-	u64 features;
-	u16 csum_type;
-	struct btrfs_key location;
-	struct buffer_head *bh;
-	struct btrfs_super_block *disk_super;
-	struct btrfs_fs_info *fs_info = btrfs_sb(sb);
-	struct btrfs_root *tree_root;
-	struct btrfs_root *chunk_root;
 	int ret;
-	int err = -EINVAL;
-	int clear_free_space_tree = 0;
-	int level;
-
-	tree_root = fs_info->tree_root = btrfs_alloc_root(fs_info,
-					BTRFS_ROOT_TREE_OBJECTID, GFP_KERNEL);
-	chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info,
-					BTRFS_CHUNK_TREE_OBJECTID, GFP_KERNEL);
-	if (!tree_root || !chunk_root) {
-		err = -ENOMEM;
-		goto fail;
-	}
-
-	ret = init_srcu_struct(&fs_info->subvol_srcu);
-	if (ret) {
-		err = ret;
-		goto fail;
-	}
-
-	ret = percpu_counter_init(&fs_info->dio_bytes, 0, GFP_KERNEL);
-	if (ret) {
-		err = ret;
-		goto fail_srcu;
-	}
-
-	ret = percpu_counter_init(&fs_info->dirty_metadata_bytes, 0, GFP_KERNEL);
-	if (ret) {
-		err = ret;
-		goto fail_srcu;
-	}
-	fs_info->dirty_metadata_batch = PAGE_SIZE *
-					(1 + ilog2(nr_cpu_ids));
-
-	ret = percpu_counter_init(&fs_info->delalloc_bytes, 0, GFP_KERNEL);
-	if (ret) {
-		err = ret;
-		goto fail_srcu;
-	}
-
-	ret = percpu_counter_init(&fs_info->dev_replace.bio_counter, 0,
-			GFP_KERNEL);
-	if (ret) {
-		err = ret;
-		goto fail_srcu;
-	}
 
 	INIT_RADIX_TREE(&fs_info->fs_roots_radix, GFP_ATOMIC);
 	INIT_RADIX_TREE(&fs_info->buffer_radix, GFP_ATOMIC);
@@ -2774,21 +2715,6 @@ int __cold open_ctree(struct super_block *sb,
 	INIT_LIST_HEAD(&fs_info->ordered_roots);
 	spin_lock_init(&fs_info->ordered_root_lock);
 
-	fs_info->btree_inode = new_inode(sb);
-	if (!fs_info->btree_inode) {
-		err = -ENOMEM;
-		goto fail_srcu;
-	}
-	mapping_set_gfp_mask(fs_info->btree_inode->i_mapping, GFP_NOFS);
-
-	fs_info->delayed_root = kmalloc(sizeof(struct btrfs_delayed_root),
-					GFP_KERNEL);
-	if (!fs_info->delayed_root) {
-		err = -ENOMEM;
-		goto fail_iput;
-	}
-	btrfs_init_delayed_root(fs_info->delayed_root);
-
 	btrfs_init_scrub(fs_info);
 #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY
 	fs_info->check_integrity_print_mask = 0;
@@ -2799,8 +2725,6 @@ int __cold open_ctree(struct super_block *sb,
 	sb->s_blocksize = BTRFS_BDEV_BLOCKSIZE;
 	sb->s_blocksize_bits = blksize_bits(BTRFS_BDEV_BLOCKSIZE);
 
-	btrfs_init_btree_inode(fs_info);
-
 	spin_lock_init(&fs_info->block_group_cache_lock);
 	fs_info->block_group_cache_tree = RB_ROOT;
 	fs_info->first_logical_byte = (u64)-1;
@@ -2846,12 +2770,93 @@ int __cold open_ctree(struct super_block *sb,
 
 	fs_info->send_in_progress = 0;
 
+	ret = init_srcu_struct(&fs_info->subvol_srcu);
+	if (ret)
+		return ret;
+
+	ret = percpu_counter_init(&fs_info->dio_bytes, 0, GFP_KERNEL);
+	if (ret)
+		goto fail;
+
+	ret = percpu_counter_init(&fs_info->dirty_metadata_bytes, 0, GFP_KERNEL);
+	if (ret)
+		goto fail;
+
+	fs_info->dirty_metadata_batch = PAGE_SIZE *
+					(1 + ilog2(nr_cpu_ids));
+
+	ret = percpu_counter_init(&fs_info->delalloc_bytes, 0, GFP_KERNEL);
+	if (ret)
+		goto fail;
+
+	ret = percpu_counter_init(&fs_info->dev_replace.bio_counter, 0,
+			GFP_KERNEL);
+	if (ret)
+		goto fail;
+
+	fs_info->delayed_root = kmalloc(sizeof(struct btrfs_delayed_root),
+					GFP_KERNEL);
+	if (!fs_info->delayed_root) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+	btrfs_init_delayed_root(fs_info->delayed_root);
+
 	ret = btrfs_alloc_stripe_hash_table(fs_info);
+	if (ret)
+		goto fail;
+
+	return 0;
+fail:
+	cleanup_srcu_struct(&fs_info->subvol_srcu);
+	return ret;
+}
+
+int __cold open_ctree(struct super_block *sb,
+	       struct btrfs_fs_devices *fs_devices,
+	       char *options)
+{
+	u32 sectorsize;
+	u32 nodesize;
+	u32 stripesize;
+	u64 generation;
+	u64 features;
+	u16 csum_type;
+	struct btrfs_key location;
+	struct buffer_head *bh;
+	struct btrfs_super_block *disk_super;
+	struct btrfs_fs_info *fs_info = btrfs_sb(sb);
+	struct btrfs_root *tree_root;
+	struct btrfs_root *chunk_root;
+	int ret;
+	int err = -EINVAL;
+	int clear_free_space_tree = 0;
+	int level;
+
+	ret = init_fs_info(fs_info, sb);
 	if (ret) {
 		err = ret;
-		goto fail_alloc;
+		goto fail;
 	}
 
+	/* These need to be init'ed before we start creating inodes and such. */
+	tree_root = fs_info->tree_root = btrfs_alloc_root(fs_info,
+					BTRFS_ROOT_TREE_OBJECTID, GFP_KERNEL);
+	chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info,
+					BTRFS_CHUNK_TREE_OBJECTID, GFP_KERNEL);
+	if (!tree_root || !chunk_root) {
+		err = -ENOMEM;
+		goto fail_srcu;
+	}
+
+	fs_info->btree_inode = new_inode(sb);
+	if (!fs_info->btree_inode) {
+		err = -ENOMEM;
+		goto fail_srcu;
+	}
+	mapping_set_gfp_mask(fs_info->btree_inode->i_mapping, GFP_NOFS);
+	btrfs_init_btree_inode(fs_info);
+
 	invalidate_bdev(fs_devices->latest_bdev);
 
 	/*
@@ -3352,7 +3357,6 @@ int __cold open_ctree(struct super_block *sb,
 	btrfs_stop_all_workers(fs_info);
 	btrfs_free_block_groups(fs_info);
 fail_alloc:
-fail_iput:
 	btrfs_mapping_tree_free(&fs_info->mapping_tree);
 
 	iput(fs_info->btree_inode);
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 42/44] btrfs: make the init of static elements in fs_info separate
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (40 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 41/44] btrfs: move fs_info init work into it's own helper function Josef Bacik
@ 2020-01-24 14:32 ` Josef Bacik
  2020-01-24 14:33 ` [PATCH 43/44] btrfs: add a leak check for roots Josef Bacik
                   ` (3 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:32 UTC (permalink / raw)
  To: kernel-team, linux-btrfs

In adding things like eb leak checking and root leak checking there were
a lot of weird corner cases that come from the fact that

1) We do not init the fs_info until we get to open_ctree time in the
normal case and

2) The test infrastructure half-init's the fs_info for things that it
needs.

This makes it really annoying to make changes because you have to add
init in two different places, have special cases for testing fs_info's
that may not have certain things init'ed, and cases for fs_info's that
didn't make it to open_ctree and thus are not fully init'ed.

Fix this by extracting out the non-allocating init of the fs info into
it's own public function and use that to make sure we're all getting
consistent views of an allocated fs_info.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/disk-io.c           | 19 +++++++++++--------
 fs/btrfs/disk-io.h           |  1 +
 fs/btrfs/super.c             |  7 +++++--
 fs/btrfs/tests/btrfs-tests.c | 28 ++++------------------------
 4 files changed, 21 insertions(+), 34 deletions(-)

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index b7e4313bdc6f..87bad959b1a5 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2649,10 +2649,8 @@ static int __cold init_tree_roots(struct btrfs_fs_info *fs_info)
 	return ret;
 }
 
-static int init_fs_info(struct btrfs_fs_info *fs_info, struct super_block *sb)
+void btrfs_init_fs_info(struct btrfs_fs_info *fs_info)
 {
-	int ret;
-
 	INIT_RADIX_TREE(&fs_info->fs_roots_radix, GFP_ATOMIC);
 	INIT_RADIX_TREE(&fs_info->buffer_radix, GFP_ATOMIC);
 	INIT_LIST_HEAD(&fs_info->trans_list);
@@ -2696,7 +2694,6 @@ static int init_fs_info(struct btrfs_fs_info *fs_info, struct super_block *sb)
 	atomic_set(&fs_info->reada_works_cnt, 0);
 	atomic_set(&fs_info->nr_delayed_iputs, 0);
 	atomic64_set(&fs_info->tree_mod_seq, 0);
-	fs_info->sb = sb;
 	fs_info->max_inline = BTRFS_DEFAULT_MAX_INLINE;
 	fs_info->metadata_ratio = 0;
 	fs_info->defrag_inodes = RB_ROOT;
@@ -2722,9 +2719,6 @@ static int init_fs_info(struct btrfs_fs_info *fs_info, struct super_block *sb)
 	btrfs_init_balance(fs_info);
 	btrfs_init_async_reclaim_work(&fs_info->async_reclaim_work);
 
-	sb->s_blocksize = BTRFS_BDEV_BLOCKSIZE;
-	sb->s_blocksize_bits = blksize_bits(BTRFS_BDEV_BLOCKSIZE);
-
 	spin_lock_init(&fs_info->block_group_cache_lock);
 	fs_info->block_group_cache_tree = RB_ROOT;
 	fs_info->first_logical_byte = (u64)-1;
@@ -2769,6 +2763,15 @@ static int init_fs_info(struct btrfs_fs_info *fs_info, struct super_block *sb)
 	fs_info->swapfile_pins = RB_ROOT;
 
 	fs_info->send_in_progress = 0;
+}
+
+static int init_mount_fs_info(struct btrfs_fs_info *fs_info, struct super_block *sb)
+{
+	int ret;
+
+	fs_info->sb = sb;
+	sb->s_blocksize = BTRFS_BDEV_BLOCKSIZE;
+	sb->s_blocksize_bits = blksize_bits(BTRFS_BDEV_BLOCKSIZE);
 
 	ret = init_srcu_struct(&fs_info->subvol_srcu);
 	if (ret)
@@ -2833,7 +2836,7 @@ int __cold open_ctree(struct super_block *sb,
 	int clear_free_space_tree = 0;
 	int level;
 
-	ret = init_fs_info(fs_info, sb);
+	ret = init_mount_fs_info(fs_info, sb);
 	if (ret) {
 		err = ret;
 		goto fail;
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
index 97e7ac474a52..2414d572bc9a 100644
--- a/fs/btrfs/disk-io.h
+++ b/fs/btrfs/disk-io.h
@@ -39,6 +39,7 @@ static inline u64 btrfs_sb_offset(int mirror)
 struct btrfs_device;
 struct btrfs_fs_devices;
 
+void btrfs_init_fs_info(struct btrfs_fs_info *fs_info);
 int btrfs_verify_level_key(struct extent_buffer *eb, int level,
 			   struct btrfs_key *first_key, u64 parent_transid);
 struct extent_buffer *read_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr,
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 8ce292a47634..cf8c49d06a77 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -1523,14 +1523,17 @@ static struct dentry *btrfs_mount_root(struct file_system_type *fs_type,
 	/*
 	 * Setup a dummy root and fs_info for test/set super.  This is because
 	 * we don't actually fill this stuff out until open_ctree, but we need
-	 * it for searching for existing supers, so this lets us do that and
-	 * then open_ctree will properly initialize everything later.
+	 * then open_ctree will properly initialize the file system specific
+	 * settings later.  btrfs_init_fs_info initializes the static elements
+	 * of the fs_info (locks and such) to make cleanup easier if we find a
+	 * superblock with our given fs_devices later on at sget() time.
 	 */
 	fs_info = kvzalloc(sizeof(struct btrfs_fs_info), GFP_KERNEL);
 	if (!fs_info) {
 		error = -ENOMEM;
 		goto error_sec_opts;
 	}
+	btrfs_init_fs_info(fs_info);
 
 	fs_info->super_copy = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_KERNEL);
 	fs_info->super_for_commit = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_KERNEL);
diff --git a/fs/btrfs/tests/btrfs-tests.c b/fs/btrfs/tests/btrfs-tests.c
index 27f5b662d2cb..683381a692bc 100644
--- a/fs/btrfs/tests/btrfs-tests.c
+++ b/fs/btrfs/tests/btrfs-tests.c
@@ -120,6 +120,8 @@ struct btrfs_fs_info *btrfs_alloc_dummy_fs_info(u32 nodesize, u32 sectorsize)
 		kfree(fs_info);
 		return NULL;
 	}
+	INIT_LIST_HEAD(&fs_info->fs_devices->devices);
+
 	fs_info->super_copy = kzalloc(sizeof(struct btrfs_super_block),
 				      GFP_KERNEL);
 	if (!fs_info->super_copy) {
@@ -128,6 +130,8 @@ struct btrfs_fs_info *btrfs_alloc_dummy_fs_info(u32 nodesize, u32 sectorsize)
 		return NULL;
 	}
 
+	btrfs_init_fs_info(fs_info);
+
 	fs_info->nodesize = nodesize;
 	fs_info->sectorsize = sectorsize;
 
@@ -138,30 +142,6 @@ struct btrfs_fs_info *btrfs_alloc_dummy_fs_info(u32 nodesize, u32 sectorsize)
 		return NULL;
 	}
 
-	spin_lock_init(&fs_info->buffer_lock);
-	spin_lock_init(&fs_info->qgroup_lock);
-	spin_lock_init(&fs_info->super_lock);
-	spin_lock_init(&fs_info->fs_roots_radix_lock);
-	spin_lock_init(&fs_info->tree_mod_seq_lock);
-	mutex_init(&fs_info->qgroup_ioctl_lock);
-	mutex_init(&fs_info->qgroup_rescan_lock);
-	rwlock_init(&fs_info->tree_mod_log_lock);
-	fs_info->running_transaction = NULL;
-	fs_info->qgroup_tree = RB_ROOT;
-	fs_info->qgroup_ulist = NULL;
-	atomic64_set(&fs_info->tree_mod_seq, 0);
-	INIT_LIST_HEAD(&fs_info->dirty_qgroups);
-	INIT_LIST_HEAD(&fs_info->dead_roots);
-	INIT_LIST_HEAD(&fs_info->tree_mod_seq_list);
-	INIT_LIST_HEAD(&fs_info->fs_devices->devices);
-	INIT_RADIX_TREE(&fs_info->buffer_radix, GFP_ATOMIC);
-	INIT_RADIX_TREE(&fs_info->fs_roots_radix, GFP_ATOMIC);
-	extent_io_tree_init(fs_info, &fs_info->freed_extents[0],
-			    IO_TREE_FS_INFO_FREED_EXTENTS0, NULL);
-	extent_io_tree_init(fs_info, &fs_info->freed_extents[1],
-			    IO_TREE_FS_INFO_FREED_EXTENTS1, NULL);
-	extent_map_tree_init(&fs_info->mapping_tree);
-	fs_info->pinned_extents = &fs_info->freed_extents[0];
 	set_bit(BTRFS_FS_STATE_DUMMY_FS_INFO, &fs_info->fs_state);
 
 	test_mnt->mnt_sb->s_fs_info = fs_info;
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 43/44] btrfs: add a leak check for roots
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (41 preceding siblings ...)
  2020-01-24 14:32 ` [PATCH 42/44] btrfs: make the init of static elements in fs_info separate Josef Bacik
@ 2020-01-24 14:33 ` Josef Bacik
  2020-01-24 14:33 ` [PATCH 44/44] btrfs: rename btrfs_put_fs_root and btrfs_grab_fs_root Josef Bacik
                   ` (2 subsequent siblings)
  45 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:33 UTC (permalink / raw)
  To: kernel-team, linux-btrfs; +Cc: Nikolay Borisov

Now that we're going to start relying on getting ref counting right for
roots, add a list to track allocated roots and print out any roots that
aren't free'd up at free_fs_info time.  Hide this behind
CONFIG_BTRFS_DEBUG because this will just be used for developers to
verify they aren't breaking things.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
---
 fs/btrfs/ctree.h             |  5 +++++
 fs/btrfs/disk-io.c           | 28 ++++++++++++++++++++++++++++
 fs/btrfs/disk-io.h           |  9 ++++++++-
 fs/btrfs/tests/btrfs-tests.c |  1 +
 4 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 68510af4cacf..6006e10f371f 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -949,6 +949,7 @@ struct btrfs_fs_info {
 #ifdef CONFIG_BTRFS_DEBUG
 	struct kobject *debug_kobj;
 	struct kobject *discard_debug_kobj;
+	struct list_head alloced_roots;
 #endif
 };
 
@@ -1151,6 +1152,10 @@ struct btrfs_root {
 #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
 	u64 alloc_bytenr;
 #endif
+
+#ifdef CONFIG_BTRFS_DEBUG
+	struct list_head leak_list;
+#endif
 };
 
 struct btrfs_clone_extent_info {
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 87bad959b1a5..c01cade1a935 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1202,6 +1202,12 @@ static void __setup_root(struct btrfs_root *root, struct btrfs_fs_info *fs_info,
 
 	spin_lock_init(&root->root_item_lock);
 	btrfs_qgroup_init_swapped_blocks(&root->swapped_blocks);
+#ifdef CONFIG_BTRFS_DEBUG
+	INIT_LIST_HEAD(&root->leak_list);
+	spin_lock(&fs_info->fs_roots_radix_lock);
+	list_add_tail(&root->leak_list, &fs_info->alloced_roots);
+	spin_unlock(&fs_info->fs_roots_radix_lock);
+#endif
 }
 
 static struct btrfs_root *btrfs_alloc_root(struct btrfs_fs_info *fs_info,
@@ -1531,6 +1537,24 @@ int btrfs_insert_fs_root(struct btrfs_fs_info *fs_info,
 	return ret;
 }
 
+void btrfs_check_leaked_roots(struct btrfs_fs_info *fs_info)
+{
+#ifdef CONFIG_BTRFS_DEBUG
+	struct btrfs_root *root;
+
+	while (!list_empty(&fs_info->alloced_roots)) {
+		root = list_first_entry(&fs_info->alloced_roots,
+					struct btrfs_root, leak_list);
+		btrfs_err(fs_info, "leaked root %llu-%llu refcount %d",
+			  root->root_key.objectid, root->root_key.offset,
+			  refcount_read(&root->refs));
+		while (refcount_read(&root->refs) > 1)
+			btrfs_put_fs_root(root);
+		btrfs_put_fs_root(root);
+	}
+#endif
+}
+
 void btrfs_free_fs_info(struct btrfs_fs_info *fs_info)
 {
 	percpu_counter_destroy(&fs_info->dirty_metadata_bytes);
@@ -1551,6 +1575,7 @@ void btrfs_free_fs_info(struct btrfs_fs_info *fs_info)
 	btrfs_put_fs_root(fs_info->uuid_root);
 	btrfs_put_fs_root(fs_info->free_space_root);
 	btrfs_put_fs_root(fs_info->fs_root);
+	btrfs_check_leaked_roots(fs_info);
 	kfree(fs_info->super_copy);
 	kfree(fs_info->super_for_commit);
 	kvfree(fs_info);
@@ -2678,6 +2703,9 @@ void btrfs_init_fs_info(struct btrfs_fs_info *fs_info)
 	INIT_LIST_HEAD(&fs_info->space_info);
 	INIT_LIST_HEAD(&fs_info->tree_mod_seq_list);
 	INIT_LIST_HEAD(&fs_info->unused_bgs);
+#ifdef CONFIG_BTRFS_DEBUG
+	INIT_LIST_HEAD(&fs_info->alloced_roots);
+#endif
 	extent_map_tree_init(&fs_info->mapping_tree);
 	btrfs_init_block_rsv(&fs_info->global_block_rsv,
 			     BTRFS_BLOCK_RSV_GLOBAL);
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
index 2414d572bc9a..04a29f961527 100644
--- a/fs/btrfs/disk-io.h
+++ b/fs/btrfs/disk-io.h
@@ -39,6 +39,7 @@ static inline u64 btrfs_sb_offset(int mirror)
 struct btrfs_device;
 struct btrfs_fs_devices;
 
+void btrfs_check_leaked_roots(struct btrfs_fs_info *fs_info);
 void btrfs_init_fs_info(struct btrfs_fs_info *fs_info);
 int btrfs_verify_level_key(struct extent_buffer *eb, int level,
 			   struct btrfs_key *first_key, u64 parent_transid);
@@ -101,8 +102,14 @@ static inline void btrfs_put_fs_root(struct btrfs_root *root)
 {
 	if (!root)
 		return;
-	if (refcount_dec_and_test(&root->refs))
+	if (refcount_dec_and_test(&root->refs)) {
+#ifdef CONFIG_BTRFS_DEBUG
+		spin_lock(&root->fs_info->fs_roots_radix_lock);
+		list_del_init(&root->leak_list);
+		spin_unlock(&root->fs_info->fs_roots_radix_lock);
+#endif
 		kfree(root);
+	}
 }
 
 void btrfs_mark_buffer_dirty(struct extent_buffer *buf);
diff --git a/fs/btrfs/tests/btrfs-tests.c b/fs/btrfs/tests/btrfs-tests.c
index 683381a692bc..609abca4fe3a 100644
--- a/fs/btrfs/tests/btrfs-tests.c
+++ b/fs/btrfs/tests/btrfs-tests.c
@@ -193,6 +193,7 @@ void btrfs_free_dummy_fs_info(struct btrfs_fs_info *fs_info)
 	btrfs_free_fs_roots(fs_info);
 	cleanup_srcu_struct(&fs_info->subvol_srcu);
 	kfree(fs_info->super_copy);
+	btrfs_check_leaked_roots(fs_info);
 	kfree(fs_info->fs_devices);
 	kfree(fs_info);
 }
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 44/44] btrfs: rename btrfs_put_fs_root and btrfs_grab_fs_root
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (42 preceding siblings ...)
  2020-01-24 14:33 ` [PATCH 43/44] btrfs: add a leak check for roots Josef Bacik
@ 2020-01-24 14:33 ` Josef Bacik
  2020-02-05 15:44   ` David Sterba
  2020-02-04 23:48 ` [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 David Sterba
  2020-02-05 15:48 ` David Sterba
  45 siblings, 1 reply; 63+ messages in thread
From: Josef Bacik @ 2020-01-24 14:33 UTC (permalink / raw)
  To: kernel-team, linux-btrfs; +Cc: Nikolay Borisov

We are now using these for all roots, rename them to btrfs_put_root()
and btrfs_grab_root();

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
---
 fs/btrfs/backref.c           |  2 +-
 fs/btrfs/disk-io.c           | 78 ++++++++++++++++++------------------
 fs/btrfs/disk-io.h           |  4 +-
 fs/btrfs/export.c            |  2 +-
 fs/btrfs/extent-tree.c       |  2 +-
 fs/btrfs/file.c              |  2 +-
 fs/btrfs/free-space-tree.c   |  2 +-
 fs/btrfs/inode.c             |  6 +--
 fs/btrfs/ioctl.c             | 18 ++++-----
 fs/btrfs/ordered-data.c      |  4 +-
 fs/btrfs/qgroup.c            |  4 +-
 fs/btrfs/relocation.c        | 50 +++++++++++------------
 fs/btrfs/root-tree.c         |  2 +-
 fs/btrfs/scrub.c             |  6 +--
 fs/btrfs/send.c              | 12 +++---
 fs/btrfs/super.c             | 10 ++---
 fs/btrfs/tests/btrfs-tests.c |  2 +-
 fs/btrfs/tree-log.c          | 10 ++---
 fs/btrfs/volumes.c           |  2 +-
 19 files changed, 109 insertions(+), 109 deletions(-)

diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index b69154d72529..ded46efac27d 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -577,7 +577,7 @@ static int resolve_indirect_ref(struct btrfs_fs_info *fs_info,
 	ret = add_all_parents(root, path, parents, ref, level, time_seq,
 			      extent_item_pos, total_refs, ignore_offset);
 out:
-	btrfs_put_fs_root(root);
+	btrfs_put_root(root);
 out_free:
 	path->lowest_level = 0;
 	btrfs_release_path(path);
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index c01cade1a935..62067f60456e 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1309,7 +1309,7 @@ struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans,
 		free_extent_buffer(root->commit_root);
 		free_extent_buffer(leaf);
 	}
-	btrfs_put_fs_root(root);
+	btrfs_put_root(root);
 
 	return ERR_PTR(ret);
 }
@@ -1340,7 +1340,7 @@ static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans,
 	leaf = btrfs_alloc_tree_block(trans, root, 0, BTRFS_TREE_LOG_OBJECTID,
 			NULL, 0, 0, 0);
 	if (IS_ERR(leaf)) {
-		btrfs_put_fs_root(root);
+		btrfs_put_root(root);
 		return ERR_CAST(leaf);
 	}
 
@@ -1443,7 +1443,7 @@ struct btrfs_root *btrfs_read_tree_root(struct btrfs_root *tree_root,
 	return root;
 
 find_fail:
-	btrfs_put_fs_root(root);
+	btrfs_put_root(root);
 alloc_fail:
 	root = ERR_PTR(ret);
 	goto out;
@@ -1509,7 +1509,7 @@ static struct btrfs_root *btrfs_lookup_fs_root(struct btrfs_fs_info *fs_info,
 	root = radix_tree_lookup(&fs_info->fs_roots_radix,
 				 (unsigned long)root_id);
 	if (root)
-		root = btrfs_grab_fs_root(root);
+		root = btrfs_grab_root(root);
 	spin_unlock(&fs_info->fs_roots_radix_lock);
 	return root;
 }
@@ -1528,7 +1528,7 @@ int btrfs_insert_fs_root(struct btrfs_fs_info *fs_info,
 				(unsigned long)root->root_key.objectid,
 				root);
 	if (ret == 0) {
-		btrfs_grab_fs_root(root);
+		btrfs_grab_root(root);
 		set_bit(BTRFS_ROOT_IN_RADIX, &root->state);
 	}
 	spin_unlock(&fs_info->fs_roots_radix_lock);
@@ -1549,8 +1549,8 @@ void btrfs_check_leaked_roots(struct btrfs_fs_info *fs_info)
 			  root->root_key.objectid, root->root_key.offset,
 			  refcount_read(&root->refs));
 		while (refcount_read(&root->refs) > 1)
-			btrfs_put_fs_root(root);
-		btrfs_put_fs_root(root);
+			btrfs_put_root(root);
+		btrfs_put_root(root);
 	}
 #endif
 }
@@ -1566,15 +1566,15 @@ void btrfs_free_fs_info(struct btrfs_fs_info *fs_info)
 	btrfs_free_ref_cache(fs_info);
 	kfree(fs_info->balance_ctl);
 	kfree(fs_info->delayed_root);
-	btrfs_put_fs_root(fs_info->extent_root);
-	btrfs_put_fs_root(fs_info->tree_root);
-	btrfs_put_fs_root(fs_info->chunk_root);
-	btrfs_put_fs_root(fs_info->dev_root);
-	btrfs_put_fs_root(fs_info->csum_root);
-	btrfs_put_fs_root(fs_info->quota_root);
-	btrfs_put_fs_root(fs_info->uuid_root);
-	btrfs_put_fs_root(fs_info->free_space_root);
-	btrfs_put_fs_root(fs_info->fs_root);
+	btrfs_put_root(fs_info->extent_root);
+	btrfs_put_root(fs_info->tree_root);
+	btrfs_put_root(fs_info->chunk_root);
+	btrfs_put_root(fs_info->dev_root);
+	btrfs_put_root(fs_info->csum_root);
+	btrfs_put_root(fs_info->quota_root);
+	btrfs_put_root(fs_info->uuid_root);
+	btrfs_put_root(fs_info->free_space_root);
+	btrfs_put_root(fs_info->fs_root);
 	btrfs_check_leaked_roots(fs_info);
 	kfree(fs_info->super_copy);
 	kfree(fs_info->super_for_commit);
@@ -1592,29 +1592,29 @@ struct btrfs_root *btrfs_get_fs_root(struct btrfs_fs_info *fs_info,
 	int ret;
 
 	if (location->objectid == BTRFS_ROOT_TREE_OBJECTID)
-		return btrfs_grab_fs_root(fs_info->tree_root);
+		return btrfs_grab_root(fs_info->tree_root);
 	if (location->objectid == BTRFS_EXTENT_TREE_OBJECTID)
-		return btrfs_grab_fs_root(fs_info->extent_root);
+		return btrfs_grab_root(fs_info->extent_root);
 	if (location->objectid == BTRFS_CHUNK_TREE_OBJECTID)
-		return btrfs_grab_fs_root(fs_info->chunk_root);
+		return btrfs_grab_root(fs_info->chunk_root);
 	if (location->objectid == BTRFS_DEV_TREE_OBJECTID)
-		return btrfs_grab_fs_root(fs_info->dev_root);
+		return btrfs_grab_root(fs_info->dev_root);
 	if (location->objectid == BTRFS_CSUM_TREE_OBJECTID)
-		return btrfs_grab_fs_root(fs_info->csum_root);
+		return btrfs_grab_root(fs_info->csum_root);
 	if (location->objectid == BTRFS_QUOTA_TREE_OBJECTID)
-		return btrfs_grab_fs_root(fs_info->quota_root) ?
+		return btrfs_grab_root(fs_info->quota_root) ?
 			fs_info->quota_root : ERR_PTR(-ENOENT);
 	if (location->objectid == BTRFS_UUID_TREE_OBJECTID)
-		return btrfs_grab_fs_root(fs_info->uuid_root) ?
+		return btrfs_grab_root(fs_info->uuid_root) ?
 			fs_info->uuid_root : ERR_PTR(-ENOENT);
 	if (location->objectid == BTRFS_FREE_SPACE_TREE_OBJECTID)
-		return btrfs_grab_fs_root(fs_info->free_space_root) ?
+		return btrfs_grab_root(fs_info->free_space_root) ?
 			fs_info->free_space_root : ERR_PTR(-ENOENT);
 again:
 	root = btrfs_lookup_fs_root(fs_info, location->objectid);
 	if (root) {
 		if (check_ref && btrfs_root_refs(&root->root_item) == 0) {
-			btrfs_put_fs_root(root);
+			btrfs_put_root(root);
 			return ERR_PTR(-ENOENT);
 		}
 		return root;
@@ -1657,10 +1657,10 @@ struct btrfs_root *btrfs_get_fs_root(struct btrfs_fs_info *fs_info,
 	 * we have the third for returning it, and the caller will put it when
 	 * it's done with the root.
 	 */
-	btrfs_grab_fs_root(root);
+	btrfs_grab_root(root);
 	ret = btrfs_insert_fs_root(fs_info, root);
 	if (ret) {
-		btrfs_put_fs_root(root);
+		btrfs_put_root(root);
 		if (ret == -EEXIST) {
 			btrfs_free_fs_root(root);
 			goto again;
@@ -2062,7 +2062,7 @@ void btrfs_free_fs_roots(struct btrfs_fs_info *fs_info)
 		} else {
 			free_extent_buffer(gang[0]->node);
 			free_extent_buffer(gang[0]->commit_root);
-			btrfs_put_fs_root(gang[0]);
+			btrfs_put_root(gang[0]);
 		}
 	}
 
@@ -2270,12 +2270,12 @@ static int btrfs_replay_log(struct btrfs_fs_info *fs_info,
 	if (IS_ERR(log_tree_root->node)) {
 		btrfs_warn(fs_info, "failed to read log tree");
 		ret = PTR_ERR(log_tree_root->node);
-		btrfs_put_fs_root(log_tree_root);
+		btrfs_put_root(log_tree_root);
 		return ret;
 	} else if (!extent_buffer_uptodate(log_tree_root->node)) {
 		btrfs_err(fs_info, "failed to read log tree");
 		free_extent_buffer(log_tree_root->node);
-		btrfs_put_fs_root(log_tree_root);
+		btrfs_put_root(log_tree_root);
 		return -EIO;
 	}
 	/* returns with log_tree_root freed on success */
@@ -2284,7 +2284,7 @@ static int btrfs_replay_log(struct btrfs_fs_info *fs_info,
 		btrfs_handle_fs_error(fs_info, ret,
 				      "Failed to recover log tree");
 		free_extent_buffer(log_tree_root->node);
-		btrfs_put_fs_root(log_tree_root);
+		btrfs_put_root(log_tree_root);
 		return ret;
 	}
 
@@ -3882,7 +3882,7 @@ void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info,
 	radix_tree_delete(&fs_info->fs_roots_radix,
 			  (unsigned long)root->root_key.objectid);
 	if (test_and_clear_bit(BTRFS_ROOT_IN_RADIX, &root->state))
-		btrfs_put_fs_root(root);
+		btrfs_put_root(root);
 	spin_unlock(&fs_info->fs_roots_radix_lock);
 
 	if (btrfs_root_refs(&root->root_item) == 0)
@@ -3893,7 +3893,7 @@ void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info,
 		if (root->reloc_root) {
 			free_extent_buffer(root->reloc_root->node);
 			free_extent_buffer(root->reloc_root->commit_root);
-			btrfs_put_fs_root(root->reloc_root);
+			btrfs_put_root(root->reloc_root);
 			root->reloc_root = NULL;
 		}
 	}
@@ -3917,7 +3917,7 @@ void btrfs_free_fs_root(struct btrfs_root *root)
 	free_extent_buffer(root->commit_root);
 	kfree(root->free_ino_ctl);
 	kfree(root->free_ino_pinned);
-	btrfs_put_fs_root(root);
+	btrfs_put_root(root);
 }
 
 int btrfs_cleanup_fs_roots(struct btrfs_fs_info *fs_info)
@@ -3947,7 +3947,7 @@ int btrfs_cleanup_fs_roots(struct btrfs_fs_info *fs_info)
 				continue;
 			}
 			/* grab all the search result for later use */
-			gang[i] = btrfs_grab_fs_root(gang[i]);
+			gang[i] = btrfs_grab_root(gang[i]);
 		}
 		srcu_read_unlock(&fs_info->subvol_srcu, index);
 
@@ -3958,7 +3958,7 @@ int btrfs_cleanup_fs_roots(struct btrfs_fs_info *fs_info)
 			err = btrfs_orphan_cleanup(gang[i]);
 			if (err)
 				break;
-			btrfs_put_fs_root(gang[i]);
+			btrfs_put_root(gang[i]);
 		}
 		root_objectid++;
 	}
@@ -3966,7 +3966,7 @@ int btrfs_cleanup_fs_roots(struct btrfs_fs_info *fs_info)
 	/* release the uncleaned roots due to error */
 	for (; i < ret; i++) {
 		if (gang[i])
-			btrfs_put_fs_root(gang[i]);
+			btrfs_put_root(gang[i]);
 	}
 	return err;
 }
@@ -4358,12 +4358,12 @@ static void btrfs_destroy_all_delalloc_inodes(struct btrfs_fs_info *fs_info)
 	while (!list_empty(&splice)) {
 		root = list_first_entry(&splice, struct btrfs_root,
 					 delalloc_root);
-		root = btrfs_grab_fs_root(root);
+		root = btrfs_grab_root(root);
 		BUG_ON(!root);
 		spin_unlock(&fs_info->delalloc_root_lock);
 
 		btrfs_destroy_delalloc_inodes(root);
-		btrfs_put_fs_root(root);
+		btrfs_put_root(root);
 
 		spin_lock(&fs_info->delalloc_root_lock);
 	}
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
index 04a29f961527..db21ab614357 100644
--- a/fs/btrfs/disk-io.h
+++ b/fs/btrfs/disk-io.h
@@ -89,7 +89,7 @@ struct btrfs_root *btrfs_alloc_dummy_root(struct btrfs_fs_info *fs_info);
  * If you want to ensure the whole tree is safe, you should use
  * 	fs_info->subvol_srcu
  */
-static inline struct btrfs_root *btrfs_grab_fs_root(struct btrfs_root *root)
+static inline struct btrfs_root *btrfs_grab_root(struct btrfs_root *root)
 {
 	if (!root)
 		return NULL;
@@ -98,7 +98,7 @@ static inline struct btrfs_root *btrfs_grab_fs_root(struct btrfs_root *root)
 	return NULL;
 }
 
-static inline void btrfs_put_fs_root(struct btrfs_root *root)
+static inline void btrfs_put_root(struct btrfs_root *root)
 {
 	if (!root)
 		return;
diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c
index f07c2300ade2..657fd6ad6e18 100644
--- a/fs/btrfs/export.c
+++ b/fs/btrfs/export.c
@@ -88,7 +88,7 @@ static struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid,
 	key.offset = 0;
 
 	inode = btrfs_iget(sb, &key, root);
-	btrfs_put_fs_root(root);
+	btrfs_put_root(root);
 	if (IS_ERR(inode)) {
 		err = PTR_ERR(inode);
 		goto fail;
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 0163fdd59f8f..c43acb329fa6 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -5416,7 +5416,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
 	} else {
 		free_extent_buffer(root->node);
 		free_extent_buffer(root->commit_root);
-		btrfs_put_fs_root(root);
+		btrfs_put_root(root);
 	}
 	root_dropped = true;
 out_end_trans:
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 682f21ee6034..8f44cbea6255 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -297,7 +297,7 @@ static int __btrfs_run_defrag_inode(struct btrfs_fs_info *fs_info,
 	key.type = BTRFS_INODE_ITEM_KEY;
 	key.offset = 0;
 	inode = btrfs_iget(fs_info->sb, &key, inode_root);
-	btrfs_put_fs_root(inode_root);
+	btrfs_put_root(inode_root);
 	if (IS_ERR(inode)) {
 		ret = PTR_ERR(inode);
 		goto cleanup;
diff --git a/fs/btrfs/free-space-tree.c b/fs/btrfs/free-space-tree.c
index c79804c30b17..bc43950eb32f 100644
--- a/fs/btrfs/free-space-tree.c
+++ b/fs/btrfs/free-space-tree.c
@@ -1253,7 +1253,7 @@ int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info)
 
 	free_extent_buffer(free_space_root->node);
 	free_extent_buffer(free_space_root->commit_root);
-	btrfs_put_fs_root(free_space_root);
+	btrfs_put_root(free_space_root);
 
 	return btrfs_commit_transaction(trans);
 
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index c01dc2790a40..cbbe72d0600b 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -5269,7 +5269,7 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)
 		inode = btrfs_iget(dir->i_sb, &location, sub_root);
 	}
 	if (root != sub_root)
-		btrfs_put_fs_root(sub_root);
+		btrfs_put_root(sub_root);
 	srcu_read_unlock(&fs_info->subvol_srcu, index);
 
 	if (!IS_ERR(inode) && root != sub_root) {
@@ -9588,14 +9588,14 @@ int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, int nr)
 	while (!list_empty(&splice) && nr) {
 		root = list_first_entry(&splice, struct btrfs_root,
 					delalloc_root);
-		root = btrfs_grab_fs_root(root);
+		root = btrfs_grab_root(root);
 		BUG_ON(!root);
 		list_move_tail(&root->delalloc_root,
 			       &fs_info->delalloc_roots);
 		spin_unlock(&fs_info->delalloc_root_lock);
 
 		ret = start_delalloc_inodes(root, nr, false);
-		btrfs_put_fs_root(root);
+		btrfs_put_root(root);
 		if (ret < 0)
 			goto out;
 
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 20861cabe6a1..ef6c5d672860 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -676,7 +676,7 @@ static noinline int create_subvol(struct inode *dir,
 	btrfs_record_root_in_trans(trans, new_root);
 
 	ret = btrfs_create_subvol_root(trans, new_root, root, new_dirid);
-	btrfs_put_fs_root(new_root);
+	btrfs_put_root(new_root);
 	if (ret) {
 		/* We potentially lose an unused inode item here */
 		btrfs_abort_transaction(trans, ret);
@@ -870,7 +870,7 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
 	d_instantiate(dentry, inode);
 	ret = 0;
 fail:
-	btrfs_put_fs_root(pending_snapshot->snap);
+	btrfs_put_root(pending_snapshot->snap);
 	btrfs_subvolume_release_metadata(fs_info, &pending_snapshot->block_rsv);
 dec_and_free:
 	if (snapshot_force_cow)
@@ -2176,7 +2176,7 @@ static noinline int search_ioctl(struct inode *inode,
 
 	if (sk->tree_id == 0) {
 		/* search the root of the inode that was passed */
-		root = btrfs_grab_fs_root(BTRFS_I(inode)->root);
+		root = btrfs_grab_root(BTRFS_I(inode)->root);
 	} else {
 		key.objectid = sk->tree_id;
 		key.type = BTRFS_ROOT_ITEM_KEY;
@@ -2210,7 +2210,7 @@ static noinline int search_ioctl(struct inode *inode,
 		ret = 0;
 err:
 	sk->nr_items = num_found;
-	btrfs_put_fs_root(root);
+	btrfs_put_root(root);
 	btrfs_free_path(path);
 	return ret;
 }
@@ -2372,7 +2372,7 @@ static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info,
 	ret = 0;
 out:
 	if (root)
-		btrfs_put_fs_root(root);
+		btrfs_put_root(root);
 	btrfs_free_path(path);
 	return ret;
 }
@@ -2500,7 +2500,7 @@ static int btrfs_search_path_in_tree_user(struct inode *inode,
 
 		memmove(args->path, ptr, total_len);
 		args->path[total_len] = '\0';
-		btrfs_put_fs_root(root);
+		btrfs_put_root(root);
 		btrfs_release_path(path);
 	}
 
@@ -2540,7 +2540,7 @@ static int btrfs_search_path_in_tree_user(struct inode *inode,
 	btrfs_free_path(path);
 	return ret;
 out_put:
-	btrfs_put_fs_root(root);
+	btrfs_put_root(root);
 	goto out;
 }
 
@@ -2743,7 +2743,7 @@ static int btrfs_ioctl_get_subvol_info(struct file *file, void __user *argp)
 		ret = -EFAULT;
 
 out:
-	btrfs_put_fs_root(root);
+	btrfs_put_root(root);
 out_free:
 	btrfs_free_path(path);
 	kzfree(subvol_info);
@@ -4035,7 +4035,7 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp)
 	btrfs_set_fs_incompat(fs_info, DEFAULT_SUBVOL);
 	btrfs_end_transaction(trans);
 out_free:
-	btrfs_put_fs_root(new_root);
+	btrfs_put_root(new_root);
 	btrfs_free_path(path);
 out:
 	mnt_drop_write_file(file);
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index ecb9fb6a6fe0..64281247bd18 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -580,7 +580,7 @@ void btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, u64 nr,
 	while (!list_empty(&splice) && nr) {
 		root = list_first_entry(&splice, struct btrfs_root,
 					ordered_root);
-		root = btrfs_grab_fs_root(root);
+		root = btrfs_grab_root(root);
 		BUG_ON(!root);
 		list_move_tail(&root->ordered_root,
 			       &fs_info->ordered_roots);
@@ -588,7 +588,7 @@ void btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, u64 nr,
 
 		done = btrfs_wait_ordered_extents(root, nr,
 						  range_start, range_len);
-		btrfs_put_fs_root(root);
+		btrfs_put_root(root);
 
 		spin_lock(&fs_info->ordered_root_lock);
 		if (nr != U64_MAX) {
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 0845e56a1672..6ae868eb9a17 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -1040,7 +1040,7 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info)
 	if (ret) {
 		free_extent_buffer(quota_root->node);
 		free_extent_buffer(quota_root->commit_root);
-		btrfs_put_fs_root(quota_root);
+		btrfs_put_root(quota_root);
 	}
 out:
 	if (ret) {
@@ -1106,7 +1106,7 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info)
 
 	free_extent_buffer(quota_root->node);
 	free_extent_buffer(quota_root->commit_root);
-	btrfs_put_fs_root(quota_root);
+	btrfs_put_root(quota_root);
 
 end_trans:
 	ret = btrfs_end_transaction(trans);
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index c08aeb83a8f7..fe5984c6c5d0 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -257,7 +257,7 @@ static void free_backref_node(struct backref_cache *cache,
 	if (node) {
 		cache->nr_nodes--;
 		if (node->root)
-			btrfs_put_fs_root(node->root);
+			btrfs_put_root(node->root);
 		kfree(node);
 	}
 }
@@ -591,7 +591,7 @@ static struct btrfs_root *find_reloc_root(struct reloc_control *rc,
 		root = (struct btrfs_root *)node->data;
 	}
 	spin_unlock(&rc->reloc_root_tree.lock);
-	return btrfs_grab_fs_root(root);
+	return btrfs_grab_root(root);
 }
 
 static int is_cowonly_root(u64 root_objectid)
@@ -902,7 +902,7 @@ struct backref_node *build_backref_tree(struct reloc_control *rc,
 			ASSERT(btrfs_root_bytenr(&root->root_item) ==
 			       cur->bytenr);
 			if (should_ignore_root(root)) {
-				btrfs_put_fs_root(root);
+				btrfs_put_root(root);
 				list_add(&cur->list, &useless);
 			} else {
 				cur->root = root;
@@ -919,7 +919,7 @@ struct backref_node *build_backref_tree(struct reloc_control *rc,
 		ret = btrfs_search_slot(NULL, root, node_key, path2, 0, 0);
 		path2->lowest_level = 0;
 		if (ret < 0) {
-			btrfs_put_fs_root(root);
+			btrfs_put_root(root);
 			err = ret;
 			goto out;
 		}
@@ -935,7 +935,7 @@ struct backref_node *build_backref_tree(struct reloc_control *rc,
 				  root->root_key.objectid,
 				  node_key->objectid, node_key->type,
 				  node_key->offset);
-			btrfs_put_fs_root(root);
+			btrfs_put_root(root);
 			err = -ENOENT;
 			goto out;
 		}
@@ -948,7 +948,7 @@ struct backref_node *build_backref_tree(struct reloc_control *rc,
 				ASSERT(btrfs_root_bytenr(&root->root_item) ==
 				       lower->bytenr);
 				if (should_ignore_root(root)) {
-					btrfs_put_fs_root(root);
+					btrfs_put_root(root);
 					list_add(&lower->list, &useless);
 				} else {
 					lower->root = root;
@@ -958,7 +958,7 @@ struct backref_node *build_backref_tree(struct reloc_control *rc,
 
 			edge = alloc_backref_edge(cache);
 			if (!edge) {
-				btrfs_put_fs_root(root);
+				btrfs_put_root(root);
 				err = -ENOMEM;
 				goto out;
 			}
@@ -968,7 +968,7 @@ struct backref_node *build_backref_tree(struct reloc_control *rc,
 			if (!rb_node) {
 				upper = alloc_backref_node(cache);
 				if (!upper) {
-					btrfs_put_fs_root(root);
+					btrfs_put_root(root);
 					free_backref_edge(cache, edge);
 					err = -ENOMEM;
 					goto out;
@@ -1017,7 +1017,7 @@ struct backref_node *build_backref_tree(struct reloc_control *rc,
 			edge->node[UPPER] = upper;
 
 			if (rb_node) {
-				btrfs_put_fs_root(root);
+				btrfs_put_root(root);
 				break;
 			}
 			lower = upper;
@@ -1256,7 +1256,7 @@ static int clone_backref_node(struct btrfs_trans_handle *trans,
 	new_node->level = node->level;
 	new_node->lowest = node->lowest;
 	new_node->checked = 1;
-	new_node->root = btrfs_grab_fs_root(dest);
+	new_node->root = btrfs_grab_root(dest);
 	ASSERT(new_node->root);
 
 	if (!node->lowest) {
@@ -2225,7 +2225,7 @@ static void insert_dirty_subvol(struct btrfs_trans_handle *trans,
 	btrfs_update_reloc_root(trans, root);
 
 	if (list_empty(&root->reloc_dirty_list)) {
-		btrfs_grab_fs_root(root);
+		btrfs_grab_root(root);
 		list_add_tail(&root->reloc_dirty_list, &rc->dirty_subvol_roots);
 	}
 }
@@ -2257,7 +2257,7 @@ static int clean_dirty_subvols(struct reloc_control *rc)
 			 */
 			smp_wmb();
 			clear_bit(BTRFS_ROOT_DEAD_RELOC_TREE, &root->state);
-			btrfs_put_fs_root(root);
+			btrfs_put_root(root);
 		} else {
 			/* Orphan reloc tree, just clean it up */
 			ret2 = btrfs_drop_snapshot(root, NULL, 0, 1);
@@ -2482,7 +2482,7 @@ int prepare_to_merge(struct reloc_control *rc, int err)
 		btrfs_update_reloc_root(trans, root);
 
 		list_add(&reloc_root->root_list, &reloc_roots);
-		btrfs_put_fs_root(root);
+		btrfs_put_root(root);
 	}
 
 	list_splice(&reloc_roots, &rc->reloc_roots);
@@ -2544,7 +2544,7 @@ void merge_reloc_roots(struct reloc_control *rc)
 			BUG_ON(root->reloc_root != reloc_root);
 
 			ret = merge_reloc_root(rc, root);
-			btrfs_put_fs_root(root);
+			btrfs_put_root(root);
 			if (ret) {
 				if (list_empty(&reloc_root->root_list))
 					list_add_tail(&reloc_root->root_list,
@@ -2605,7 +2605,7 @@ static int record_reloc_root_in_trans(struct btrfs_trans_handle *trans,
 	BUG_ON(IS_ERR(root));
 	BUG_ON(root->reloc_root != reloc_root);
 	ret = btrfs_record_root_in_trans(trans, root);
-	btrfs_put_fs_root(root);
+	btrfs_put_root(root);
 
 	return ret;
 }
@@ -2640,8 +2640,8 @@ struct btrfs_root *select_reloc_root(struct btrfs_trans_handle *trans,
 			BUG_ON(next->new_bytenr);
 			BUG_ON(!list_empty(&next->list));
 			next->new_bytenr = root->node->start;
-			btrfs_put_fs_root(next->root);
-			next->root = btrfs_grab_fs_root(root);
+			btrfs_put_root(next->root);
+			next->root = btrfs_grab_root(root);
 			ASSERT(next->root);
 			list_add_tail(&next->list,
 				      &rc->backref_cache.changed);
@@ -3114,8 +3114,8 @@ static int relocate_tree_block(struct btrfs_trans_handle *trans,
 			btrfs_record_root_in_trans(trans, root);
 			root = root->reloc_root;
 			node->new_bytenr = root->node->start;
-			btrfs_put_fs_root(node->root);
-			node->root = btrfs_grab_fs_root(root);
+			btrfs_put_root(node->root);
+			node->root = btrfs_grab_root(root);
 			ASSERT(node->root);
 			list_add_tail(&node->list, &rc->backref_cache.changed);
 		} else {
@@ -3811,7 +3811,7 @@ static int find_data_references(struct reloc_control *rc,
 
 	}
 out:
-	btrfs_put_fs_root(root);
+	btrfs_put_root(root);
 out_free:
 	btrfs_free_path(path);
 	return err;
@@ -4297,7 +4297,7 @@ struct inode *create_reloc_inode(struct btrfs_fs_info *fs_info,
 
 	trans = btrfs_start_transaction(root, 6);
 	if (IS_ERR(trans)) {
-		btrfs_put_fs_root(root);
+		btrfs_put_root(root);
 		return ERR_CAST(trans);
 	}
 
@@ -4317,7 +4317,7 @@ struct inode *create_reloc_inode(struct btrfs_fs_info *fs_info,
 
 	err = btrfs_orphan_add(trans, BTRFS_I(inode));
 out:
-	btrfs_put_fs_root(root);
+	btrfs_put_root(root);
 	btrfs_end_transaction(trans);
 	btrfs_btree_balance_dirty(fs_info);
 	if (err) {
@@ -4589,7 +4589,7 @@ int btrfs_recover_relocation(struct btrfs_root *root)
 					goto out;
 				}
 			} else {
-				btrfs_put_fs_root(fs_root);
+				btrfs_put_root(fs_root);
 			}
 		}
 
@@ -4643,7 +4643,7 @@ int btrfs_recover_relocation(struct btrfs_root *root)
 		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);
+		btrfs_put_root(fs_root);
 	}
 
 	err = btrfs_commit_transaction(trans);
@@ -4679,7 +4679,7 @@ int btrfs_recover_relocation(struct btrfs_root *root)
 			err = PTR_ERR(fs_root);
 		} else {
 			err = btrfs_orphan_cleanup(fs_root);
-			btrfs_put_fs_root(fs_root);
+			btrfs_put_root(fs_root);
 		}
 	}
 	return err;
diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c
index fca8334cb34d..f2a59ec6c1ce 100644
--- a/fs/btrfs/root-tree.c
+++ b/fs/btrfs/root-tree.c
@@ -288,7 +288,7 @@ int btrfs_find_orphan_roots(struct btrfs_fs_info *fs_info)
 			set_bit(BTRFS_ROOT_DEAD_TREE, &root->state);
 			btrfs_add_dead_root(root);
 		}
-		btrfs_put_fs_root(root);
+		btrfs_put_root(root);
 	}
 
 	btrfs_free_path(path);
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index 4f21f0b04a17..cf35bb2e9401 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -668,7 +668,7 @@ static int scrub_print_warning_inode(u64 inum, u64 offset, u64 root,
 
 	ret = btrfs_search_slot(NULL, local_root, &key, swarn->path, 0, 0);
 	if (ret) {
-		btrfs_put_fs_root(local_root);
+		btrfs_put_root(local_root);
 		btrfs_release_path(swarn->path);
 		goto err;
 	}
@@ -689,7 +689,7 @@ static int scrub_print_warning_inode(u64 inum, u64 offset, u64 root,
 	ipath = init_ipath(4096, local_root, swarn->path);
 	memalloc_nofs_restore(nofs_flag);
 	if (IS_ERR(ipath)) {
-		btrfs_put_fs_root(local_root);
+		btrfs_put_root(local_root);
 		ret = PTR_ERR(ipath);
 		ipath = NULL;
 		goto err;
@@ -713,7 +713,7 @@ static int scrub_print_warning_inode(u64 inum, u64 offset, u64 root,
 				  min(isize - offset, (u64)PAGE_SIZE), nlink,
 				  (char *)(unsigned long)ipath->fspath->val[i]);
 
-	btrfs_put_fs_root(local_root);
+	btrfs_put_root(local_root);
 	free_ipath(ipath);
 	return 0;
 
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 5ef4c6f75ecd..95aa0d54abec 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -7205,7 +7205,7 @@ long btrfs_ioctl_send(struct file *mnt_file, struct btrfs_ioctl_send_args *arg)
 			    btrfs_root_dead(clone_root)) {
 				spin_unlock(&clone_root->root_item_lock);
 				srcu_read_unlock(&fs_info->subvol_srcu, index);
-				btrfs_put_fs_root(clone_root);
+				btrfs_put_root(clone_root);
 				ret = -EPERM;
 				goto out;
 			}
@@ -7213,7 +7213,7 @@ long btrfs_ioctl_send(struct file *mnt_file, struct btrfs_ioctl_send_args *arg)
 				dedupe_in_progress_warn(clone_root);
 				spin_unlock(&clone_root->root_item_lock);
 				srcu_read_unlock(&fs_info->subvol_srcu, index);
-				btrfs_put_fs_root(clone_root);
+				btrfs_put_root(clone_root);
 				ret = -EAGAIN;
 				goto out;
 			}
@@ -7269,7 +7269,7 @@ long btrfs_ioctl_send(struct file *mnt_file, struct btrfs_ioctl_send_args *arg)
 	 * for possible clone sources.
 	 */
 	sctx->clone_roots[sctx->clone_roots_cnt++].root =
-		btrfs_grab_fs_root(sctx->send_root);
+		btrfs_grab_root(sctx->send_root);
 
 	/* We do a bsearch later */
 	sort(sctx->clone_roots, sctx->clone_roots_cnt,
@@ -7357,20 +7357,20 @@ long btrfs_ioctl_send(struct file *mnt_file, struct btrfs_ioctl_send_args *arg)
 		for (i = 0; i < sctx->clone_roots_cnt; i++) {
 			btrfs_root_dec_send_in_progress(
 					sctx->clone_roots[i].root);
-			btrfs_put_fs_root(sctx->clone_roots[i].root);
+			btrfs_put_root(sctx->clone_roots[i].root);
 		}
 	} else {
 		for (i = 0; sctx && i < clone_sources_to_rollback; i++) {
 			btrfs_root_dec_send_in_progress(
 					sctx->clone_roots[i].root);
-			btrfs_put_fs_root(sctx->clone_roots[i].root);
+			btrfs_put_root(sctx->clone_roots[i].root);
 		}
 
 		btrfs_root_dec_send_in_progress(send_root);
 	}
 	if (sctx && !IS_ERR_OR_NULL(sctx->parent_root)) {
 		btrfs_root_dec_send_in_progress(sctx->parent_root);
-		btrfs_put_fs_root(sctx->parent_root);
+		btrfs_put_root(sctx->parent_root);
 	}
 
 	kvfree(clone_sources_tmp);
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index cf8c49d06a77..d421884f0c23 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -1113,16 +1113,16 @@ static char *get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info,
 
 			ret = btrfs_search_slot(NULL, fs_root, &key, path, 0, 0);
 			if (ret < 0) {
-				btrfs_put_fs_root(fs_root);
+				btrfs_put_root(fs_root);
 				goto err;
 			} else if (ret > 0) {
 				ret = btrfs_previous_item(fs_root, path, dirid,
 							  BTRFS_INODE_REF_KEY);
 				if (ret < 0) {
-					btrfs_put_fs_root(fs_root);
+					btrfs_put_root(fs_root);
 					goto err;
 				} else if (ret > 0) {
-					btrfs_put_fs_root(fs_root);
+					btrfs_put_root(fs_root);
 					ret = -ENOENT;
 					goto err;
 				}
@@ -1139,7 +1139,7 @@ static char *get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info,
 			ptr -= len + 1;
 			if (ptr < name) {
 				ret = -ENAMETOOLONG;
-				btrfs_put_fs_root(fs_root);
+				btrfs_put_root(fs_root);
 				goto err;
 			}
 			read_extent_buffer(path->nodes[0], ptr + 1,
@@ -1147,7 +1147,7 @@ static char *get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info,
 			ptr[0] = '/';
 			btrfs_release_path(path);
 		}
-		btrfs_put_fs_root(fs_root);
+		btrfs_put_root(fs_root);
 	}
 
 	btrfs_free_path(path);
diff --git a/fs/btrfs/tests/btrfs-tests.c b/fs/btrfs/tests/btrfs-tests.c
index 609abca4fe3a..69c9afef06e3 100644
--- a/fs/btrfs/tests/btrfs-tests.c
+++ b/fs/btrfs/tests/btrfs-tests.c
@@ -209,7 +209,7 @@ void btrfs_free_dummy_root(struct btrfs_root *root)
 		/* One for allocate_extent_buffer */
 		free_extent_buffer(root->node);
 	}
-	btrfs_put_fs_root(root);
+	btrfs_put_root(root);
 }
 
 struct btrfs_block_group *
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index e7525689b1e8..e4e53d38cbc1 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -3284,7 +3284,7 @@ static void free_log_tree(struct btrfs_trans_handle *trans,
 	clear_extent_bits(&log->dirty_log_pages, 0, (u64)-1,
 			  EXTENT_DIRTY | EXTENT_NEW | EXTENT_NEED_WAIT);
 	free_extent_buffer(log->node);
-	btrfs_put_fs_root(log);
+	btrfs_put_root(log);
 }
 
 /*
@@ -6134,7 +6134,7 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
 							log->node->len);
 			free_extent_buffer(log->node);
 			free_extent_buffer(log->commit_root);
-			btrfs_put_fs_root(log);
+			btrfs_put_root(log);
 
 			if (!ret)
 				goto next;
@@ -6170,10 +6170,10 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
 		}
 
 		wc.replay_dest->log_root = NULL;
-		btrfs_put_fs_root(wc.replay_dest);
+		btrfs_put_root(wc.replay_dest);
 		free_extent_buffer(log->node);
 		free_extent_buffer(log->commit_root);
-		btrfs_put_fs_root(log);
+		btrfs_put_root(log);
 
 		if (ret)
 			goto error;
@@ -6207,7 +6207,7 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
 	free_extent_buffer(log_root_tree->node);
 	log_root_tree->log_root = NULL;
 	clear_bit(BTRFS_FS_LOG_RECOVERING, &fs_info->flags);
-	btrfs_put_fs_root(log_root_tree);
+	btrfs_put_root(log_root_tree);
 
 	return 0;
 error:
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 4a922b9f6e2c..c72fd33a9ce1 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -4394,7 +4394,7 @@ static int btrfs_check_uuid_tree_entry(struct btrfs_fs_info *fs_info,
 			ret = 1;
 		break;
 	}
-	btrfs_put_fs_root(subvol_root);
+	btrfs_put_root(subvol_root);
 out:
 	return ret;
 }
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* Re: [PATCH 36/44] btrfs: move free_fs_info
  2020-01-24 14:32 ` [PATCH 36/44] btrfs: move free_fs_info Josef Bacik
@ 2020-01-24 14:52   ` Nikolay Borisov
  0 siblings, 0 replies; 63+ messages in thread
From: Nikolay Borisov @ 2020-01-24 14:52 UTC (permalink / raw)
  To: Josef Bacik, kernel-team, linux-btrfs



On 24.01.20 г. 16:32 ч., Josef Bacik wrote:
> We're going to start freeing roots and doing other complicated things in
> free_fs_info, so we need to move it to disk-io.c and export it in order
> to use things lik btrfs_put_fs_root().
> 
> Signed-off-by: Josef Bacik <josef@toxicpanda.com>

Reviewed-by: Nikolay Borisov <nborisov@suse.com>

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 01/44] btrfs: push __setup_root into btrfs_alloc_root
  2020-01-24 14:32 ` [PATCH 01/44] btrfs: push __setup_root into btrfs_alloc_root Josef Bacik
@ 2020-02-04 22:05   ` David Sterba
  0 siblings, 0 replies; 63+ messages in thread
From: David Sterba @ 2020-02-04 22:05 UTC (permalink / raw)
  To: Josef Bacik; +Cc: kernel-team, linux-btrfs, Nikolay Borisov

On Fri, Jan 24, 2020 at 09:32:18AM -0500, Josef Bacik wrote:
> @@ -2645,8 +2639,10 @@ int __cold open_ctree(struct super_block *sb,
>  	int clear_free_space_tree = 0;
>  	int level;
>  
> -	tree_root = fs_info->tree_root = btrfs_alloc_root(fs_info, GFP_KERNEL);
> -	chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info, GFP_KERNEL);
> +	tree_root = fs_info->tree_root = btrfs_alloc_root(fs_info,
> +					BTRFS_ROOT_TREE_OBJECTID, GFP_KERNEL);
> +	chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info,
> +					BTRFS_CHUNK_TREE_OBJECTID, GFP_KERNEL);

Chaned assignments should be split to individual assignments when the code
is changed. Updated.

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 00/44][v5] Cleanup how we handle root refs, part 1
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (43 preceding siblings ...)
  2020-01-24 14:33 ` [PATCH 44/44] btrfs: rename btrfs_put_fs_root and btrfs_grab_fs_root Josef Bacik
@ 2020-02-04 23:48 ` David Sterba
  2020-02-05 15:48 ` David Sterba
  45 siblings, 0 replies; 63+ messages in thread
From: David Sterba @ 2020-02-04 23:48 UTC (permalink / raw)
  To: Josef Bacik; +Cc: kernel-team, linux-btrfs

On Fri, Jan 24, 2020 at 09:32:17AM -0500, Josef Bacik wrote:
> v4->v5:
> - split out the btrfs_free_fs_info() moving around into it's own patch.
> - updated a comment in btrfs_get_root() to describe why we are initializing part
>   of the fs_info

Patches 1-9 are preparatory and don't change the root ref logic so I'll
add them to misc-next now, the rest will follow.

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 17/44] btrfs: hold a ref on the root in btrfs_search_path_in_tree
  2020-01-24 14:32 ` [PATCH 17/44] btrfs: hold a ref on the root in btrfs_search_path_in_tree Josef Bacik
@ 2020-02-05 14:30   ` David Sterba
  0 siblings, 0 replies; 63+ messages in thread
From: David Sterba @ 2020-02-05 14:30 UTC (permalink / raw)
  To: Josef Bacik; +Cc: kernel-team, linux-btrfs

On Fri, Jan 24, 2020 at 09:32:34AM -0500, Josef Bacik wrote:
> We look up an arbitrary fs root, we need to hold a ref on it while we're
> doing our search.
> 
> Signed-off-by: Josef Bacik <josef@toxicpanda.com>
> ---
>  fs/btrfs/ioctl.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
> index 62dd06b65686..c721b4fce1c0 100644
> --- a/fs/btrfs/ioctl.c
> +++ b/fs/btrfs/ioctl.c
> @@ -2328,6 +2328,12 @@ static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info,
>  	root = btrfs_get_fs_root(info, &key, true);
>  	if (IS_ERR(root)) {
>  		ret = PTR_ERR(root);
> +		root = NULL;
> +		goto out;
> +	}
> +	if (!btrfs_grab_fs_root(root)) {
> +		ret = -ENOENT;
> +		root = NULL;
>  		goto out;
>  	}
>  
> @@ -2378,6 +2384,8 @@ static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info,
>  	name[total_len] = '\0';
>  	ret = 0;
>  out:
> +	if (root)
> +		btrfs_put_fs_root(root);

The NULL check is not necessary, you added that into btrfs_put_fs_root
and I think it's readable without it here.

>  	btrfs_free_path(path);
>  	return ret;
>  }
> -- 
> 2.24.1

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 18/44] btrfs: hold a ref on the root in btrfs_search_path_in_tree_user
  2020-01-24 14:32 ` [PATCH 18/44] btrfs: hold a ref on the root in btrfs_search_path_in_tree_user Josef Bacik
@ 2020-02-05 14:37   ` David Sterba
  0 siblings, 0 replies; 63+ messages in thread
From: David Sterba @ 2020-02-05 14:37 UTC (permalink / raw)
  To: Josef Bacik; +Cc: kernel-team, linux-btrfs

On Fri, Jan 24, 2020 at 09:32:35AM -0500, Josef Bacik wrote:
> We can wander into a different root, so grab a ref on the root we look
> up.  Later on we make root = fs_info->tree_root so we need this separate
> out label to make sure we do the right cleanup only in the case we're
> looking up a different root.
> 
> Signed-off-by: Josef Bacik <josef@toxicpanda.com>
> ---
>  fs/btrfs/ioctl.c | 28 ++++++++++++++++++----------
>  1 file changed, 18 insertions(+), 10 deletions(-)
> 
> diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
> index c721b4fce1c0..5fffa1b6f685 100644
> --- a/fs/btrfs/ioctl.c
> +++ b/fs/btrfs/ioctl.c
> @@ -2432,6 +2432,10 @@ static int btrfs_search_path_in_tree_user(struct inode *inode,
>  			ret = PTR_ERR(root);
>  			goto out;
>  		}
> +		if (!btrfs_grab_fs_root(root)) {
> +			ret = -ENOENT;
> +			goto out;
> +		}
>  
>  		key.objectid = dirid;
>  		key.type = BTRFS_INODE_REF_KEY;
> @@ -2439,15 +2443,15 @@ static int btrfs_search_path_in_tree_user(struct inode *inode,
>  		while (1) {
>  			ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
>  			if (ret < 0) {
> -				goto out;
> +				goto out_put;
>  			} else if (ret > 0) {
>  				ret = btrfs_previous_item(root, path, dirid,
>  							  BTRFS_INODE_REF_KEY);
>  				if (ret < 0) {
> -					goto out;
> +					goto out_put;
>  				} else if (ret > 0) {
>  					ret = -ENOENT;
> -					goto out;
> +					goto out_put;
>  				}
>  			}
>  
> @@ -2461,7 +2465,7 @@ static int btrfs_search_path_in_tree_user(struct inode *inode,
>  			total_len += len + 1;
>  			if (ptr < args->path) {
>  				ret = -ENAMETOOLONG;
> -				goto out;
> +				goto out_put;
>  			}
>  
>  			*(ptr + len) = '/';
> @@ -2472,10 +2476,10 @@ static int btrfs_search_path_in_tree_user(struct inode *inode,
>  			ret = btrfs_previous_item(root, path, dirid,
>  						  BTRFS_INODE_ITEM_KEY);
>  			if (ret < 0) {
> -				goto out;
> +				goto out_put;
>  			} else if (ret > 0) {
>  				ret = -ENOENT;
> -				goto out;
> +				goto out_put;
>  			}
>  
>  			leaf = path->nodes[0];
> @@ -2483,26 +2487,26 @@ static int btrfs_search_path_in_tree_user(struct inode *inode,
>  			btrfs_item_key_to_cpu(leaf, &key2, slot);
>  			if (key2.objectid != dirid) {
>  				ret = -ENOENT;
> -				goto out;
> +				goto out_put;
>  			}
>  
>  			temp_inode = btrfs_iget(sb, &key2, root);
>  			if (IS_ERR(temp_inode)) {
>  				ret = PTR_ERR(temp_inode);
> -				goto out;
> +				goto out_put;
>  			}
>  			ret = inode_permission(temp_inode, MAY_READ | MAY_EXEC);
>  			iput(temp_inode);
>  			if (ret) {
>  				ret = -EACCES;
> -				goto out;
> +				goto out_put;
>  			}
>  
>  			if (key.offset == upper_limit.objectid)
>  				break;
>  			if (key.objectid == BTRFS_FIRST_FREE_OBJECTID) {
>  				ret = -EACCES;
> -				goto out;
> +				goto out_put;
>  			}
>  
>  			btrfs_release_path(path);
> @@ -2513,6 +2517,7 @@ static int btrfs_search_path_in_tree_user(struct inode *inode,
>  
>  		memmove(args->path, ptr, total_len);
>  		args->path[total_len] = '\0';
> +		btrfs_put_fs_root(root);
>  		btrfs_release_path(path);
>  	}
>  
> @@ -2551,6 +2556,9 @@ static int btrfs_search_path_in_tree_user(struct inode *inode,
>  out:
>  	btrfs_free_path(path);
>  	return ret;
> +out_put:
> +	btrfs_put_fs_root(root);
> +	goto out;

That's the ugly goto pattern we'd rather not use

I see a simple way to merge the gotos to one: set root to NULL after the
proper btrfs_put_fs_root (next to the memmove call above), and do the
error btrfs_put_fs_root before free path.

There's one catch, 'root' is used to hold tree_root that's only passed
to search slot, but that can be simplified so 'root' is always the
referenced root.

Incremental diff:

---
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -2518,15 +2518,15 @@ static int btrfs_search_path_in_tree_user(struct inode *inode,
                memmove(args->path, ptr, total_len);
                args->path[total_len] = '\0';
                btrfs_put_fs_root(root);
+               root = NULL;
                btrfs_release_path(path);
        }
 
        /* Get the bottom subvolume's name from ROOT_REF */
-       root = fs_info->tree_root;
        key.objectid = treeid;
        key.type = BTRFS_ROOT_REF_KEY;
        key.offset = args->treeid;
-       ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
+       ret = btrfs_search_slot(NULL, fs_info->tree_root, &key, path, 0, 0);
        if (ret < 0) {
                goto out;
        } else if (ret > 0) {
@@ -2553,12 +2553,11 @@ static int btrfs_search_path_in_tree_user(struct inode *inode,
        read_extent_buffer(leaf, args->name, item_off, item_len);
        args->name[item_len] = 0;
 
+out_put:
+       btrfs_put_fs_root(root);
 out:
        btrfs_free_path(path);
        return ret;
-out_put:
-       btrfs_put_fs_root(root);
-       goto out;
 }
---

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 21/44] btrfs: hold a ref on the root in build_backref_tree
  2020-01-24 14:32 ` [PATCH 21/44] btrfs: hold a ref on the root in build_backref_tree Josef Bacik
@ 2020-02-05 14:46   ` David Sterba
  0 siblings, 0 replies; 63+ messages in thread
From: David Sterba @ 2020-02-05 14:46 UTC (permalink / raw)
  To: Josef Bacik; +Cc: kernel-team, linux-btrfs

On Fri, Jan 24, 2020 at 09:32:38AM -0500, Josef Bacik wrote:
> This is trickier than the previous conversions.  We have backref_node's
> that need to hold onto their root for their lifetime.  Do the read of
> the root and grab the ref.  If at any point we don't use the root we
> discard it, however if we use it in our backref node we don't free it
> until we free the backref node.  Any time we switch the root's for the
> backref node we need to drop our ref on the old root and grab the ref on
> the new root, and if we dupe a node we need to get a ref on the root
> there as well.
> 
> Signed-off-by: Josef Bacik <josef@toxicpanda.com>
> ---
>  fs/btrfs/relocation.c | 39 ++++++++++++++++++++++++++++++---------
>  1 file changed, 30 insertions(+), 9 deletions(-)
> 
> diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
> index aa3aa8e0c0ea..990595a27a15 100644
> --- a/fs/btrfs/relocation.c
> +++ b/fs/btrfs/relocation.c
> @@ -256,6 +256,8 @@ static void free_backref_node(struct backref_cache *cache,
>  {
>  	if (node) {
>  		cache->nr_nodes--;
> +		if (node->root)
> +			btrfs_put_fs_root(node->root);

And here the check can be dropped too, to be consistent with the rest.

>  		kfree(node);
>  	}
>  }

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 22/44] btrfs: hold a ref on the root in prepare_to_merge
  2020-01-24 14:32 ` [PATCH 22/44] btrfs: hold a ref on the root in prepare_to_merge Josef Bacik
@ 2020-02-05 14:52   ` David Sterba
  0 siblings, 0 replies; 63+ messages in thread
From: David Sterba @ 2020-02-05 14:52 UTC (permalink / raw)
  To: Josef Bacik; +Cc: kernel-team, linux-btrfs

On Fri, Jan 24, 2020 at 09:32:39AM -0500, Josef Bacik wrote:
> We look up the reloc roots corresponding root, we need to hold a ref on
> that root.
> 
> Signed-off-by: Josef Bacik <josef@toxicpanda.com>
> ---
>  fs/btrfs/relocation.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
> index 990595a27a15..53df57b59bc3 100644
> --- a/fs/btrfs/relocation.c
> +++ b/fs/btrfs/relocation.c
> @@ -2474,6 +2474,8 @@ int prepare_to_merge(struct reloc_control *rc, int err)
>  		list_del_init(&reloc_root->root_list);
>  
>  		root = read_fs_root(fs_info, reloc_root->root_key.offset);
> +		if (!btrfs_grab_fs_root(root))
> +			BUG();
>  		BUG_ON(IS_ERR(root));

These two should be swapped, first the root is "checked" if it's
valid, then the reference can be grabbed. The code is later pushed into
the other helper and there it's in the right order so it's only
temporary.

>  		BUG_ON(root->reloc_root != reloc_root);
>  

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 27/44] btrfs: hold a ref on the root in btrfs_recover_relocation
  2020-01-24 14:32 ` [PATCH 27/44] btrfs: hold a ref on the root in btrfs_recover_relocation Josef Bacik
@ 2020-02-05 15:00   ` David Sterba
  2020-02-06 16:26   ` David Sterba
  1 sibling, 0 replies; 63+ messages in thread
From: David Sterba @ 2020-02-05 15:00 UTC (permalink / raw)
  To: Josef Bacik; +Cc: kernel-team, linux-btrfs

On Fri, Jan 24, 2020 at 09:32:44AM -0500, Josef Bacik wrote:
> 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>
> ---
>  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 9531739b5a8c..81f383df8f63 100644
> --- a/fs/btrfs/relocation.c
> +++ b/fs/btrfs/relocation.c
> @@ -4593,6 +4593,10 @@ int btrfs_recover_relocation(struct btrfs_root *root)
>  		if (btrfs_root_refs(&reloc_root->root_item) > 0) {
>  			fs_root = read_fs_root(fs_info,
>  					       reloc_root->root_key.offset);
> +			if (!btrfs_grab_fs_root(fs_root)) {
> +				err = -ENOENT;
> +				goto out;
> +			}
>  			if (IS_ERR(fs_root)) {

Also in the wrong order.

>  				ret = PTR_ERR(fs_root);
>  				if (ret != -ENOENT) {

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 29/44] btrfs: hold a ref for the root in btrfs_find_orphan_roots
  2020-01-24 14:32 ` [PATCH 29/44] btrfs: hold a ref for the root in btrfs_find_orphan_roots Josef Bacik
@ 2020-02-05 15:06   ` David Sterba
  0 siblings, 0 replies; 63+ messages in thread
From: David Sterba @ 2020-02-05 15:06 UTC (permalink / raw)
  To: Josef Bacik; +Cc: kernel-team, linux-btrfs

On Fri, Jan 24, 2020 at 09:32:46AM -0500, Josef Bacik wrote:
> We lookup roots for every orphan item we have, we need to hold a ref on
> the root while we're doing this work.
> 
> Signed-off-by: Josef Bacik <josef@toxicpanda.com>
> ---
>  fs/btrfs/root-tree.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c
> index 094a71c54fa1..25842527fd42 100644
> --- a/fs/btrfs/root-tree.c
> +++ b/fs/btrfs/root-tree.c
> @@ -257,6 +257,8 @@ int btrfs_find_orphan_roots(struct btrfs_fs_info *fs_info)
>  
>  		root = btrfs_get_fs_root(fs_info, &root_key, false);
>  		err = PTR_ERR_OR_ZERO(root);
> +		if (!err && !btrfs_grab_fs_root(root))
> +			err = -ENOENT;
>  		if (err && err != -ENOENT) {
>  			break;
>  		} else if (err == -ENOENT) {

It's hard to read and reason about where's the reference and where it's
not due to the combined options. There are some breaks and continues and
I think some refs might leak. I'll have another thought how it could be
restructured.

> @@ -288,6 +290,7 @@ int btrfs_find_orphan_roots(struct btrfs_fs_info *fs_info)
>  			set_bit(BTRFS_ROOT_DEAD_TREE, &root->state);
>  			btrfs_add_dead_root(root);
>  		}
> +		btrfs_put_fs_root(root);
>  	}
>  
>  	btrfs_free_path(path);
> -- 
> 2.24.1

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 31/44] btrfs: hold a ref on the root in btrfs_ioctl_send
  2020-01-24 14:32 ` [PATCH 31/44] btrfs: hold a ref on the root in btrfs_ioctl_send Josef Bacik
@ 2020-02-05 15:16   ` David Sterba
  0 siblings, 0 replies; 63+ messages in thread
From: David Sterba @ 2020-02-05 15:16 UTC (permalink / raw)
  To: Josef Bacik; +Cc: kernel-team, linux-btrfs

On Fri, Jan 24, 2020 at 09:32:48AM -0500, Josef Bacik wrote:
> --- a/fs/btrfs/send.c
> +++ b/fs/btrfs/send.c
> @@ -7200,11 +7200,17 @@ long btrfs_ioctl_send(struct file *mnt_file, struct btrfs_ioctl_send_args *arg)
>  				ret = PTR_ERR(clone_root);
>  				goto out;
>  			}
> +			if (!btrfs_grab_fs_root(clone_root)) {
> +				srcu_read_unlock(&fs_info->subvol_srcu, index);
> +				ret = -ENOENT;
> +				goto out;
> +			}
>  			spin_lock(&clone_root->root_item_lock);
>  			if (!btrfs_root_readonly(clone_root) ||
>  			    btrfs_root_dead(clone_root)) {
>  				spin_unlock(&clone_root->root_item_lock);
>  				srcu_read_unlock(&fs_info->subvol_srcu, index);
> +				btrfs_put_fs_root(clone_root);

Here and

>  				ret = -EPERM;
>  				goto out;
>  			}
> @@ -7212,6 +7218,7 @@ long btrfs_ioctl_send(struct file *mnt_file, struct btrfs_ioctl_send_args *arg)
>  				dedupe_in_progress_warn(clone_root);
>  				spin_unlock(&clone_root->root_item_lock);
>  				srcu_read_unlock(&fs_info->subvol_srcu, index);
> +				btrfs_put_fs_root(clone_root);

here, the order is srcu, put ref. As it's on error handling path anyway
it's no big deal, but I'd rather swap them so the nesting is proper,
tree refs inside srcu section.

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 32/44] btrfs: hold a ref on the root in get_subvol_name_from_objectid
  2020-01-24 14:32 ` [PATCH 32/44] btrfs: hold a ref on the root in get_subvol_name_from_objectid Josef Bacik
@ 2020-02-05 15:19   ` David Sterba
  2020-02-06 15:24     ` [PATCH][v2] " Josef Bacik
  0 siblings, 1 reply; 63+ messages in thread
From: David Sterba @ 2020-02-05 15:19 UTC (permalink / raw)
  To: Josef Bacik; +Cc: kernel-team, linux-btrfs

On Fri, Jan 24, 2020 at 09:32:49AM -0500, Josef Bacik wrote:
> We lookup the name of a subvol which means we'll cross into different
> roots.  Hold a ref while we're doing the look ups in the fs_root we're
> searching.
> 
> Signed-off-by: Josef Bacik <josef@toxicpanda.com>
> ---
>  fs/btrfs/super.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
> index 3118bc01321e..5c3a1b7de6ee 100644
> --- a/fs/btrfs/super.c
> +++ b/fs/btrfs/super.c
> @@ -1101,6 +1101,10 @@ static char *get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info,
>  			ret = PTR_ERR(fs_root);
>  			goto err;
>  		}
> +		if (!btrfs_grab_fs_root(fs_root)) {
> +			ret = -ENOENT;
> +			goto err;
> +		}
>  
>  		/*
>  		 * Walk up the filesystem tree by inode refs until we hit the
> @@ -1113,13 +1117,16 @@ static char *get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info,
>  
>  			ret = btrfs_search_slot(NULL, fs_root, &key, path, 0, 0);
>  			if (ret < 0) {
> +				btrfs_put_fs_root(fs_root);
>  				goto err;
>  			} else if (ret > 0) {
>  				ret = btrfs_previous_item(fs_root, path, dirid,
>  							  BTRFS_INODE_REF_KEY);
>  				if (ret < 0) {
> +					btrfs_put_fs_root(fs_root);
>  					goto err;
>  				} else if (ret > 0) {
> +					btrfs_put_fs_root(fs_root);
>  					ret = -ENOENT;
>  					goto err;
>  				}
> @@ -1136,6 +1143,7 @@ static char *get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info,
>  			ptr -= len + 1;
>  			if (ptr < name) {
>  				ret = -ENAMETOOLONG;
> +				btrfs_put_fs_root(fs_root);
>  				goto err;
>  			}
>  			read_extent_buffer(path->nodes[0], ptr + 1,
> @@ -1143,6 +1151,7 @@ static char *get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info,
>  			ptr[0] = '/';
>  			btrfs_release_path(path);
>  		}
> +		btrfs_put_fs_root(fs_root);
>  	}
>  
>  	btrfs_free_path(path);

All the put_fs_root before goto err can and should be merged into the
exit block that's already there.

> -- 
> 2.24.1

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 44/44] btrfs: rename btrfs_put_fs_root and btrfs_grab_fs_root
  2020-01-24 14:33 ` [PATCH 44/44] btrfs: rename btrfs_put_fs_root and btrfs_grab_fs_root Josef Bacik
@ 2020-02-05 15:44   ` David Sterba
  0 siblings, 0 replies; 63+ messages in thread
From: David Sterba @ 2020-02-05 15:44 UTC (permalink / raw)
  To: Josef Bacik; +Cc: kernel-team, linux-btrfs, Nikolay Borisov

On Fri, Jan 24, 2020 at 09:33:01AM -0500, Josef Bacik wrote:
> We are now using these for all roots, rename them to btrfs_put_root()
> and btrfs_grab_root();

Regarding the naming, the usual pattern is get/put, while grab does not
necessarily have to pair with anything and is for special cases (like
igrab). btrfs_get_root is free so we can use it.

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 00/44][v5] Cleanup how we handle root refs, part 1
  2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
                   ` (44 preceding siblings ...)
  2020-02-04 23:48 ` [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 David Sterba
@ 2020-02-05 15:48 ` David Sterba
  2020-02-06 16:59   ` David Sterba
  45 siblings, 1 reply; 63+ messages in thread
From: David Sterba @ 2020-02-05 15:48 UTC (permalink / raw)
  To: Josef Bacik; +Cc: kernel-team, linux-btrfs

On Fri, Jan 24, 2020 at 09:32:17AM -0500, Josef Bacik wrote:
> v4->v5:
> - split out the btrfs_free_fs_info() moving around into it's own patch.
> - updated a comment in btrfs_get_root() to describe why we are initializing part
>   of the fs_info

I've commented under the patches, small things that I'd rather fixup
in my branch once you look at them, no need to resend anything.

As the code is split, some changes are removed so even if there's
something called in wrong order, it lasts only a few patches. For
clarity I'd still like to have committed patches that don't have such
things left.

^ permalink raw reply	[flat|nested] 63+ messages in thread

* [PATCH][v2] btrfs: hold a ref on the root in get_subvol_name_from_objectid
  2020-02-05 15:19   ` David Sterba
@ 2020-02-06 15:24     ` Josef Bacik
  0 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-02-06 15:24 UTC (permalink / raw)
  To: linux-btrfs, kernel-team, dsterba

We lookup the name of a subvol which means we'll cross into different
roots.  Hold a ref while we're doing the look ups in the fs_root we're
searching.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
v1->v2:
- Moved the btrfs_put_fs_root() to err, but this requires making sure that
  fs_root == NULL in all the cases we won't have a valid fs_root to drop a ref
  on.

 fs/btrfs/super.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index fa74caf39165..96bc10da5ff2 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -1028,7 +1028,7 @@ static char *get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info,
 					   u64 subvol_objectid)
 {
 	struct btrfs_root *root = fs_info->tree_root;
-	struct btrfs_root *fs_root;
+	struct btrfs_root *fs_root = NULL;
 	struct btrfs_root_ref *root_ref;
 	struct btrfs_inode_ref *inode_ref;
 	struct btrfs_key key;
@@ -1099,6 +1099,12 @@ static char *get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info,
 		fs_root = btrfs_get_fs_root(fs_info, &key, true);
 		if (IS_ERR(fs_root)) {
 			ret = PTR_ERR(fs_root);
+			fs_root = NULL;
+			goto err;
+		}
+		if (!btrfs_grab_fs_root(fs_root)) {
+			ret = -ENOENT;
+			fs_root = NULL;
 			goto err;
 		}
 
@@ -1143,6 +1149,8 @@ static char *get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info,
 			ptr[0] = '/';
 			btrfs_release_path(path);
 		}
+		btrfs_put_fs_root(fs_root);
+		fs_root = NULL;
 	}
 
 	btrfs_free_path(path);
@@ -1155,6 +1163,7 @@ static char *get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info,
 	return name;
 
 err:
+	btrfs_put_fs_root(fs_root);
 	btrfs_free_path(path);
 	kfree(name);
 	return ERR_PTR(ret);
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 63+ messages in thread

* Re: [PATCH 27/44] btrfs: hold a ref on the root in btrfs_recover_relocation
  2020-01-24 14:32 ` [PATCH 27/44] btrfs: hold a ref on the root in btrfs_recover_relocation Josef Bacik
  2020-02-05 15:00   ` David Sterba
@ 2020-02-06 16:26   ` David Sterba
  2020-02-06 16:30     ` Josef Bacik
  1 sibling, 1 reply; 63+ messages in thread
From: David Sterba @ 2020-02-06 16:26 UTC (permalink / raw)
  To: Josef Bacik; +Cc: kernel-team, linux-btrfs

On Fri, Jan 24, 2020 at 09:32:44AM -0500, Josef Bacik wrote:
> @@ -4593,6 +4593,10 @@ int btrfs_recover_relocation(struct btrfs_root *root)
>  		if (btrfs_root_refs(&reloc_root->root_item) > 0) {
>  			fs_root = read_fs_root(fs_info,
>  					       reloc_root->root_key.offset);
> +			if (!btrfs_grab_fs_root(fs_root)) {
> +				err = -ENOENT;
> +				goto out;
> +			}
>  			if (IS_ERR(fs_root)) {
>  				ret = PTR_ERR(fs_root);
>  				if (ret != -ENOENT) {
> @@ -4604,6 +4608,8 @@ int btrfs_recover_relocation(struct btrfs_root *root)
>  					err = ret;
>  					goto out;
>  				}
> +			} else {
> +				btrfs_put_fs_root(fs_root);
>  			}
>  		}

The order of IS_ERR and btrfs_grab_fs_root is reversed but then it looks
strange:

  4637                         fs_root = read_fs_root(fs_info,
_ 4638                                                reloc_root->root_key.offset);
  4639                         if (IS_ERR(fs_root)) {
  4640                                 ret = PTR_ERR(fs_root);
  4641                                 if (ret != -ENOENT) {
  4642                                         err = ret;
  4643                                         goto out;
  4644                                 }
  4645                                 ret = mark_garbage_root(reloc_root);
  4646                                 if (ret < 0) {
  4647                                         err = ret;
  4648                                         goto out;
  4649                                 }
  4650                         } else {
+ 4651                                 if (!btrfs_grab_fs_root(fs_root)) {
+ 4652                                         err = -ENOENT;
+ 4653                                         goto out;
+ 4654                                 }
  4655                                 btrfs_put_fs_root(fs_root);
  4656                         }
  4657                 }

Seems that the refcounting is not necessary here at all, it just tries
to read the fs root and handle errors if it does not exist, no operation
that would want to keep the fs_root.

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 27/44] btrfs: hold a ref on the root in btrfs_recover_relocation
  2020-02-06 16:26   ` David Sterba
@ 2020-02-06 16:30     ` Josef Bacik
  0 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2020-02-06 16:30 UTC (permalink / raw)
  To: dsterba, kernel-team, linux-btrfs

On 2/6/20 11:26 AM, David Sterba wrote:
> On Fri, Jan 24, 2020 at 09:32:44AM -0500, Josef Bacik wrote:
>> @@ -4593,6 +4593,10 @@ int btrfs_recover_relocation(struct btrfs_root *root)
>>   		if (btrfs_root_refs(&reloc_root->root_item) > 0) {
>>   			fs_root = read_fs_root(fs_info,
>>   					       reloc_root->root_key.offset);
>> +			if (!btrfs_grab_fs_root(fs_root)) {
>> +				err = -ENOENT;
>> +				goto out;
>> +			}
>>   			if (IS_ERR(fs_root)) {
>>   				ret = PTR_ERR(fs_root);
>>   				if (ret != -ENOENT) {
>> @@ -4604,6 +4608,8 @@ int btrfs_recover_relocation(struct btrfs_root *root)
>>   					err = ret;
>>   					goto out;
>>   				}
>> +			} else {
>> +				btrfs_put_fs_root(fs_root);
>>   			}
>>   		}
> 
> The order of IS_ERR and btrfs_grab_fs_root is reversed but then it looks
> strange:
> 
>    4637                         fs_root = read_fs_root(fs_info,
> _ 4638                                                reloc_root->root_key.offset);
>    4639                         if (IS_ERR(fs_root)) {
>    4640                                 ret = PTR_ERR(fs_root);
>    4641                                 if (ret != -ENOENT) {
>    4642                                         err = ret;
>    4643                                         goto out;
>    4644                                 }
>    4645                                 ret = mark_garbage_root(reloc_root);
>    4646                                 if (ret < 0) {
>    4647                                         err = ret;
>    4648                                         goto out;
>    4649                                 }
>    4650                         } else {
> + 4651                                 if (!btrfs_grab_fs_root(fs_root)) {
> + 4652                                         err = -ENOENT;
> + 4653                                         goto out;
> + 4654                                 }
>    4655                                 btrfs_put_fs_root(fs_root);
>    4656                         }
>    4657                 }
> 
> Seems that the refcounting is not necessary here at all, it just tries
> to read the fs root and handle errors if it does not exist, no operation
> that would want to keep the fs_root.
>

Yeah we aren't actually using the root here, so strictly speaking we don't need 
the refcount.  But in the future read_fs_root() will return a root with a 
refcount so we will still have to clean it up.  Thanks,

Josef



^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 00/44][v5] Cleanup how we handle root refs, part 1
  2020-02-05 15:48 ` David Sterba
@ 2020-02-06 16:59   ` David Sterba
  0 siblings, 0 replies; 63+ messages in thread
From: David Sterba @ 2020-02-06 16:59 UTC (permalink / raw)
  To: dsterba, Josef Bacik, kernel-team, linux-btrfs

On Wed, Feb 05, 2020 at 04:48:41PM +0100, David Sterba wrote:
> On Fri, Jan 24, 2020 at 09:32:17AM -0500, Josef Bacik wrote:
> > v4->v5:
> > - split out the btrfs_free_fs_info() moving around into it's own patch.
> > - updated a comment in btrfs_get_root() to describe why we are initializing part
> >   of the fs_info
> 
> I've commented under the patches, small things that I'd rather fixup
> in my branch once you look at them, no need to resend anything.
> 
> As the code is split, some changes are removed so even if there's
> something called in wrong order, it lasts only a few patches. For
> clarity I'd still like to have committed patches that don't have such
> things left.

All fixups done, I'll add the branch to misc-next.

^ permalink raw reply	[flat|nested] 63+ messages in thread

* [PATCH 44/44] btrfs: rename btrfs_put_fs_root and btrfs_grab_fs_root
  2019-12-06 14:44 [PATCH 0/44] " Josef Bacik
@ 2019-12-06 14:45 ` Josef Bacik
  0 siblings, 0 replies; 63+ messages in thread
From: Josef Bacik @ 2019-12-06 14:45 UTC (permalink / raw)
  To: linux-btrfs, kernel-team

We are now using these for all roots, rename them to btrfs_put_root()
and btrfs_grab_root();

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/backref.c         |  2 +-
 fs/btrfs/disk-io.c         | 78 +++++++++++++++++++-------------------
 fs/btrfs/disk-io.h         |  4 +-
 fs/btrfs/export.c          |  2 +-
 fs/btrfs/extent-tree.c     |  2 +-
 fs/btrfs/file.c            |  2 +-
 fs/btrfs/free-space-tree.c |  2 +-
 fs/btrfs/inode.c           | 12 +++---
 fs/btrfs/ioctl.c           | 18 ++++-----
 fs/btrfs/ordered-data.c    |  4 +-
 fs/btrfs/qgroup.c          |  4 +-
 fs/btrfs/relocation.c      | 48 +++++++++++------------
 fs/btrfs/root-tree.c       |  2 +-
 fs/btrfs/scrub.c           |  6 +--
 fs/btrfs/send.c            | 12 +++---
 fs/btrfs/super.c           | 10 ++---
 fs/btrfs/tree-log.c        | 10 ++---
 fs/btrfs/volumes.c         |  2 +-
 18 files changed, 110 insertions(+), 110 deletions(-)

diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index b69154d72529..ded46efac27d 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -577,7 +577,7 @@ static int resolve_indirect_ref(struct btrfs_fs_info *fs_info,
 	ret = add_all_parents(root, path, parents, ref, level, time_seq,
 			      extent_item_pos, total_refs, ignore_offset);
 out:
-	btrfs_put_fs_root(root);
+	btrfs_put_root(root);
 out_free:
 	path->lowest_level = 0;
 	btrfs_release_path(path);
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 143519aea1d0..afcee4ff6be1 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1313,7 +1313,7 @@ struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans,
 		free_extent_buffer(root->commit_root);
 		free_extent_buffer(leaf);
 	}
-	btrfs_put_fs_root(root);
+	btrfs_put_root(root);
 
 	return ERR_PTR(ret);
 }
@@ -1344,7 +1344,7 @@ static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans,
 	leaf = btrfs_alloc_tree_block(trans, root, 0, BTRFS_TREE_LOG_OBJECTID,
 			NULL, 0, 0, 0);
 	if (IS_ERR(leaf)) {
-		btrfs_put_fs_root(root);
+		btrfs_put_root(root);
 		return ERR_CAST(leaf);
 	}
 
@@ -1448,7 +1448,7 @@ struct btrfs_root *btrfs_read_tree_root(struct btrfs_root *tree_root,
 	return root;
 
 find_fail:
-	btrfs_put_fs_root(root);
+	btrfs_put_root(root);
 alloc_fail:
 	root = ERR_PTR(ret);
 	goto out;
@@ -1514,7 +1514,7 @@ static struct btrfs_root *btrfs_lookup_fs_root(struct btrfs_fs_info *fs_info,
 	root = radix_tree_lookup(&fs_info->fs_roots_radix,
 				 (unsigned long)root_id);
 	if (root)
-		root = btrfs_grab_fs_root(root);
+		root = btrfs_grab_root(root);
 	spin_unlock(&fs_info->fs_roots_radix_lock);
 	return root;
 }
@@ -1533,7 +1533,7 @@ int btrfs_insert_fs_root(struct btrfs_fs_info *fs_info,
 				(unsigned long)root->root_key.objectid,
 				root);
 	if (ret == 0) {
-		btrfs_grab_fs_root(root);
+		btrfs_grab_root(root);
 		set_bit(BTRFS_ROOT_IN_RADIX, &root->state);
 	}
 	spin_unlock(&fs_info->fs_roots_radix_lock);
@@ -1561,8 +1561,8 @@ static void btrfs_check_leaked_roots(struct btrfs_fs_info *fs_info)
 			  root->root_key.objectid, root->root_key.offset,
 			  refcount_read(&root->refs));
 		while (refcount_read(&root->refs) > 1)
-			btrfs_put_fs_root(root);
-		btrfs_put_fs_root(root);
+			btrfs_put_root(root);
+		btrfs_put_root(root);
 	}
 #endif
 }
@@ -1578,15 +1578,15 @@ void btrfs_free_fs_info(struct btrfs_fs_info *fs_info)
 	btrfs_free_ref_cache(fs_info);
 	kfree(fs_info->balance_ctl);
 	kfree(fs_info->delayed_root);
-	btrfs_put_fs_root(fs_info->extent_root);
-	btrfs_put_fs_root(fs_info->tree_root);
-	btrfs_put_fs_root(fs_info->chunk_root);
-	btrfs_put_fs_root(fs_info->dev_root);
-	btrfs_put_fs_root(fs_info->csum_root);
-	btrfs_put_fs_root(fs_info->quota_root);
-	btrfs_put_fs_root(fs_info->uuid_root);
-	btrfs_put_fs_root(fs_info->free_space_root);
-	btrfs_put_fs_root(fs_info->fs_root);
+	btrfs_put_root(fs_info->extent_root);
+	btrfs_put_root(fs_info->tree_root);
+	btrfs_put_root(fs_info->chunk_root);
+	btrfs_put_root(fs_info->dev_root);
+	btrfs_put_root(fs_info->csum_root);
+	btrfs_put_root(fs_info->quota_root);
+	btrfs_put_root(fs_info->uuid_root);
+	btrfs_put_root(fs_info->free_space_root);
+	btrfs_put_root(fs_info->fs_root);
 	btrfs_check_leaked_roots(fs_info);
 	kfree(fs_info->super_copy);
 	kfree(fs_info->super_for_commit);
@@ -1604,32 +1604,32 @@ struct btrfs_root *btrfs_get_fs_root(struct btrfs_fs_info *fs_info,
 	int ret;
 
 	if (location->objectid == BTRFS_ROOT_TREE_OBJECTID)
-		return btrfs_grab_fs_root(fs_info->tree_root);
+		return btrfs_grab_root(fs_info->tree_root);
 	if (location->objectid == BTRFS_EXTENT_TREE_OBJECTID)
-		return btrfs_grab_fs_root(fs_info->extent_root);
+		return btrfs_grab_root(fs_info->extent_root);
 	if (location->objectid == BTRFS_CHUNK_TREE_OBJECTID)
-		return btrfs_grab_fs_root(fs_info->chunk_root);
+		return btrfs_grab_root(fs_info->chunk_root);
 	if (location->objectid == BTRFS_DEV_TREE_OBJECTID)
-		return btrfs_grab_fs_root(fs_info->dev_root);
+		return btrfs_grab_root(fs_info->dev_root);
 	if (location->objectid == BTRFS_CSUM_TREE_OBJECTID)
-		return btrfs_grab_fs_root(fs_info->csum_root);
+		return btrfs_grab_root(fs_info->csum_root);
 	if (location->objectid == BTRFS_QUOTA_TREE_OBJECTID)
 		return fs_info->quota_root ?
-			btrfs_grab_fs_root(fs_info->quota_root) :
+			btrfs_grab_root(fs_info->quota_root) :
 			ERR_PTR(-ENOENT);
 	if (location->objectid == BTRFS_UUID_TREE_OBJECTID)
 		return fs_info->uuid_root ?
-			btrfs_grab_fs_root(fs_info->uuid_root) :
+			btrfs_grab_root(fs_info->uuid_root) :
 			ERR_PTR(-ENOENT);
 	if (location->objectid == BTRFS_FREE_SPACE_TREE_OBJECTID)
 		return fs_info->free_space_root ?
-			btrfs_grab_fs_root(fs_info->free_space_root) :
+			btrfs_grab_root(fs_info->free_space_root) :
 			ERR_PTR(-ENOENT);
 again:
 	root = btrfs_lookup_fs_root(fs_info, location->objectid);
 	if (root) {
 		if (check_ref && btrfs_root_refs(&root->root_item) == 0) {
-			btrfs_put_fs_root(root);
+			btrfs_put_root(root);
 			return ERR_PTR(-ENOENT);
 		}
 		return root;
@@ -1672,10 +1672,10 @@ struct btrfs_root *btrfs_get_fs_root(struct btrfs_fs_info *fs_info,
 	 * we have the third for returning it, and the caller will put it when
 	 * it's done with the root.
 	 */
-	btrfs_grab_fs_root(root);
+	btrfs_grab_root(root);
 	ret = btrfs_insert_fs_root(fs_info, root);
 	if (ret) {
-		btrfs_put_fs_root(root);
+		btrfs_put_root(root);
 		if (ret == -EEXIST) {
 			btrfs_free_fs_root(root);
 			goto again;
@@ -2075,7 +2075,7 @@ void btrfs_free_fs_roots(struct btrfs_fs_info *fs_info)
 		} else {
 			free_extent_buffer(gang[0]->node);
 			free_extent_buffer(gang[0]->commit_root);
-			btrfs_put_fs_root(gang[0]);
+			btrfs_put_root(gang[0]);
 		}
 	}
 
@@ -2280,12 +2280,12 @@ static int btrfs_replay_log(struct btrfs_fs_info *fs_info,
 	if (IS_ERR(log_tree_root->node)) {
 		btrfs_warn(fs_info, "failed to read log tree");
 		ret = PTR_ERR(log_tree_root->node);
-		btrfs_put_fs_root(log_tree_root);
+		btrfs_put_root(log_tree_root);
 		return ret;
 	} else if (!extent_buffer_uptodate(log_tree_root->node)) {
 		btrfs_err(fs_info, "failed to read log tree");
 		free_extent_buffer(log_tree_root->node);
-		btrfs_put_fs_root(log_tree_root);
+		btrfs_put_root(log_tree_root);
 		return -EIO;
 	}
 	/* returns with log_tree_root freed on success */
@@ -2294,7 +2294,7 @@ static int btrfs_replay_log(struct btrfs_fs_info *fs_info,
 		btrfs_handle_fs_error(fs_info, ret,
 				      "Failed to recover log tree");
 		free_extent_buffer(log_tree_root->node);
-		btrfs_put_fs_root(log_tree_root);
+		btrfs_put_root(log_tree_root);
 		return ret;
 	}
 
@@ -3892,7 +3892,7 @@ void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info,
 	radix_tree_delete(&fs_info->fs_roots_radix,
 			  (unsigned long)root->root_key.objectid);
 	if (test_and_clear_bit(BTRFS_ROOT_IN_RADIX, &root->state))
-		btrfs_put_fs_root(root);
+		btrfs_put_root(root);
 	spin_unlock(&fs_info->fs_roots_radix_lock);
 
 	if (btrfs_root_refs(&root->root_item) == 0)
@@ -3903,7 +3903,7 @@ void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info,
 		if (root->reloc_root) {
 			free_extent_buffer(root->reloc_root->node);
 			free_extent_buffer(root->reloc_root->commit_root);
-			btrfs_put_fs_root(root->reloc_root);
+			btrfs_put_root(root->reloc_root);
 			root->reloc_root = NULL;
 		}
 	}
@@ -3927,7 +3927,7 @@ void btrfs_free_fs_root(struct btrfs_root *root)
 	free_extent_buffer(root->commit_root);
 	kfree(root->free_ino_ctl);
 	kfree(root->free_ino_pinned);
-	btrfs_put_fs_root(root);
+	btrfs_put_root(root);
 }
 
 int btrfs_cleanup_fs_roots(struct btrfs_fs_info *fs_info)
@@ -3957,7 +3957,7 @@ int btrfs_cleanup_fs_roots(struct btrfs_fs_info *fs_info)
 				continue;
 			}
 			/* grab all the search result for later use */
-			gang[i] = btrfs_grab_fs_root(gang[i]);
+			gang[i] = btrfs_grab_root(gang[i]);
 		}
 		srcu_read_unlock(&fs_info->subvol_srcu, index);
 
@@ -3968,7 +3968,7 @@ int btrfs_cleanup_fs_roots(struct btrfs_fs_info *fs_info)
 			err = btrfs_orphan_cleanup(gang[i]);
 			if (err)
 				break;
-			btrfs_put_fs_root(gang[i]);
+			btrfs_put_root(gang[i]);
 		}
 		root_objectid++;
 	}
@@ -3976,7 +3976,7 @@ int btrfs_cleanup_fs_roots(struct btrfs_fs_info *fs_info)
 	/* release the uncleaned roots due to error */
 	for (; i < ret; i++) {
 		if (gang[i])
-			btrfs_put_fs_root(gang[i]);
+			btrfs_put_root(gang[i]);
 	}
 	return err;
 }
@@ -4365,12 +4365,12 @@ static void btrfs_destroy_all_delalloc_inodes(struct btrfs_fs_info *fs_info)
 	while (!list_empty(&splice)) {
 		root = list_first_entry(&splice, struct btrfs_root,
 					 delalloc_root);
-		root = btrfs_grab_fs_root(root);
+		root = btrfs_grab_root(root);
 		BUG_ON(!root);
 		spin_unlock(&fs_info->delalloc_root_lock);
 
 		btrfs_destroy_delalloc_inodes(root);
-		btrfs_put_fs_root(root);
+		btrfs_put_root(root);
 
 		spin_lock(&fs_info->delalloc_root_lock);
 	}
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
index 3178849ee82d..955d7826b6af 100644
--- a/fs/btrfs/disk-io.h
+++ b/fs/btrfs/disk-io.h
@@ -87,14 +87,14 @@ struct btrfs_root *btrfs_alloc_dummy_root(struct btrfs_fs_info *fs_info);
  * If you want to ensure the whole tree is safe, you should use
  * 	fs_info->subvol_srcu
  */
-static inline struct btrfs_root *btrfs_grab_fs_root(struct btrfs_root *root)
+static inline struct btrfs_root *btrfs_grab_root(struct btrfs_root *root)
 {
 	if (refcount_inc_not_zero(&root->refs))
 		return root;
 	return NULL;
 }
 
-static inline void btrfs_put_fs_root(struct btrfs_root *root)
+static inline void btrfs_put_root(struct btrfs_root *root)
 {
 	if (!root)
 		return;
diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c
index f07c2300ade2..657fd6ad6e18 100644
--- a/fs/btrfs/export.c
+++ b/fs/btrfs/export.c
@@ -88,7 +88,7 @@ static struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid,
 	key.offset = 0;
 
 	inode = btrfs_iget(sb, &key, root);
-	btrfs_put_fs_root(root);
+	btrfs_put_root(root);
 	if (IS_ERR(inode)) {
 		err = PTR_ERR(inode);
 		goto fail;
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 18df434bfe52..04ad2100ecc1 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -5415,7 +5415,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
 	} else {
 		free_extent_buffer(root->node);
 		free_extent_buffer(root->commit_root);
-		btrfs_put_fs_root(root);
+		btrfs_put_root(root);
 	}
 	root_dropped = true;
 out_end_trans:
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 062580a1721f..254fa3cc1ba7 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -297,7 +297,7 @@ static int __btrfs_run_defrag_inode(struct btrfs_fs_info *fs_info,
 	key.type = BTRFS_INODE_ITEM_KEY;
 	key.offset = 0;
 	inode = btrfs_iget(fs_info->sb, &key, inode_root);
-	btrfs_put_fs_root(inode_root);
+	btrfs_put_root(inode_root);
 	if (IS_ERR(inode)) {
 		ret = PTR_ERR(inode);
 		goto cleanup;
diff --git a/fs/btrfs/free-space-tree.c b/fs/btrfs/free-space-tree.c
index c79804c30b17..bc43950eb32f 100644
--- a/fs/btrfs/free-space-tree.c
+++ b/fs/btrfs/free-space-tree.c
@@ -1253,7 +1253,7 @@ int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info)
 
 	free_extent_buffer(free_space_root->node);
 	free_extent_buffer(free_space_root->commit_root);
-	btrfs_put_fs_root(free_space_root);
+	btrfs_put_root(free_space_root);
 
 	return btrfs_commit_transaction(trans);
 
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index bc961ca6995f..bbb8a9641a6d 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -2533,7 +2533,7 @@ static noinline int record_one_backref(u64 inum, u64 offset, u64 root_id,
 
 	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
 	if (WARN_ON(ret < 0)) {
-		btrfs_put_fs_root(root);
+		btrfs_put_root(root);
 		return ret;
 	}
 	ret = 0;
@@ -2605,7 +2605,7 @@ static noinline int record_one_backref(u64 inum, u64 offset, u64 root_id,
 	backref_insert(&new->root, backref);
 	old->count++;
 out:
-	btrfs_put_fs_root(root);
+	btrfs_put_root(root);
 	btrfs_release_path(path);
 	WARN_ON(ret);
 	return ret;
@@ -2720,7 +2720,7 @@ static noinline int relink_extent_backref(struct btrfs_path *path,
 	key.offset = 0;
 
 	inode = btrfs_iget(fs_info->sb, &key, root);
-	btrfs_put_fs_root(root);
+	btrfs_put_root(root);
 	if (IS_ERR(inode)) {
 		srcu_read_unlock(&fs_info->subvol_srcu, index);
 		return 0;
@@ -5923,7 +5923,7 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)
 		inode = btrfs_iget(dir->i_sb, &location, sub_root);
 	}
 	if (root != sub_root)
-		btrfs_put_fs_root(sub_root);
+		btrfs_put_root(sub_root);
 	srcu_read_unlock(&fs_info->subvol_srcu, index);
 
 	if (!IS_ERR(inode) && root != sub_root) {
@@ -10257,14 +10257,14 @@ int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, int nr)
 	while (!list_empty(&splice) && nr) {
 		root = list_first_entry(&splice, struct btrfs_root,
 					delalloc_root);
-		root = btrfs_grab_fs_root(root);
+		root = btrfs_grab_root(root);
 		BUG_ON(!root);
 		list_move_tail(&root->delalloc_root,
 			       &fs_info->delalloc_roots);
 		spin_unlock(&fs_info->delalloc_root_lock);
 
 		ret = start_delalloc_inodes(root, nr, false);
-		btrfs_put_fs_root(root);
+		btrfs_put_root(root);
 		if (ret < 0)
 			goto out;
 
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 7df2576aa2e3..8ec61f3f0291 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -676,7 +676,7 @@ static noinline int create_subvol(struct inode *dir,
 	btrfs_record_root_in_trans(trans, new_root);
 
 	ret = btrfs_create_subvol_root(trans, new_root, root, new_dirid);
-	btrfs_put_fs_root(new_root);
+	btrfs_put_root(new_root);
 	if (ret) {
 		/* We potentially lose an unused inode item here */
 		btrfs_abort_transaction(trans, ret);
@@ -870,7 +870,7 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
 	d_instantiate(dentry, inode);
 	ret = 0;
 fail:
-	btrfs_put_fs_root(pending_snapshot->snap);
+	btrfs_put_root(pending_snapshot->snap);
 	btrfs_subvolume_release_metadata(fs_info, &pending_snapshot->block_rsv);
 dec_and_free:
 	if (snapshot_force_cow)
@@ -2176,7 +2176,7 @@ static noinline int search_ioctl(struct inode *inode,
 
 	if (sk->tree_id == 0) {
 		/* search the root of the inode that was passed */
-		root = btrfs_grab_fs_root(BTRFS_I(inode)->root);
+		root = btrfs_grab_root(BTRFS_I(inode)->root);
 	} else {
 		key.objectid = sk->tree_id;
 		key.type = BTRFS_ROOT_ITEM_KEY;
@@ -2210,7 +2210,7 @@ static noinline int search_ioctl(struct inode *inode,
 		ret = 0;
 err:
 	sk->nr_items = num_found;
-	btrfs_put_fs_root(root);
+	btrfs_put_root(root);
 	btrfs_free_path(path);
 	return ret;
 }
@@ -2372,7 +2372,7 @@ static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info,
 	ret = 0;
 out:
 	if (root)
-		btrfs_put_fs_root(root);
+		btrfs_put_root(root);
 	btrfs_free_path(path);
 	return ret;
 }
@@ -2500,7 +2500,7 @@ static int btrfs_search_path_in_tree_user(struct inode *inode,
 
 		memmove(args->path, ptr, total_len);
 		args->path[total_len] = '\0';
-		btrfs_put_fs_root(root);
+		btrfs_put_root(root);
 		btrfs_release_path(path);
 	}
 
@@ -2540,7 +2540,7 @@ static int btrfs_search_path_in_tree_user(struct inode *inode,
 	btrfs_free_path(path);
 	return ret;
 out_put:
-	btrfs_put_fs_root(root);
+	btrfs_put_root(root);
 	goto out;
 }
 
@@ -2743,7 +2743,7 @@ static int btrfs_ioctl_get_subvol_info(struct file *file, void __user *argp)
 		ret = -EFAULT;
 
 out:
-	btrfs_put_fs_root(root);
+	btrfs_put_root(root);
 out_free:
 	btrfs_free_path(path);
 	kzfree(subvol_info);
@@ -4041,7 +4041,7 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp)
 	btrfs_set_fs_incompat(fs_info, DEFAULT_SUBVOL);
 	btrfs_end_transaction(trans);
 out_free:
-	btrfs_put_fs_root(new_root);
+	btrfs_put_root(new_root);
 	btrfs_free_path(path);
 out:
 	mnt_drop_write_file(file);
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index 6240a5a1f2c0..3a3c648bb9d3 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -588,7 +588,7 @@ u64 btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, u64 nr,
 	while (!list_empty(&splice) && nr) {
 		root = list_first_entry(&splice, struct btrfs_root,
 					ordered_root);
-		root = btrfs_grab_fs_root(root);
+		root = btrfs_grab_root(root);
 		BUG_ON(!root);
 		list_move_tail(&root->ordered_root,
 			       &fs_info->ordered_roots);
@@ -596,7 +596,7 @@ u64 btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, u64 nr,
 
 		done = btrfs_wait_ordered_extents(root, nr,
 						  range_start, range_len);
-		btrfs_put_fs_root(root);
+		btrfs_put_root(root);
 		total_done += done;
 
 		spin_lock(&fs_info->ordered_root_lock);
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 762f254b4b38..8fb576495be9 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -1040,7 +1040,7 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info)
 	if (ret) {
 		free_extent_buffer(quota_root->node);
 		free_extent_buffer(quota_root->commit_root);
-		btrfs_put_fs_root(quota_root);
+		btrfs_put_root(quota_root);
 	}
 out:
 	if (ret) {
@@ -1106,7 +1106,7 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info)
 
 	free_extent_buffer(quota_root->node);
 	free_extent_buffer(quota_root->commit_root);
-	btrfs_put_fs_root(quota_root);
+	btrfs_put_root(quota_root);
 
 end_trans:
 	ret = btrfs_end_transaction(trans);
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index f6d63d6cf22d..754f18e8019b 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -257,7 +257,7 @@ static void free_backref_node(struct backref_cache *cache,
 	if (node) {
 		cache->nr_nodes--;
 		if (node->root)
-			btrfs_put_fs_root(node->root);
+			btrfs_put_root(node->root);
 		kfree(node);
 	}
 }
@@ -870,7 +870,7 @@ struct backref_node *build_backref_tree(struct reloc_control *rc,
 			ASSERT(btrfs_root_bytenr(&root->root_item) ==
 			       cur->bytenr);
 			if (should_ignore_root(root)) {
-				btrfs_put_fs_root(root);
+				btrfs_put_root(root);
 				list_add(&cur->list, &useless);
 			} else {
 				cur->root = root;
@@ -887,7 +887,7 @@ struct backref_node *build_backref_tree(struct reloc_control *rc,
 		ret = btrfs_search_slot(NULL, root, node_key, path2, 0, 0);
 		path2->lowest_level = 0;
 		if (ret < 0) {
-			btrfs_put_fs_root(root);
+			btrfs_put_root(root);
 			err = ret;
 			goto out;
 		}
@@ -903,7 +903,7 @@ struct backref_node *build_backref_tree(struct reloc_control *rc,
 				  root->root_key.objectid,
 				  node_key->objectid, node_key->type,
 				  node_key->offset);
-			btrfs_put_fs_root(root);
+			btrfs_put_root(root);
 			err = -ENOENT;
 			goto out;
 		}
@@ -916,7 +916,7 @@ struct backref_node *build_backref_tree(struct reloc_control *rc,
 				ASSERT(btrfs_root_bytenr(&root->root_item) ==
 				       lower->bytenr);
 				if (should_ignore_root(root)) {
-					btrfs_put_fs_root(root);
+					btrfs_put_root(root);
 					list_add(&lower->list, &useless);
 				} else {
 					lower->root = root;
@@ -926,7 +926,7 @@ struct backref_node *build_backref_tree(struct reloc_control *rc,
 
 			edge = alloc_backref_edge(cache);
 			if (!edge) {
-				btrfs_put_fs_root(root);
+				btrfs_put_root(root);
 				err = -ENOMEM;
 				goto out;
 			}
@@ -936,7 +936,7 @@ struct backref_node *build_backref_tree(struct reloc_control *rc,
 			if (!rb_node) {
 				upper = alloc_backref_node(cache);
 				if (!upper) {
-					btrfs_put_fs_root(root);
+					btrfs_put_root(root);
 					free_backref_edge(cache, edge);
 					err = -ENOMEM;
 					goto out;
@@ -985,7 +985,7 @@ struct backref_node *build_backref_tree(struct reloc_control *rc,
 			edge->node[UPPER] = upper;
 
 			if (rb_node) {
-				btrfs_put_fs_root(root);
+				btrfs_put_root(root);
 				break;
 			}
 			lower = upper;
@@ -1224,7 +1224,7 @@ static int clone_backref_node(struct btrfs_trans_handle *trans,
 	new_node->level = node->level;
 	new_node->lowest = node->lowest;
 	new_node->checked = 1;
-	new_node->root = btrfs_grab_fs_root(dest);
+	new_node->root = btrfs_grab_root(dest);
 	ASSERT(new_node->root);
 
 	if (!node->lowest) {
@@ -2189,7 +2189,7 @@ static void insert_dirty_subvol(struct btrfs_trans_handle *trans,
 	btrfs_update_reloc_root(trans, root);
 
 	if (list_empty(&root->reloc_dirty_list)) {
-		btrfs_grab_fs_root(root);
+		btrfs_grab_root(root);
 		list_add_tail(&root->reloc_dirty_list, &rc->dirty_subvol_roots);
 	}
 }
@@ -2216,7 +2216,7 @@ static int clean_dirty_subvols(struct reloc_control *rc)
 					ret = ret2;
 			}
 			clear_bit(BTRFS_ROOT_DEAD_RELOC_TREE, &root->state);
-			btrfs_put_fs_root(root);
+			btrfs_put_root(root);
 		} else {
 			/* Orphan reloc tree, just clean it up */
 			ret2 = btrfs_drop_snapshot(root, NULL, 0, 1);
@@ -2441,7 +2441,7 @@ int prepare_to_merge(struct reloc_control *rc, int err)
 		btrfs_update_reloc_root(trans, root);
 
 		list_add(&reloc_root->root_list, &reloc_roots);
-		btrfs_put_fs_root(root);
+		btrfs_put_root(root);
 	}
 
 	list_splice(&reloc_roots, &rc->reloc_roots);
@@ -2503,7 +2503,7 @@ void merge_reloc_roots(struct reloc_control *rc)
 			BUG_ON(root->reloc_root != reloc_root);
 
 			ret = merge_reloc_root(rc, root);
-			btrfs_put_fs_root(root);
+			btrfs_put_root(root);
 			if (ret) {
 				if (list_empty(&reloc_root->root_list))
 					list_add_tail(&reloc_root->root_list,
@@ -2564,7 +2564,7 @@ static int record_reloc_root_in_trans(struct btrfs_trans_handle *trans,
 	BUG_ON(IS_ERR(root));
 	BUG_ON(root->reloc_root != reloc_root);
 	ret = btrfs_record_root_in_trans(trans, root);
-	btrfs_put_fs_root(root);
+	btrfs_put_root(root);
 
 	return ret;
 }
@@ -2599,8 +2599,8 @@ struct btrfs_root *select_reloc_root(struct btrfs_trans_handle *trans,
 			BUG_ON(next->new_bytenr);
 			BUG_ON(!list_empty(&next->list));
 			next->new_bytenr = root->node->start;
-			btrfs_put_fs_root(next->root);
-			next->root = btrfs_grab_fs_root(root);
+			btrfs_put_root(next->root);
+			next->root = btrfs_grab_root(root);
 			ASSERT(next->root);
 			list_add_tail(&next->list,
 				      &rc->backref_cache.changed);
@@ -3073,8 +3073,8 @@ static int relocate_tree_block(struct btrfs_trans_handle *trans,
 			btrfs_record_root_in_trans(trans, root);
 			root = root->reloc_root;
 			node->new_bytenr = root->node->start;
-			btrfs_put_fs_root(node->root);
-			node->root = btrfs_grab_fs_root(root);
+			btrfs_put_root(node->root);
+			node->root = btrfs_grab_root(root);
 			ASSERT(node->root);
 			list_add_tail(&node->list, &rc->backref_cache.changed);
 		} else {
@@ -3772,7 +3772,7 @@ static int find_data_references(struct reloc_control *rc,
 
 	}
 out:
-	btrfs_put_fs_root(root);
+	btrfs_put_root(root);
 out_free:
 	btrfs_free_path(path);
 	return err;
@@ -4258,7 +4258,7 @@ struct inode *create_reloc_inode(struct btrfs_fs_info *fs_info,
 
 	trans = btrfs_start_transaction(root, 6);
 	if (IS_ERR(trans)) {
-		btrfs_put_fs_root(root);
+		btrfs_put_root(root);
 		return ERR_CAST(trans);
 	}
 
@@ -4278,7 +4278,7 @@ struct inode *create_reloc_inode(struct btrfs_fs_info *fs_info,
 
 	err = btrfs_orphan_add(trans, BTRFS_I(inode));
 out:
-	btrfs_put_fs_root(root);
+	btrfs_put_root(root);
 	btrfs_end_transaction(trans);
 	btrfs_btree_balance_dirty(fs_info);
 	if (err) {
@@ -4538,7 +4538,7 @@ int btrfs_recover_relocation(struct btrfs_root *root)
 					goto out;
 				}
 			} else {
-				btrfs_put_fs_root(fs_root);
+				btrfs_put_root(fs_root);
 			}
 		}
 
@@ -4592,7 +4592,7 @@ int btrfs_recover_relocation(struct btrfs_root *root)
 		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);
+		btrfs_put_root(fs_root);
 	}
 
 	err = btrfs_commit_transaction(trans);
@@ -4628,7 +4628,7 @@ int btrfs_recover_relocation(struct btrfs_root *root)
 			err = PTR_ERR(fs_root);
 		} else {
 			err = btrfs_orphan_cleanup(fs_root);
-			btrfs_put_fs_root(fs_root);
+			btrfs_put_root(fs_root);
 		}
 	}
 	return err;
diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c
index 2c94b5318b40..0a455f116666 100644
--- a/fs/btrfs/root-tree.c
+++ b/fs/btrfs/root-tree.c
@@ -288,7 +288,7 @@ int btrfs_find_orphan_roots(struct btrfs_fs_info *fs_info)
 			set_bit(BTRFS_ROOT_DEAD_TREE, &root->state);
 			btrfs_add_dead_root(root);
 		}
-		btrfs_put_fs_root(root);
+		btrfs_put_root(root);
 	}
 
 	btrfs_free_path(path);
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index 0c8b60055c2e..53261bf04c11 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -667,7 +667,7 @@ static int scrub_print_warning_inode(u64 inum, u64 offset, u64 root,
 
 	ret = btrfs_search_slot(NULL, local_root, &key, swarn->path, 0, 0);
 	if (ret) {
-		btrfs_put_fs_root(local_root);
+		btrfs_put_root(local_root);
 		btrfs_release_path(swarn->path);
 		goto err;
 	}
@@ -688,7 +688,7 @@ static int scrub_print_warning_inode(u64 inum, u64 offset, u64 root,
 	ipath = init_ipath(4096, local_root, swarn->path);
 	memalloc_nofs_restore(nofs_flag);
 	if (IS_ERR(ipath)) {
-		btrfs_put_fs_root(local_root);
+		btrfs_put_root(local_root);
 		ret = PTR_ERR(ipath);
 		ipath = NULL;
 		goto err;
@@ -712,7 +712,7 @@ static int scrub_print_warning_inode(u64 inum, u64 offset, u64 root,
 				  min(isize - offset, (u64)PAGE_SIZE), nlink,
 				  (char *)(unsigned long)ipath->fspath->val[i]);
 
-	btrfs_put_fs_root(local_root);
+	btrfs_put_root(local_root);
 	free_ipath(ipath);
 	return 0;
 
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 6520ad8f4e81..a7041f270140 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -7211,7 +7211,7 @@ long btrfs_ioctl_send(struct file *mnt_file, struct btrfs_ioctl_send_args *arg)
 			    btrfs_root_dead(clone_root)) {
 				spin_unlock(&clone_root->root_item_lock);
 				srcu_read_unlock(&fs_info->subvol_srcu, index);
-				btrfs_put_fs_root(clone_root);
+				btrfs_put_root(clone_root);
 				ret = -EPERM;
 				goto out;
 			}
@@ -7219,7 +7219,7 @@ long btrfs_ioctl_send(struct file *mnt_file, struct btrfs_ioctl_send_args *arg)
 				dedupe_in_progress_warn(clone_root);
 				spin_unlock(&clone_root->root_item_lock);
 				srcu_read_unlock(&fs_info->subvol_srcu, index);
-				btrfs_put_fs_root(clone_root);
+				btrfs_put_root(clone_root);
 				ret = -EAGAIN;
 				goto out;
 			}
@@ -7275,7 +7275,7 @@ long btrfs_ioctl_send(struct file *mnt_file, struct btrfs_ioctl_send_args *arg)
 	 * for possible clone sources.
 	 */
 	sctx->clone_roots[sctx->clone_roots_cnt++].root =
-		btrfs_grab_fs_root(sctx->send_root);
+		btrfs_grab_root(sctx->send_root);
 
 	/* We do a bsearch later */
 	sort(sctx->clone_roots, sctx->clone_roots_cnt,
@@ -7363,20 +7363,20 @@ long btrfs_ioctl_send(struct file *mnt_file, struct btrfs_ioctl_send_args *arg)
 		for (i = 0; i < sctx->clone_roots_cnt; i++) {
 			btrfs_root_dec_send_in_progress(
 					sctx->clone_roots[i].root);
-			btrfs_put_fs_root(sctx->clone_roots[i].root);
+			btrfs_put_root(sctx->clone_roots[i].root);
 		}
 	} else {
 		for (i = 0; sctx && i < clone_sources_to_rollback; i++) {
 			btrfs_root_dec_send_in_progress(
 					sctx->clone_roots[i].root);
-			btrfs_put_fs_root(sctx->clone_roots[i].root);
+			btrfs_put_root(sctx->clone_roots[i].root);
 		}
 
 		btrfs_root_dec_send_in_progress(send_root);
 	}
 	if (sctx && !IS_ERR_OR_NULL(sctx->parent_root)) {
 		btrfs_root_dec_send_in_progress(sctx->parent_root);
-		btrfs_put_fs_root(sctx->parent_root);
+		btrfs_put_root(sctx->parent_root);
 	}
 
 	kvfree(clone_sources_tmp);
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 80fea16cf34c..476c93a238eb 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -1094,16 +1094,16 @@ static char *get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info,
 
 			ret = btrfs_search_slot(NULL, fs_root, &key, path, 0, 0);
 			if (ret < 0) {
-				btrfs_put_fs_root(fs_root);
+				btrfs_put_root(fs_root);
 				goto err;
 			} else if (ret > 0) {
 				ret = btrfs_previous_item(fs_root, path, dirid,
 							  BTRFS_INODE_REF_KEY);
 				if (ret < 0) {
-					btrfs_put_fs_root(fs_root);
+					btrfs_put_root(fs_root);
 					goto err;
 				} else if (ret > 0) {
-					btrfs_put_fs_root(fs_root);
+					btrfs_put_root(fs_root);
 					ret = -ENOENT;
 					goto err;
 				}
@@ -1120,7 +1120,7 @@ static char *get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info,
 			ptr -= len + 1;
 			if (ptr < name) {
 				ret = -ENAMETOOLONG;
-				btrfs_put_fs_root(fs_root);
+				btrfs_put_root(fs_root);
 				goto err;
 			}
 			read_extent_buffer(path->nodes[0], ptr + 1,
@@ -1128,7 +1128,7 @@ static char *get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info,
 			ptr[0] = '/';
 			btrfs_release_path(path);
 		}
-		btrfs_put_fs_root(fs_root);
+		btrfs_put_root(fs_root);
 	}
 
 	btrfs_free_path(path);
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 32ee8698a87f..968605b901ed 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -3296,7 +3296,7 @@ static void free_log_tree(struct btrfs_trans_handle *trans,
 	clear_extent_bits(&log->dirty_log_pages, 0, (u64)-1,
 			  EXTENT_DIRTY | EXTENT_NEW | EXTENT_NEED_WAIT);
 	free_extent_buffer(log->node);
-	btrfs_put_fs_root(log);
+	btrfs_put_root(log);
 }
 
 /*
@@ -6312,7 +6312,7 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
 							log->node->len);
 			free_extent_buffer(log->node);
 			free_extent_buffer(log->commit_root);
-			btrfs_put_fs_root(log);
+			btrfs_put_root(log);
 
 			if (!ret)
 				goto next;
@@ -6348,10 +6348,10 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
 		}
 
 		wc.replay_dest->log_root = NULL;
-		btrfs_put_fs_root(wc.replay_dest);
+		btrfs_put_root(wc.replay_dest);
 		free_extent_buffer(log->node);
 		free_extent_buffer(log->commit_root);
-		btrfs_put_fs_root(log);
+		btrfs_put_root(log);
 
 		if (ret)
 			goto error;
@@ -6385,7 +6385,7 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
 	free_extent_buffer(log_root_tree->node);
 	log_root_tree->log_root = NULL;
 	clear_bit(BTRFS_FS_LOG_RECOVERING, &fs_info->flags);
-	btrfs_put_fs_root(log_root_tree);
+	btrfs_put_root(log_root_tree);
 
 	return 0;
 error:
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index d261a39b7aa6..7483521a928b 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -4391,7 +4391,7 @@ static int btrfs_check_uuid_tree_entry(struct btrfs_fs_info *fs_info,
 			ret = 1;
 		break;
 	}
-	btrfs_put_fs_root(subvol_root);
+	btrfs_put_root(subvol_root);
 out:
 	return ret;
 }
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 63+ messages in thread

end of thread, other threads:[~2020-02-06 17:00 UTC | newest]

Thread overview: 63+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-24 14:32 [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 Josef Bacik
2020-01-24 14:32 ` [PATCH 01/44] btrfs: push __setup_root into btrfs_alloc_root Josef Bacik
2020-02-04 22:05   ` David Sterba
2020-01-24 14:32 ` [PATCH 02/44] btrfs: move fs root init stuff into btrfs_init_fs_root Josef Bacik
2020-01-24 14:32 ` [PATCH 03/44] btrfs: make btrfs_find_orphan_roots use btrfs_get_fs_root Josef Bacik
2020-01-24 14:32 ` [PATCH 04/44] btrfs: export and use btrfs_read_tree_root Josef Bacik
2020-01-24 14:32 ` [PATCH 05/44] btrfs: make relocation use btrfs_read_tree_root() Josef Bacik
2020-01-24 14:32 ` [PATCH 06/44] btrfs: kill btrfs_read_fs_root Josef Bacik
2020-01-24 14:32 ` [PATCH 07/44] btrfs: kill the btrfs_read_fs_root_no_name helper Josef Bacik
2020-01-24 14:32 ` [PATCH 08/44] btrfs: make the fs root init functions static Josef Bacik
2020-01-24 14:32 ` [PATCH 09/44] btrfs: handle NULL roots in btrfs_put/btrfs_grab_fs_root Josef Bacik
2020-01-24 14:32 ` [PATCH 10/44] btrfs: hold a ref on fs roots while they're in the radix tree Josef Bacik
2020-01-24 14:32 ` [PATCH 11/44] btrfs: hold a ref on the root in resolve_indirect_ref Josef Bacik
2020-01-24 14:32 ` [PATCH 12/44] btrfs: hold a root ref in btrfs_get_dentry Josef Bacik
2020-01-24 14:32 ` [PATCH 13/44] btrfs: hold a ref on the root in __btrfs_run_defrag_inode Josef Bacik
2020-01-24 14:32 ` [PATCH 14/44] btrfs: hold a ref on the root in fixup_tree_root_location Josef Bacik
2020-01-24 14:32 ` [PATCH 15/44] btrfs: hold a ref on the root in create_subvol Josef Bacik
2020-01-24 14:32 ` [PATCH 16/44] btrfs: hold a ref on the root in search_ioctl Josef Bacik
2020-01-24 14:32 ` [PATCH 17/44] btrfs: hold a ref on the root in btrfs_search_path_in_tree Josef Bacik
2020-02-05 14:30   ` David Sterba
2020-01-24 14:32 ` [PATCH 18/44] btrfs: hold a ref on the root in btrfs_search_path_in_tree_user Josef Bacik
2020-02-05 14:37   ` David Sterba
2020-01-24 14:32 ` [PATCH 19/44] btrfs: hold a ref on the root in btrfs_ioctl_get_subvol_info Josef Bacik
2020-01-24 14:32 ` [PATCH 20/44] btrfs: hold ref on root in btrfs_ioctl_default_subvol Josef Bacik
2020-01-24 14:32 ` [PATCH 21/44] btrfs: hold a ref on the root in build_backref_tree Josef Bacik
2020-02-05 14:46   ` David Sterba
2020-01-24 14:32 ` [PATCH 22/44] btrfs: hold a ref on the root in prepare_to_merge Josef Bacik
2020-02-05 14:52   ` David Sterba
2020-01-24 14:32 ` [PATCH 23/44] btrfs: hold a ref on the root in merge_reloc_roots Josef Bacik
2020-01-24 14:32 ` [PATCH 24/44] btrfs: hold a ref on the root in record_reloc_root_in_trans Josef Bacik
2020-01-24 14:32 ` [PATCH 25/44] btrfs: hold a ref on the root in find_data_references Josef Bacik
2020-01-24 14:32 ` [PATCH 26/44] btrfs: hold a ref on the root in create_reloc_inode Josef Bacik
2020-01-24 14:32 ` [PATCH 27/44] btrfs: hold a ref on the root in btrfs_recover_relocation Josef Bacik
2020-02-05 15:00   ` David Sterba
2020-02-06 16:26   ` David Sterba
2020-02-06 16:30     ` Josef Bacik
2020-01-24 14:32 ` [PATCH 28/44] btrfs: push grab_fs_root into read_fs_root Josef Bacik
2020-01-24 14:32 ` [PATCH 29/44] btrfs: hold a ref for the root in btrfs_find_orphan_roots Josef Bacik
2020-02-05 15:06   ` David Sterba
2020-01-24 14:32 ` [PATCH 30/44] btrfs: hold a ref on the root in scrub_print_warning_inode Josef Bacik
2020-01-24 14:32 ` [PATCH 31/44] btrfs: hold a ref on the root in btrfs_ioctl_send Josef Bacik
2020-02-05 15:16   ` David Sterba
2020-01-24 14:32 ` [PATCH 32/44] btrfs: hold a ref on the root in get_subvol_name_from_objectid Josef Bacik
2020-02-05 15:19   ` David Sterba
2020-02-06 15:24     ` [PATCH][v2] " Josef Bacik
2020-01-24 14:32 ` [PATCH 33/44] btrfs: hold a ref on the root in create_pending_snapshot Josef Bacik
2020-01-24 14:32 ` [PATCH 34/44] btrfs: hold a ref on the root in btrfs_recover_log_trees Josef Bacik
2020-01-24 14:32 ` [PATCH 35/44] btrfs: hold a ref on the root in btrfs_check_uuid_tree_entry Josef Bacik
2020-01-24 14:32 ` [PATCH 36/44] btrfs: move free_fs_info Josef Bacik
2020-01-24 14:52   ` Nikolay Borisov
2020-01-24 14:32 ` [PATCH 37/44] btrfs: hold a ref on the root in open_ctree Josef Bacik
2020-01-24 14:32 ` [PATCH 38/44] btrfs: use btrfs_put_fs_root to free roots always Josef Bacik
2020-01-24 14:32 ` [PATCH 39/44] btrfs: push btrfs_grab_fs_root into btrfs_get_fs_root Josef Bacik
2020-01-24 14:32 ` [PATCH 40/44] btrfs: free more things in btrfs_free_fs_info Josef Bacik
2020-01-24 14:32 ` [PATCH 41/44] btrfs: move fs_info init work into it's own helper function Josef Bacik
2020-01-24 14:32 ` [PATCH 42/44] btrfs: make the init of static elements in fs_info separate Josef Bacik
2020-01-24 14:33 ` [PATCH 43/44] btrfs: add a leak check for roots Josef Bacik
2020-01-24 14:33 ` [PATCH 44/44] btrfs: rename btrfs_put_fs_root and btrfs_grab_fs_root Josef Bacik
2020-02-05 15:44   ` David Sterba
2020-02-04 23:48 ` [PATCH 00/44][v5] Cleanup how we handle root refs, part 1 David Sterba
2020-02-05 15:48 ` David Sterba
2020-02-06 16:59   ` David Sterba
  -- strict thread matches above, loose matches on Subject: below --
2019-12-06 14:44 [PATCH 0/44] " Josef Bacik
2019-12-06 14:45 ` [PATCH 44/44] btrfs: rename btrfs_put_fs_root and btrfs_grab_fs_root Josef Bacik

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).