linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/6] btrfs-progs: Support for BG_TREE feature
@ 2018-12-28  8:38 Qu Wenruo
  2018-12-28  8:38 ` [PATCH 1/6] btrfs-progs: Refactor excluded extent functions to use fs_info Qu Wenruo
                   ` (6 more replies)
  0 siblings, 7 replies; 9+ messages in thread
From: Qu Wenruo @ 2018-12-28  8:38 UTC (permalink / raw)
  To: linux-btrfs

This patchset can be fetched from github:
https://github.com/adam900710/btrfs-progs/tree/bg_tree
The basis commit is:

commit 7d16a2b460182ee98c649533a6975b6e419c3d71
Author: Qu Wenruo <wqu@suse.com>
Date:   Thu Dec 27 13:49:18 2018 +0800

    btrfs-progs: Create uuid tree with proper contents

Which is further based on devel branch.

This patchset provides the needed user space infrastructure for BG_TREE
feature.

Since it's an new exclusive feature, unlike SKINNY_METADATA, btrfs-progs
is needed to convert existing fs (unmounted) to new format.

Although I have prepared the functionality, convert_to_bg_tree(), and
already uses it in mkfs, I haven't decided if I should put it under
btrfstune, as btrfstune isn't such offline convert tool.

If anyone has better idea on the new convert tool interface, I'm all
ears.

For the performance improvement, please check the kernel patchset cover
letter or the last patch.
(SPOILER ALERT: It's super fast)

Qu Wenruo (6):
  btrfs-progs: Refactor excluded extent functions to use fs_info
  btrfs-progs: Refactor btrfs_read_block_groups()
  btrfs-progs: Enable read-write ability for 'bg_tree' feature
  btrfs-progs: mkfs: Introduce -O bg-tree
  btrfs-progs: dump-tree/dump-super: Introduce support for bg tree
  btrfs-progs: check: Introduce support for bg-tree feature

 check/main.c              |   7 +-
 check/mode-lowmem.c       |   9 +-
 cmds-inspect-dump-super.c |   3 +-
 cmds-inspect-dump-tree.c  |   5 +
 ctree.h                   |  17 +-
 disk-io.c                 |  29 +++-
 extent-tree.c             | 326 +++++++++++++++++++++++++++-----------
 fsfeatures.c              |   6 +
 mkfs/common.c             |   7 +-
 mkfs/common.h             |   1 +
 mkfs/main.c               |  57 +++++++
 print-tree.c              |   3 +
 transaction.c             |   1 +
 13 files changed, 365 insertions(+), 106 deletions(-)

-- 
2.20.1


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

* [PATCH 1/6] btrfs-progs: Refactor excluded extent functions to use fs_info
  2018-12-28  8:38 [PATCH 0/6] btrfs-progs: Support for BG_TREE feature Qu Wenruo
@ 2018-12-28  8:38 ` Qu Wenruo
  2018-12-28  8:38 ` [PATCH 2/6] btrfs-progs: Refactor btrfs_read_block_groups() Qu Wenruo
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Qu Wenruo @ 2018-12-28  8:38 UTC (permalink / raw)
  To: linux-btrfs

The following functions are just using @root to reach fs_info:
- exclude_super_stripes
- free_excluded_extents
- add_excluded_extent

Refactor them to use fs_info directly.

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 check/main.c  |  4 ++--
 ctree.h       |  4 ++--
 extent-tree.c | 20 ++++++++++----------
 3 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/check/main.c b/check/main.c
index eb6a4a50db98..54ab146d0d13 100644
--- a/check/main.c
+++ b/check/main.c
@@ -5531,7 +5531,7 @@ static int check_space_cache(struct btrfs_root *root)
 		}
 
 		if (btrfs_fs_compat_ro(root->fs_info, FREE_SPACE_TREE)) {
-			ret = exclude_super_stripes(root, cache);
+			ret = exclude_super_stripes(root->fs_info, cache);
 			if (ret) {
 				errno = -ret;
 				fprintf(stderr,
@@ -5540,7 +5540,7 @@ static int check_space_cache(struct btrfs_root *root)
 				continue;
 			}
 			ret = load_free_space_tree(root->fs_info, cache);
-			free_excluded_extents(root, cache);
+			free_excluded_extents(root->fs_info, cache);
 			if (ret < 0) {
 				errno = -ret;
 				fprintf(stderr,
diff --git a/ctree.h b/ctree.h
index 6a10e5994a6b..7f332161de1d 100644
--- a/ctree.h
+++ b/ctree.h
@@ -2557,9 +2557,9 @@ int btrfs_record_file_extent(struct btrfs_trans_handle *trans,
 			      u64 num_bytes);
 int btrfs_free_block_group(struct btrfs_trans_handle *trans,
 			   struct btrfs_fs_info *fs_info, u64 bytenr, u64 len);
-void free_excluded_extents(struct btrfs_root *root,
+void free_excluded_extents(struct btrfs_fs_info *fs_info,
 			   struct btrfs_block_group_cache *cache);
-int exclude_super_stripes(struct btrfs_root *root,
+int exclude_super_stripes(struct btrfs_fs_info *fs_info,
 			  struct btrfs_block_group_cache *cache);
 u64 add_new_free_space(struct btrfs_block_group_cache *block_group,
 		       struct btrfs_fs_info *info, u64 start, u64 end);
diff --git a/extent-tree.c b/extent-tree.c
index 8c9cdeff3b02..2a8b278285e8 100644
--- a/extent-tree.c
+++ b/extent-tree.c
@@ -3116,7 +3116,7 @@ int btrfs_read_block_groups(struct btrfs_root *root)
 		if (btrfs_chunk_readonly(info, cache->key.objectid))
 			cache->ro = 1;
 
-		exclude_super_stripes(root, cache);
+		exclude_super_stripes(info, cache);
 
 		ret = update_space_info(info, cache->flags, found_key.offset,
 					btrfs_block_group_used(&cache->item),
@@ -3160,7 +3160,7 @@ btrfs_add_block_group(struct btrfs_fs_info *fs_info, u64 bytes_used, u64 type,
 	cache->flags = type;
 	btrfs_set_block_group_flags(&cache->item, type);
 
-	exclude_super_stripes(fs_info->extent_root, cache);
+	exclude_super_stripes(fs_info, cache);
 	ret = update_space_info(fs_info, cache->flags, size, bytes_used,
 				&cache->space_info);
 	BUG_ON(ret);
@@ -3951,16 +3951,16 @@ int btrfs_record_file_extent(struct btrfs_trans_handle *trans,
 }
 
 
-static int add_excluded_extent(struct btrfs_root *root,
+static int add_excluded_extent(struct btrfs_fs_info *fs_info,
 			       u64 start, u64 num_bytes)
 {
 	u64 end = start + num_bytes - 1;
-	set_extent_bits(&root->fs_info->pinned_extents,
+	set_extent_bits(&fs_info->pinned_extents,
 			start, end, EXTENT_UPTODATE);
 	return 0;
 }
 
-void free_excluded_extents(struct btrfs_root *root,
+void free_excluded_extents(struct btrfs_fs_info *fs_info,
 			   struct btrfs_block_group_cache *cache)
 {
 	u64 start, end;
@@ -3968,11 +3968,11 @@ void free_excluded_extents(struct btrfs_root *root,
 	start = cache->key.objectid;
 	end = start + cache->key.offset - 1;
 
-	clear_extent_bits(&root->fs_info->pinned_extents,
+	clear_extent_bits(&fs_info->pinned_extents,
 			  start, end, EXTENT_UPTODATE);
 }
 
-int exclude_super_stripes(struct btrfs_root *root,
+int exclude_super_stripes(struct btrfs_fs_info *fs_info,
 			  struct btrfs_block_group_cache *cache)
 {
 	u64 bytenr;
@@ -3983,7 +3983,7 @@ int exclude_super_stripes(struct btrfs_root *root,
 	if (cache->key.objectid < BTRFS_SUPER_INFO_OFFSET) {
 		stripe_len = BTRFS_SUPER_INFO_OFFSET - cache->key.objectid;
 		cache->bytes_super += stripe_len;
-		ret = add_excluded_extent(root, cache->key.objectid,
+		ret = add_excluded_extent(fs_info, cache->key.objectid,
 					  stripe_len);
 		if (ret)
 			return ret;
@@ -3991,7 +3991,7 @@ int exclude_super_stripes(struct btrfs_root *root,
 
 	for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) {
 		bytenr = btrfs_sb_offset(i);
-		ret = btrfs_rmap_block(root->fs_info,
+		ret = btrfs_rmap_block(fs_info,
 				       cache->key.objectid, bytenr,
 				       &logical, &nr, &stripe_len);
 		if (ret)
@@ -4018,7 +4018,7 @@ int exclude_super_stripes(struct btrfs_root *root,
 			}
 
 			cache->bytes_super += len;
-			ret = add_excluded_extent(root, start, len);
+			ret = add_excluded_extent(fs_info, start, len);
 			if (ret) {
 				kfree(logical);
 				return ret;
-- 
2.20.1


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

* [PATCH 2/6] btrfs-progs: Refactor btrfs_read_block_groups()
  2018-12-28  8:38 [PATCH 0/6] btrfs-progs: Support for BG_TREE feature Qu Wenruo
  2018-12-28  8:38 ` [PATCH 1/6] btrfs-progs: Refactor excluded extent functions to use fs_info Qu Wenruo
@ 2018-12-28  8:38 ` Qu Wenruo
  2018-12-28  8:38 ` [PATCH 3/6] btrfs-progs: Enable read-write ability for 'bg_tree' feature Qu Wenruo
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Qu Wenruo @ 2018-12-28  8:38 UTC (permalink / raw)
  To: linux-btrfs

This patch does the following refactor:
- Refactor parameter from @root to @fs_info

- Refactor the large loop body into another function
  Now we have a helper function, read_one_block_group(), to handle
  block group cache and space info related routine.

- Refactor the return value
  Even we have the code handling ret > 0 from find_first_block_group(),
  it never works, as when there is no more block group,
  find_first_block_group() just return -ENOENT other than 1.

  This is super confusing, it's almost a mircle it even works.

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 ctree.h       |   2 +-
 disk-io.c     |   9 ++-
 extent-tree.c | 160 ++++++++++++++++++++++++++++----------------------
 3 files changed, 97 insertions(+), 74 deletions(-)

diff --git a/ctree.h b/ctree.h
index 7f332161de1d..1288324d1afe 100644
--- a/ctree.h
+++ b/ctree.h
@@ -2539,7 +2539,7 @@ int btrfs_update_extent_ref(struct btrfs_trans_handle *trans,
 			    u64 owner_objectid);
 int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans);
 int btrfs_free_block_groups(struct btrfs_fs_info *info);
-int btrfs_read_block_groups(struct btrfs_root *root);
+int btrfs_read_block_groups(struct btrfs_fs_info *info);
 struct btrfs_block_group_cache *
 btrfs_add_block_group(struct btrfs_fs_info *fs_info, u64 bytes_used, u64 type,
 		      u64 chunk_offset, u64 size);
diff --git a/disk-io.c b/disk-io.c
index 89e2d9d7e1c0..34fa6a7edc50 100644
--- a/disk-io.c
+++ b/disk-io.c
@@ -943,14 +943,17 @@ int btrfs_setup_all_roots(struct btrfs_fs_info *fs_info, u64 root_tree_bytenr,
 	fs_info->last_trans_committed = generation;
 	if (extent_buffer_uptodate(fs_info->extent_root->node) &&
 	    !(flags & OPEN_CTREE_NO_BLOCK_GROUPS)) {
-		ret = btrfs_read_block_groups(fs_info->tree_root);
+		ret = btrfs_read_block_groups(fs_info);
 		/*
 		 * If we don't find any blockgroups (ENOENT) we're either
 		 * restoring or creating the filesystem, where it's expected,
 		 * anything else is error
 		 */
-		if (ret != -ENOENT)
-			return -EIO;
+		if (ret < 0 && ret != -ENOENT) {
+			errno = -ret;
+			error("failed to read block groups: %m");
+			return ret;
+		}
 	}
 
 	key.objectid = BTRFS_FS_TREE_OBJECTID;
diff --git a/extent-tree.c b/extent-tree.c
index 2a8b278285e8..262bdc952886 100644
--- a/extent-tree.c
+++ b/extent-tree.c
@@ -3007,6 +3007,13 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info)
 	return 0;
 }
 
+/*
+ * Find a block group which starts >= @key->objectid in extent tree.
+ *
+ * Return 0 for found
+ * Retrun >0 for not found
+ * Return <0 for error
+ */
 static int find_first_block_group(struct btrfs_root *root,
 		struct btrfs_path *path, struct btrfs_key *key)
 {
@@ -3036,36 +3043,95 @@ static int find_first_block_group(struct btrfs_root *root,
 			return 0;
 		path->slots[0]++;
 	}
-	ret = -ENOENT;
+	ret = 1;
 error:
 	return ret;
 }
 
-int btrfs_read_block_groups(struct btrfs_root *root)
+/*
+ * Helper function to read out one BLOCK_GROUP_ITEM and insert it into
+ * block group cache.
+ *
+ * Return 0 if nothing wrong (either insert the bg cache or skip 0 sized bg)
+ * Return <0 for error.
+ */
+static int read_one_block_group(struct btrfs_fs_info *fs_info,
+				 struct btrfs_path *path)
 {
-	struct btrfs_path *path;
-	int ret;
-	int bit;
-	struct btrfs_block_group_cache *cache;
-	struct btrfs_fs_info *info = root->fs_info;
+	struct extent_io_tree *block_group_cache = &fs_info->block_group_cache;
+	struct extent_buffer *leaf = path->nodes[0];
 	struct btrfs_space_info *space_info;
-	struct extent_io_tree *block_group_cache;
+	struct btrfs_block_group_cache *cache;
 	struct btrfs_key key;
-	struct btrfs_key found_key;
-	struct extent_buffer *leaf;
+	int slot = path->slots[0];
+	int bit = 0;
+	int ret;
 
-	block_group_cache = &info->block_group_cache;
+	btrfs_item_key_to_cpu(leaf, &key, slot);
+	ASSERT(key.type == BTRFS_BLOCK_GROUP_ITEM_KEY);
+
+	/*
+	 * Skip 0 sized block group, don't insert them into block
+	 * group cache tree, as its length is 0, it won't get
+	 * freed at close_ctree() time.
+	 */
+	if (key.offset == 0)
+		return 0;
+
+	cache = kzalloc(sizeof(*cache), GFP_NOFS);
+	if (!cache)
+		return -ENOMEM;
+	read_extent_buffer(leaf, &cache->item,
+			   btrfs_item_ptr_offset(leaf, slot),
+			   sizeof(cache->item));
+	memcpy(&cache->key, &key, sizeof(key));
+	cache->cached = 0;
+	cache->pinned = 0;
+	cache->flags = btrfs_block_group_flags(&cache->item);
+	if (cache->flags & BTRFS_BLOCK_GROUP_DATA) {
+		bit = BLOCK_GROUP_DATA;
+	} else if (cache->flags & BTRFS_BLOCK_GROUP_SYSTEM) {
+		bit = BLOCK_GROUP_SYSTEM;
+	} else if (cache->flags & BTRFS_BLOCK_GROUP_METADATA) {
+		bit = BLOCK_GROUP_METADATA;
+	}
+	set_avail_alloc_bits(fs_info, cache->flags);
+	if (btrfs_chunk_readonly(fs_info, cache->key.objectid))
+		cache->ro = 1;
+	exclude_super_stripes(fs_info, cache);
+
+	ret = update_space_info(fs_info, cache->flags, cache->key.offset,
+				btrfs_block_group_used(&cache->item),
+				&space_info);
+	if (ret < 0) {
+		free(cache);
+		return ret;
+	}
+	cache->space_info = space_info;
+
+	set_extent_bits(block_group_cache, cache->key.objectid,
+			cache->key.objectid + cache->key.offset - 1,
+			bit | EXTENT_LOCKED);
+	set_state_private(block_group_cache, cache->key.objectid,
+			  (unsigned long)cache);
+	return 0;
+}
 
-	root = info->extent_root;
+int btrfs_read_block_groups(struct btrfs_fs_info *fs_info)
+{
+	struct btrfs_path path;
+	struct btrfs_root *root;
+	int ret;
+	struct btrfs_key key;
+
+	root = fs_info->extent_root;
 	key.objectid = 0;
 	key.offset = 0;
 	key.type = BTRFS_BLOCK_GROUP_ITEM_KEY;
-	path = btrfs_alloc_path();
-	if (!path)
-		return -ENOMEM;
+	btrfs_init_path(&path);
 
 	while(1) {
-		ret = find_first_block_group(root, path, &key);
+		ret = find_first_block_group(root, &path, &key);
 		if (ret > 0) {
 			ret = 0;
 			goto error;
@@ -3073,67 +3139,21 @@ int btrfs_read_block_groups(struct btrfs_root *root)
 		if (ret != 0) {
 			goto error;
 		}
-		leaf = path->nodes[0];
-		btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
+		btrfs_item_key_to_cpu(path.nodes[0], &key, path.slots[0]);
 
-		cache = kzalloc(sizeof(*cache), GFP_NOFS);
-		if (!cache) {
-			ret = -ENOMEM;
+		ret = read_one_block_group(fs_info, &path);
+		if (ret < 0)
 			goto error;
-		}
 
-		read_extent_buffer(leaf, &cache->item,
-				   btrfs_item_ptr_offset(leaf, path->slots[0]),
-				   sizeof(cache->item));
-		memcpy(&cache->key, &found_key, sizeof(found_key));
-		cache->cached = 0;
-		cache->pinned = 0;
-		key.objectid = found_key.objectid + found_key.offset;
-		if (found_key.offset == 0)
+		if (key.offset == 0)
 			key.objectid++;
-		btrfs_release_path(path);
-
-		/*
-		 * Skip 0 sized block group, don't insert them into block
-		 * group cache tree, as its length is 0, it won't get
-		 * freed at close_ctree() time.
-		 */
-		if (found_key.offset == 0) {
-			free(cache);
-			continue;
-		}
-
-		cache->flags = btrfs_block_group_flags(&cache->item);
-		bit = 0;
-		if (cache->flags & BTRFS_BLOCK_GROUP_DATA) {
-			bit = BLOCK_GROUP_DATA;
-		} else if (cache->flags & BTRFS_BLOCK_GROUP_SYSTEM) {
-			bit = BLOCK_GROUP_SYSTEM;
-		} else if (cache->flags & BTRFS_BLOCK_GROUP_METADATA) {
-			bit = BLOCK_GROUP_METADATA;
-		}
-		set_avail_alloc_bits(info, cache->flags);
-		if (btrfs_chunk_readonly(info, cache->key.objectid))
-			cache->ro = 1;
-
-		exclude_super_stripes(info, cache);
-
-		ret = update_space_info(info, cache->flags, found_key.offset,
-					btrfs_block_group_used(&cache->item),
-					&space_info);
-		BUG_ON(ret);
-		cache->space_info = space_info;
-
-		/* use EXTENT_LOCKED to prevent merging */
-		set_extent_bits(block_group_cache, found_key.objectid,
-				found_key.objectid + found_key.offset - 1,
-				bit | EXTENT_LOCKED);
-		set_state_private(block_group_cache, found_key.objectid,
-				  (unsigned long)cache);
+		else
+			key.objectid = key.objectid + key.offset;
+		btrfs_release_path(&path);
 	}
 	ret = 0;
 error:
-	btrfs_free_path(path);
+	btrfs_release_path(&path);
 	return ret;
 }
 
-- 
2.20.1


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

* [PATCH 3/6] btrfs-progs: Enable read-write ability for 'bg_tree' feature
  2018-12-28  8:38 [PATCH 0/6] btrfs-progs: Support for BG_TREE feature Qu Wenruo
  2018-12-28  8:38 ` [PATCH 1/6] btrfs-progs: Refactor excluded extent functions to use fs_info Qu Wenruo
  2018-12-28  8:38 ` [PATCH 2/6] btrfs-progs: Refactor btrfs_read_block_groups() Qu Wenruo
@ 2018-12-28  8:38 ` Qu Wenruo
  2018-12-28  8:38 ` [PATCH 4/6] btrfs-progs: mkfs: Introduce -O bg-tree Qu Wenruo
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Qu Wenruo @ 2018-12-28  8:38 UTC (permalink / raw)
  To: linux-btrfs

Allow btrfs-progs to open, read and write 'bg_tree' enabled fs.

The modification itself is not large, as block groups items are only
used at 4 timing:
1) open_ctree()
   We only need to populate fs_info->bg_root and read block group items
   from fs_info->bg_root.
   The obvious change is, we don't need to do btrfs_search_slot() for
   each block group item, but btrfs_next_item() is enough.

   This should hugely reduce open_ctree() execution duration.

2) btrfs_commit_transaction()
   We need to write back dirty block group items back to bg_root.

   The modification here is to insert new block group item if we can't
   find one existing in bg_root, and delete the old one in extent tree
   if we're converting to bg_tree feature.

3) btrfs_make_block_group()
   Just change @root for btrfs_insert_item() from @extent_root to
   @bg_root for fs with that feature.

   This modification needs extra handling for converting case, where
   block group items can be either in extent tree or bg tree.

4) free_block_group_item()
   Just delete the block group item in extent tree.

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 ctree.h       |  11 +++-
 disk-io.c     |  20 +++++++
 extent-tree.c | 152 +++++++++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 168 insertions(+), 15 deletions(-)

diff --git a/ctree.h b/ctree.h
index 1288324d1afe..4d4da99dbfa5 100644
--- a/ctree.h
+++ b/ctree.h
@@ -91,6 +91,9 @@ struct btrfs_free_space_ctl;
 /* tracks free space in block groups. */
 #define BTRFS_FREE_SPACE_TREE_OBJECTID 10ULL
 
+/* store BLOCK_GROUP_ITEMS in a seperate tree */
+#define BTRFS_BLOCK_GROUP_TREE_OBJECTID 11ULL
+
 /* device stats in the device tree */
 #define BTRFS_DEV_STATS_OBJECTID 0ULL
 
@@ -492,6 +495,7 @@ struct btrfs_super_block {
 #define BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA	(1ULL << 8)
 #define BTRFS_FEATURE_INCOMPAT_NO_HOLES		(1ULL << 9)
 #define BTRFS_FEATURE_INCOMPAT_METADATA_UUID    (1ULL << 10)
+#define BTRFS_FEATURE_INCOMPAT_BG_TREE		(1ULL << 11)
 
 #define BTRFS_FEATURE_COMPAT_SUPP		0ULL
 
@@ -515,7 +519,8 @@ struct btrfs_super_block {
 	 BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS |		\
 	 BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA |	\
 	 BTRFS_FEATURE_INCOMPAT_NO_HOLES |		\
-	 BTRFS_FEATURE_INCOMPAT_METADATA_UUID)
+	 BTRFS_FEATURE_INCOMPAT_METADATA_UUID |		\
+	 BTRFS_FEATURE_INCOMPAT_BG_TREE)
 
 /*
  * A leaf is full of items. offset and size tell us where to find
@@ -1104,6 +1109,7 @@ struct btrfs_fs_info {
 	struct btrfs_root *quota_root;
 	struct btrfs_root *free_space_root;
 	struct btrfs_root *uuid_root;
+	struct btrfs_root *bg_root;
 
 	struct rb_root fs_root_tree;
 
@@ -1156,6 +1162,9 @@ struct btrfs_fs_info {
 	unsigned int avoid_sys_chunk_alloc:1;
 	unsigned int finalize_on_close:1;
 
+	/* Converting from bg in extent tree to bg tree */
+	unsigned int convert_to_bg_tree:1;
+
 	int transaction_aborted;
 
 	int (*free_extent_hook)(struct btrfs_fs_info *fs_info,
diff --git a/disk-io.c b/disk-io.c
index 34fa6a7edc50..309aa881c373 100644
--- a/disk-io.c
+++ b/disk-io.c
@@ -686,6 +686,8 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info,
 	if (location->objectid == BTRFS_FREE_SPACE_TREE_OBJECTID)
 		return fs_info->free_space_root ? fs_info->free_space_root :
 						ERR_PTR(-ENOENT);
+	if (location->objectid == BTRFS_BLOCK_GROUP_TREE_OBJECTID)
+		return fs_info->bg_root ? fs_info->bg_root : ERR_PTR(-ENOENT);
 
 	BUG_ON(location->objectid == BTRFS_TREE_RELOC_OBJECTID ||
 	       location->offset != (u64)-1);
@@ -738,6 +740,7 @@ struct btrfs_fs_info *btrfs_new_fs_info(int writable, u64 sb_bytenr)
 	fs_info->csum_root = calloc(1, sizeof(struct btrfs_root));
 	fs_info->quota_root = calloc(1, sizeof(struct btrfs_root));
 	fs_info->free_space_root = calloc(1, sizeof(struct btrfs_root));
+	fs_info->bg_root = calloc(1, sizeof(struct btrfs_root));
 	fs_info->super_copy = calloc(1, BTRFS_SUPER_INFO_SIZE);
 
 	if (!fs_info->tree_root || !fs_info->extent_root ||
@@ -899,6 +902,21 @@ int btrfs_setup_all_roots(struct btrfs_fs_info *fs_info, u64 root_tree_bytenr,
 		return ret;
 	fs_info->extent_root->track_dirty = 1;
 
+	if (btrfs_fs_incompat(fs_info, BG_TREE)) {
+		ret = setup_root_or_create_block(fs_info, flags,
+					fs_info->bg_root,
+					BTRFS_BLOCK_GROUP_TREE_OBJECTID, "bg");
+		if (ret < 0) {
+			error("Couldn't setup bg tree");
+			return ret;
+		}
+		fs_info->bg_root->track_dirty = 1;
+		fs_info->bg_root->ref_cows = 0;
+	} else {
+		free(fs_info->bg_root);
+		fs_info->bg_root = NULL;
+	}
+
 	ret = find_and_setup_root(root, fs_info, BTRFS_DEV_TREE_OBJECTID,
 				  fs_info->dev_root);
 	if (ret) {
@@ -972,6 +990,8 @@ void btrfs_release_all_roots(struct btrfs_fs_info *fs_info)
 		free_extent_buffer(fs_info->free_space_root->node);
 	if (fs_info->quota_root)
 		free_extent_buffer(fs_info->quota_root->node);
+	if (fs_info->bg_root)
+		free_extent_buffer(fs_info->bg_root->node);
 	if (fs_info->csum_root)
 		free_extent_buffer(fs_info->csum_root->node);
 	if (fs_info->dev_root)
diff --git a/extent-tree.c b/extent-tree.c
index 262bdc952886..a7ed501be29e 100644
--- a/extent-tree.c
+++ b/extent-tree.c
@@ -1684,22 +1684,68 @@ static int write_one_cache_group(struct btrfs_trans_handle *trans,
 				 struct btrfs_path *path,
 				 struct btrfs_block_group_cache *cache)
 {
+	bool is_bg_tree = btrfs_fs_incompat(trans->fs_info, BG_TREE);
 	int ret;
-	struct btrfs_root *extent_root = trans->fs_info->extent_root;
+	struct btrfs_fs_info *fs_info = trans->fs_info;
+	struct btrfs_root *root;
 	unsigned long bi;
 	struct extent_buffer *leaf;
 
-	ret = btrfs_search_slot(trans, extent_root, &cache->key, path, 0, 1);
+	if (is_bg_tree)
+		root = fs_info->bg_root;
+	else
+		root = fs_info->extent_root;
+
+	ret = btrfs_search_slot(trans, root, &cache->key, path, 0, 1);
 	if (ret < 0)
-		goto fail;
-	BUG_ON(ret);
+		goto out;
 
-	leaf = path->nodes[0];
-	bi = btrfs_item_ptr_offset(leaf, path->slots[0]);
-	write_extent_buffer(leaf, &cache->item, bi, sizeof(cache->item));
-	btrfs_mark_buffer_dirty(leaf);
-	btrfs_release_path(path);
-fail:
+	if (ret == 0) {
+		/* Update existing bg */
+		leaf = path->nodes[0];
+		bi = btrfs_item_ptr_offset(leaf, path->slots[0]);
+		write_extent_buffer(leaf, &cache->item, bi, sizeof(cache->item));
+		btrfs_mark_buffer_dirty(leaf);
+		btrfs_release_path(path);
+	} else {
+		btrfs_release_path(path);
+
+		/*
+		 * Insert new bg item
+		 *
+		 * This only happens for bg_tree feature
+		 */
+		if (!is_bg_tree) {
+			error("can't find block group item for bytenr %llu",
+			      cache->key.objectid);
+			ret = -ENOENT;
+			goto out;
+		}
+		ret = btrfs_insert_item(trans, root, &cache->key, &cache->item,
+					sizeof(cache->item));
+		if (ret < 0)
+			goto out;
+
+		/* Also delete the existing one in next tree if needed */
+		if (fs_info->convert_to_bg_tree) {
+			ret = btrfs_search_slot(trans, fs_info->extent_root,
+						&cache->key, path, -1, 1);
+			if (ret < 0) {
+				btrfs_release_path(path);
+				goto out;
+			}
+			/* Good, already converted */
+			if (ret > 0) {
+				ret = 0;
+				btrfs_release_path(path);
+				goto out;
+			}
+			/* Delete old block group item in extent tree */
+			ret = btrfs_del_item(trans, fs_info->extent_root, path);
+			btrfs_release_path(path);
+		}
+	}
+out:
 	if (ret)
 		return ret;
 	return 0;
@@ -3117,14 +3163,66 @@ static int read_one_block_group(struct btrfs_fs_info *fs_info,
 	return 0;
 }
 
+static int read_block_group_tree(struct btrfs_fs_info *fs_info)
+{
+	struct btrfs_root *root = fs_info->bg_root;
+	struct btrfs_key key = { 0 };
+	struct btrfs_path path;
+	int ret;
+
+	btrfs_init_path(&path);
+	ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0);
+	if (ret < 0) {
+		errno = -ret;
+		error("failed to search block group tree: %m");
+		return ret;
+	}
+	if (ret == 0)
+		goto invalid_key;
+
+	while (1) {
+		btrfs_item_key_to_cpu(path.nodes[0], &key, path.slots[0]);
+		if (key.type != BTRFS_BLOCK_GROUP_ITEM_KEY)
+			goto invalid_key;
+
+		ret = read_one_block_group(fs_info, &path);
+		if (ret < 0) {
+			errno = -ret;
+			error("failed to read one block group: %m");
+			goto out;
+		}
+		ret = btrfs_next_item(root, &path);
+		if (ret < 0) {
+			errno = -ret;
+			error("failed to search block group tree: %m");
+			goto out;
+		}
+		if (ret > 0) {
+			ret = 0;
+			break;
+		}
+	}
+out:
+	btrfs_release_path(&path);
+	return ret;
+
+invalid_key:
+	error("invalid key (%llu, %u, %llu) found in block group tree",
+	      key.objectid, key.type, key.offset);
+	btrfs_release_path(&path);
+	return -EUCLEAN;
+}
+
 int btrfs_read_block_groups(struct btrfs_fs_info *fs_info)
 {
 	struct btrfs_path path;
-	struct btrfs_root *root;
+	struct btrfs_root *root = fs_info->extent_root;
 	int ret;
 	struct btrfs_key key;
 
-	root = fs_info->extent_root;
+	if (btrfs_fs_incompat(fs_info, BG_TREE))
+		return read_block_group_tree(fs_info);
+
 	key.objectid = 0;
 	key.offset = 0;
 	key.type = BTRFS_BLOCK_GROUP_ITEM_KEY;
@@ -3204,12 +3302,17 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans,
 			   u64 type, u64 chunk_offset, u64 size)
 {
 	int ret;
-	struct btrfs_root *extent_root = fs_info->extent_root;
+	struct btrfs_root *root;
 	struct btrfs_block_group_cache *cache;
 
+	if (btrfs_fs_incompat(fs_info, BG_TREE))
+		root = fs_info->bg_root;
+	else
+		root = fs_info->extent_root;
+
 	cache = btrfs_add_block_group(fs_info, bytes_used, type, chunk_offset,
 				      size);
-	ret = btrfs_insert_item(trans, extent_root, &cache->key, &cache->item,
+	ret = btrfs_insert_item(trans, root, &cache->key, &cache->item,
 				sizeof(cache->item));
 	BUG_ON(ret);
 
@@ -3343,8 +3446,16 @@ static int free_block_group_item(struct btrfs_trans_handle *trans,
 	if (!path)
 		return -ENOMEM;
 
+	/* Using bg tree only */
+	if (btrfs_fs_incompat(fs_info, BG_TREE) && !fs_info->convert_to_bg_tree)
+		goto bg_tree;
+
 	ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
 	if (ret > 0) {
+		if (btrfs_fs_incompat(fs_info, BG_TREE)) {
+			btrfs_release_path(path);
+			goto bg_tree;
+		}
 		ret = -ENOENT;
 		goto out;
 	}
@@ -3352,6 +3463,19 @@ static int free_block_group_item(struct btrfs_trans_handle *trans,
 		goto out;
 
 	ret = btrfs_del_item(trans, root, path);
+	goto out;
+
+bg_tree:
+	root = fs_info->bg_root;
+	ret = btrfs_search_slot(trans, fs_info->bg_root, &key, path, -1, 1);
+	if (ret < 0)
+		goto out;
+	if (ret > 0) {
+		ret = -ENOENT;
+		goto out;
+	}
+	ret = btrfs_del_item(trans, root, path);
+
 out:
 	btrfs_free_path(path);
 	return ret;
-- 
2.20.1


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

* [PATCH 4/6] btrfs-progs: mkfs: Introduce -O bg-tree
  2018-12-28  8:38 [PATCH 0/6] btrfs-progs: Support for BG_TREE feature Qu Wenruo
                   ` (2 preceding siblings ...)
  2018-12-28  8:38 ` [PATCH 3/6] btrfs-progs: Enable read-write ability for 'bg_tree' feature Qu Wenruo
@ 2018-12-28  8:38 ` Qu Wenruo
  2018-12-28  8:38 ` [PATCH 5/6] btrfs-progs: dump-tree/dump-super: Introduce support for bg tree Qu Wenruo
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Qu Wenruo @ 2018-12-28  8:38 UTC (permalink / raw)
  To: linux-btrfs

This allow mkfs.btrfs to create a btrfs with bg-tree feature.

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 fsfeatures.c  |  6 ++++++
 mkfs/common.c |  7 +++++--
 mkfs/common.h |  1 +
 mkfs/main.c   | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++
 transaction.c |  1 +
 5 files changed, 70 insertions(+), 2 deletions(-)

diff --git a/fsfeatures.c b/fsfeatures.c
index 13ad030870cd..6458253f05ff 100644
--- a/fsfeatures.c
+++ b/fsfeatures.c
@@ -86,6 +86,12 @@ static const struct btrfs_fs_feature {
 		VERSION_TO_STRING2(4,0),
 		NULL, 0,
 		"no explicit hole extents for files" },
+	{ "bg-tree", BTRFS_FEATURE_INCOMPAT_BG_TREE,
+		"bg_tree",
+		VERSION_TO_STRING2(5, 0),
+		NULL, 0,
+		NULL, 0,
+		"store block group items in dedicated tree" },
 	/* Keep this one last */
 	{ "list-all", BTRFS_FEATURE_LIST_ALL, NULL }
 };
diff --git a/mkfs/common.c b/mkfs/common.c
index 1f5e1d03a6e3..2916ab3035f5 100644
--- a/mkfs/common.c
+++ b/mkfs/common.c
@@ -110,6 +110,9 @@ static int btrfs_create_tree_root(int fd, struct btrfs_mkfs_config *cfg,
 	return ret;
 }
 
+/* These features will not be set in the temporary fs */
+#define MASKED_FEATURES		(~(BTRFS_FEATURE_INCOMPAT_BG_TREE))
+
 /*
  * @fs_uuid - if NULL, generates a UUID, returns back the new filesystem UUID
  *
@@ -203,7 +206,7 @@ int make_btrfs(int fd, struct btrfs_mkfs_config *cfg)
 	btrfs_set_super_csum_type(&super, BTRFS_CSUM_TYPE_CRC32);
 	btrfs_set_super_chunk_root_generation(&super, 1);
 	btrfs_set_super_cache_generation(&super, -1);
-	btrfs_set_super_incompat_flags(&super, cfg->features);
+	btrfs_set_super_incompat_flags(&super, cfg->features & MASKED_FEATURES);
 	if (cfg->label)
 		__strncpy_null(super.label, cfg->label, BTRFS_LABEL_SIZE - 1);
 
@@ -868,7 +871,7 @@ static int __create_tree(struct btrfs_trans_handle *trans,
  *
  * Caller must ensure at the time of calling, csum tree is still empty
  */
-static int create_empty_tree(struct btrfs_trans_handle *trans, u64 objectid)
+int create_empty_tree(struct btrfs_trans_handle *trans, u64 objectid)
 {
 	struct btrfs_root *csum_root = trans->fs_info->csum_root;
 
diff --git a/mkfs/common.h b/mkfs/common.h
index adb5d561c38d..dfb82f9c84a3 100644
--- a/mkfs/common.h
+++ b/mkfs/common.h
@@ -75,6 +75,7 @@ int test_num_disk_vs_raid(u64 metadata_profile, u64 data_profile,
 int test_status_for_mkfs(const char *file, bool force_overwrite);
 int test_dev_for_mkfs(const char *file, int force_overwrite);
 
+int create_empty_tree(struct btrfs_trans_handle *trans, u64 objectid);
 int create_uuid_tree(struct btrfs_trans_handle *trans);
 int create_inode_tree(struct btrfs_trans_handle *trans, u64 objectid);
 
diff --git a/mkfs/main.c b/mkfs/main.c
index ea3d1ae80e5e..62f6a0115f91 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -677,6 +677,54 @@ static void update_chunk_allocation(struct btrfs_fs_info *fs_info,
 	}
 }
 
+/* Helper to convert to bg_tree feature */
+static int convert_to_bg_tree(struct btrfs_trans_handle *trans)
+{
+	struct btrfs_fs_info *fs_info = trans->fs_info;
+	struct btrfs_block_group_cache *bg;
+	struct btrfs_root *bg_root;
+	struct btrfs_key key;
+	u64 features = btrfs_super_incompat_flags(fs_info->super_copy);
+	int ret;
+
+	/* create bg tree first */
+	ret = create_empty_tree(trans, BTRFS_BLOCK_GROUP_TREE_OBJECTID);
+	if (ret < 0) {
+		errno = -ret;
+		error("failed to create bg tree: %m");
+		return ret;
+	}
+	key.objectid = BTRFS_BLOCK_GROUP_TREE_OBJECTID;
+	key.type = BTRFS_ROOT_ITEM_KEY;
+	key.offset = 0;
+	bg_root = btrfs_read_fs_root_no_cache(fs_info, &key);
+	if (IS_ERR(bg_root)) {
+		errno = -PTR_ERR(bg_root);
+		error("failed to read bg root: %m");
+		return PTR_ERR(bg_root);
+	}
+	fs_info->bg_root = bg_root;
+	fs_info->bg_root->track_dirty = 1;
+	fs_info->bg_root->ref_cows = 0;
+
+	/* set BG_TREE feature and mark the fs into bg_tree convert status */
+	btrfs_set_super_incompat_flags(fs_info->super_copy,
+			features | BTRFS_FEATURE_INCOMPAT_BG_TREE);
+	fs_info->convert_to_bg_tree = 1;
+
+	/*
+	 * Mark all block groups dirty so they will get converted to bg tree at
+	 * commit transaction time
+	 */
+	for (bg = btrfs_lookup_first_block_group(fs_info, 0); bg;
+	     bg = btrfs_lookup_first_block_group(fs_info,
+				bg->key.objectid + bg->key.offset))
+		set_extent_bits(&fs_info->block_group_cache, bg->key.objectid,
+				bg->key.objectid + bg->key.offset - 1,
+				BLOCK_GROUP_DIRTY);
+	return 0;
+}
+
 int main(int argc, char **argv)
 {
 	char *file;
@@ -1182,6 +1230,15 @@ raid_groups:
 		warning(
 	"unable to create uuid tree, will be created after mount: %d", ret);
 
+	/* Bg tree are converted after the fs is created */
+	if (mkfs_cfg.features & BTRFS_FEATURE_INCOMPAT_BG_TREE) {
+		ret = convert_to_bg_tree(trans);
+		if (ret < 0) {
+			errno = -ret;
+			error(
+		"bg-tree feature will not be enabled, due to error: %m");
+		}
+	}
 	ret = btrfs_commit_transaction(trans, root);
 	if (ret) {
 		error("unable to commit transaction: %d", ret);
diff --git a/transaction.c b/transaction.c
index e756db332fec..3c07f589d670 100644
--- a/transaction.c
+++ b/transaction.c
@@ -205,6 +205,7 @@ commit_tree:
 	root->commit_root = NULL;
 	fs_info->running_transaction = NULL;
 	fs_info->last_trans_committed = transid;
+	fs_info->convert_to_bg_tree = 0;
 out:
 	return ret;
 }
-- 
2.20.1


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

* [PATCH 5/6] btrfs-progs: dump-tree/dump-super: Introduce support for bg tree
  2018-12-28  8:38 [PATCH 0/6] btrfs-progs: Support for BG_TREE feature Qu Wenruo
                   ` (3 preceding siblings ...)
  2018-12-28  8:38 ` [PATCH 4/6] btrfs-progs: mkfs: Introduce -O bg-tree Qu Wenruo
@ 2018-12-28  8:38 ` Qu Wenruo
  2018-12-28  8:38 ` [PATCH 6/6] btrfs-progs: check: Introduce support for bg-tree feature Qu Wenruo
  2019-02-25 16:36 ` [PATCH 0/6] btrfs-progs: Support for BG_TREE feature Hans van Kranenburg
  6 siblings, 0 replies; 9+ messages in thread
From: Qu Wenruo @ 2018-12-28  8:38 UTC (permalink / raw)
  To: linux-btrfs

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 cmds-inspect-dump-super.c | 3 ++-
 cmds-inspect-dump-tree.c  | 5 +++++
 print-tree.c              | 3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/cmds-inspect-dump-super.c b/cmds-inspect-dump-super.c
index 97e9624db8d7..4550a38e59fe 100644
--- a/cmds-inspect-dump-super.c
+++ b/cmds-inspect-dump-super.c
@@ -229,7 +229,8 @@ static struct readable_flag_entry incompat_flags_array[] = {
 	DEF_INCOMPAT_FLAG_ENTRY(RAID56),
 	DEF_INCOMPAT_FLAG_ENTRY(SKINNY_METADATA),
 	DEF_INCOMPAT_FLAG_ENTRY(NO_HOLES),
-	DEF_INCOMPAT_FLAG_ENTRY(METADATA_UUID)
+	DEF_INCOMPAT_FLAG_ENTRY(METADATA_UUID),
+	DEF_INCOMPAT_FLAG_ENTRY(BG_TREE)
 };
 static const int incompat_flags_num = sizeof(incompat_flags_array) /
 				      sizeof(struct readable_flag_entry);
diff --git a/cmds-inspect-dump-tree.c b/cmds-inspect-dump-tree.c
index ad5345b4f1db..0e96acded90a 100644
--- a/cmds-inspect-dump-tree.c
+++ b/cmds-inspect-dump-tree.c
@@ -148,6 +148,7 @@ static u64 treeid_from_string(const char *str, const char **end)
 		{ "CSUM", BTRFS_CSUM_TREE_OBJECTID },
 		{ "CHECKSUM", BTRFS_CSUM_TREE_OBJECTID },
 		{ "QUOTA", BTRFS_QUOTA_TREE_OBJECTID },
+		{ "BG", BTRFS_BLOCK_GROUP_TREE_OBJECTID },
 		{ "UUID", BTRFS_UUID_TREE_OBJECTID },
 		{ "FREE_SPACE", BTRFS_FREE_SPACE_TREE_OBJECTID },
 		{ "TREE_LOG_FIXUP", BTRFS_TREE_LOG_FIXUP_OBJECTID },
@@ -559,6 +560,10 @@ again:
 				if (!skip)
 					printf("free space");
 				break;
+			case BTRFS_BLOCK_GROUP_TREE_OBJECTID:
+				if (!skip)
+					printf("block group");
+				break;
 			case BTRFS_MULTIPLE_OBJECTIDS:
 				if (!skip) {
 					printf("multiple");
diff --git a/print-tree.c b/print-tree.c
index ab77463706c1..3e61b5254a1f 100644
--- a/print-tree.c
+++ b/print-tree.c
@@ -790,6 +790,9 @@ void print_objectid(FILE *stream, u64 objectid, u8 type)
 	case BTRFS_FREE_SPACE_TREE_OBJECTID:
 		fprintf(stream, "FREE_SPACE_TREE");
 		break;
+	case BTRFS_BLOCK_GROUP_TREE_OBJECTID:
+		fprintf(stream, "BLOCK_GROUP_TREE");
+		break;
 	case BTRFS_MULTIPLE_OBJECTIDS:
 		fprintf(stream, "MULTIPLE");
 		break;
-- 
2.20.1


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

* [PATCH 6/6] btrfs-progs: check: Introduce support for bg-tree feature
  2018-12-28  8:38 [PATCH 0/6] btrfs-progs: Support for BG_TREE feature Qu Wenruo
                   ` (4 preceding siblings ...)
  2018-12-28  8:38 ` [PATCH 5/6] btrfs-progs: dump-tree/dump-super: Introduce support for bg tree Qu Wenruo
@ 2018-12-28  8:38 ` Qu Wenruo
  2019-02-25 16:36 ` [PATCH 0/6] btrfs-progs: Support for BG_TREE feature Hans van Kranenburg
  6 siblings, 0 replies; 9+ messages in thread
From: Qu Wenruo @ 2018-12-28  8:38 UTC (permalink / raw)
  To: linux-btrfs

For original mode BLOCK_GROUP_ITEM can occur in bg tree.

For lowmem mode just check BLOCK_GROUP_ITEM in bg tree if the that
feature is set.

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 check/main.c        | 3 ++-
 check/mode-lowmem.c | 9 +++++++--
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/check/main.c b/check/main.c
index 54ab146d0d13..255f762db3c3 100644
--- a/check/main.c
+++ b/check/main.c
@@ -6013,7 +6013,8 @@ static int check_type_with_root(u64 rootid, u8 key_type)
 	case BTRFS_EXTENT_ITEM_KEY:
 	case BTRFS_METADATA_ITEM_KEY:
 	case BTRFS_BLOCK_GROUP_ITEM_KEY:
-		if (rootid != BTRFS_EXTENT_TREE_OBJECTID)
+		if (rootid != BTRFS_EXTENT_TREE_OBJECTID &&
+		    rootid != BTRFS_BLOCK_GROUP_TREE_OBJECTID)
 			goto err;
 		break;
 	case BTRFS_ROOT_ITEM_KEY:
diff --git a/check/mode-lowmem.c b/check/mode-lowmem.c
index 7bb079a98ea9..acfffe1fef87 100644
--- a/check/mode-lowmem.c
+++ b/check/mode-lowmem.c
@@ -4229,7 +4229,7 @@ next:
 static int check_chunk_item(struct btrfs_fs_info *fs_info,
 			    struct extent_buffer *eb, int slot)
 {
-	struct btrfs_root *extent_root = fs_info->extent_root;
+	struct btrfs_root *root;
 	struct btrfs_root *dev_root = fs_info->dev_root;
 	struct btrfs_path path;
 	struct btrfs_key chunk_key;
@@ -4251,6 +4251,11 @@ static int check_chunk_item(struct btrfs_fs_info *fs_info,
 	int ret;
 	int err = 0;
 
+	if (btrfs_fs_incompat(fs_info, BG_TREE))
+		root = fs_info->bg_root;
+	else
+		root = fs_info->extent_root;
+
 	btrfs_item_key_to_cpu(eb, &chunk_key, slot);
 	chunk = btrfs_item_ptr(eb, slot, struct btrfs_chunk);
 	length = btrfs_chunk_length(eb, chunk);
@@ -4270,7 +4275,7 @@ static int check_chunk_item(struct btrfs_fs_info *fs_info,
 	bg_key.offset = length;
 
 	btrfs_init_path(&path);
-	ret = btrfs_search_slot(NULL, extent_root, &bg_key, &path, 0, 0);
+	ret = btrfs_search_slot(NULL, root, &bg_key, &path, 0, 0);
 	if (ret) {
 		error(
 		"chunk[%llu %llu) did not find the related block group item",
-- 
2.20.1


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

* Re: [PATCH 0/6] btrfs-progs: Support for BG_TREE feature
  2018-12-28  8:38 [PATCH 0/6] btrfs-progs: Support for BG_TREE feature Qu Wenruo
                   ` (5 preceding siblings ...)
  2018-12-28  8:38 ` [PATCH 6/6] btrfs-progs: check: Introduce support for bg-tree feature Qu Wenruo
@ 2019-02-25 16:36 ` Hans van Kranenburg
  2019-02-26  1:29   ` Qu Wenruo
  6 siblings, 1 reply; 9+ messages in thread
From: Hans van Kranenburg @ 2019-02-25 16:36 UTC (permalink / raw)
  To: Qu Wenruo, linux-btrfs

Sorry to bother you again...

On 12/28/18 9:38 AM, Qu Wenruo wrote:
> This patchset can be fetched from github:
> https://github.com/adam900710/btrfs-progs/tree/bg_tree
> The basis commit is:
> 
> commit 7d16a2b460182ee98c649533a6975b6e419c3d71
> Author: Qu Wenruo <wqu@suse.com>
> Date:   Thu Dec 27 13:49:18 2018 +0800
> 
>     btrfs-progs: Create uuid tree with proper contents
> 
> Which is further based on devel branch.
> 
> This patchset provides the needed user space infrastructure for BG_TREE
> feature.
> 
> Since it's an new exclusive feature, unlike SKINNY_METADATA, btrfs-progs
> is needed to convert existing fs (unmounted) to new format.
> 
> Although I have prepared the functionality, convert_to_bg_tree(), and
> already uses it in mkfs, I haven't decided if I should put it under
> btrfstune, as btrfstune isn't such offline convert tool.

Ok, so, the convert_to_bg_tree still needs wiring up somewhere before
it's possible to convert an existing fs?

I want to test with a (iSCSI level clone of a) rather large-ish
filesystem, so I was searching for how to convert that in place.

Do you have an idea for a (quick hack?) way to make this happen?

Doing the offline conversion itself is also already an interesting
thing, seeing how it behaves with some tens of thousands of block
groups... (As the intended audience for it will mostly be people having
large filesystems already.)

> If anyone has better idea on the new convert tool interface, I'm all
> ears.
> 
> For the performance improvement, please check the kernel patchset cover
> letter or the last patch.
> (SPOILER ALERT: It's super fast)
> 
> Qu Wenruo (6):
>   btrfs-progs: Refactor excluded extent functions to use fs_info
>   btrfs-progs: Refactor btrfs_read_block_groups()
>   btrfs-progs: Enable read-write ability for 'bg_tree' feature
>   btrfs-progs: mkfs: Introduce -O bg-tree
>   btrfs-progs: dump-tree/dump-super: Introduce support for bg tree
>   btrfs-progs: check: Introduce support for bg-tree feature
> 
>  check/main.c              |   7 +-
>  check/mode-lowmem.c       |   9 +-
>  cmds-inspect-dump-super.c |   3 +-
>  cmds-inspect-dump-tree.c  |   5 +
>  ctree.h                   |  17 +-
>  disk-io.c                 |  29 +++-
>  extent-tree.c             | 326 +++++++++++++++++++++++++++-----------
>  fsfeatures.c              |   6 +
>  mkfs/common.c             |   7 +-
>  mkfs/common.h             |   1 +
>  mkfs/main.c               |  57 +++++++
>  print-tree.c              |   3 +
>  transaction.c             |   1 +
>  13 files changed, 365 insertions(+), 106 deletions(-)
> 


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

* Re: [PATCH 0/6] btrfs-progs: Support for BG_TREE feature
  2019-02-25 16:36 ` [PATCH 0/6] btrfs-progs: Support for BG_TREE feature Hans van Kranenburg
@ 2019-02-26  1:29   ` Qu Wenruo
  0 siblings, 0 replies; 9+ messages in thread
From: Qu Wenruo @ 2019-02-26  1:29 UTC (permalink / raw)
  To: Hans van Kranenburg, Qu Wenruo, linux-btrfs


[-- Attachment #1.1: Type: text/plain, Size: 3193 bytes --]



On 2019/2/26 上午12:36, Hans van Kranenburg wrote:
> Sorry to bother you again...
> 
> On 12/28/18 9:38 AM, Qu Wenruo wrote:
>> This patchset can be fetched from github:
>> https://github.com/adam900710/btrfs-progs/tree/bg_tree
>> The basis commit is:
>>
>> commit 7d16a2b460182ee98c649533a6975b6e419c3d71
>> Author: Qu Wenruo <wqu@suse.com>
>> Date:   Thu Dec 27 13:49:18 2018 +0800
>>
>>     btrfs-progs: Create uuid tree with proper contents
>>
>> Which is further based on devel branch.
>>
>> This patchset provides the needed user space infrastructure for BG_TREE
>> feature.
>>
>> Since it's an new exclusive feature, unlike SKINNY_METADATA, btrfs-progs
>> is needed to convert existing fs (unmounted) to new format.
>>
>> Although I have prepared the functionality, convert_to_bg_tree(), and
>> already uses it in mkfs, I haven't decided if I should put it under
>> btrfstune, as btrfstune isn't such offline convert tool.
> 
> Ok, so, the convert_to_bg_tree still needs wiring up somewhere before
> it's possible to convert an existing fs?

Sorry, I haven't investigate more time for this convert.
It's more or less expected to be something use it or not so far.

> 
> I want to test with a (iSCSI level clone of a) rather large-ish
> filesystem, so I was searching for how to convert that in place.
> 
> Do you have an idea for a (quick hack?) way to make this happen?

Btrfs-progs needs extra patch for it, but I haven't implemented it yet.
It shouldn't be super complex, but I'm not confident enough yet.

If nothing goes wrong, I'll update the btrfs-progs patchset this week
with (maybe PoC) offline convert.

Thanks,
Qu
> 
> Doing the offline conversion itself is also already an interesting
> thing, seeing how it behaves with some tens of thousands of block
> groups... (As the intended audience for it will mostly be people having
> large filesystems already.)
> 
>> If anyone has better idea on the new convert tool interface, I'm all
>> ears.
>>
>> For the performance improvement, please check the kernel patchset cover
>> letter or the last patch.
>> (SPOILER ALERT: It's super fast)
>>
>> Qu Wenruo (6):
>>   btrfs-progs: Refactor excluded extent functions to use fs_info
>>   btrfs-progs: Refactor btrfs_read_block_groups()
>>   btrfs-progs: Enable read-write ability for 'bg_tree' feature
>>   btrfs-progs: mkfs: Introduce -O bg-tree
>>   btrfs-progs: dump-tree/dump-super: Introduce support for bg tree
>>   btrfs-progs: check: Introduce support for bg-tree feature
>>
>>  check/main.c              |   7 +-
>>  check/mode-lowmem.c       |   9 +-
>>  cmds-inspect-dump-super.c |   3 +-
>>  cmds-inspect-dump-tree.c  |   5 +
>>  ctree.h                   |  17 +-
>>  disk-io.c                 |  29 +++-
>>  extent-tree.c             | 326 +++++++++++++++++++++++++++-----------
>>  fsfeatures.c              |   6 +
>>  mkfs/common.c             |   7 +-
>>  mkfs/common.h             |   1 +
>>  mkfs/main.c               |  57 +++++++
>>  print-tree.c              |   3 +
>>  transaction.c             |   1 +
>>  13 files changed, 365 insertions(+), 106 deletions(-)
>>
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

end of thread, other threads:[~2019-02-26  1:29 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-12-28  8:38 [PATCH 0/6] btrfs-progs: Support for BG_TREE feature Qu Wenruo
2018-12-28  8:38 ` [PATCH 1/6] btrfs-progs: Refactor excluded extent functions to use fs_info Qu Wenruo
2018-12-28  8:38 ` [PATCH 2/6] btrfs-progs: Refactor btrfs_read_block_groups() Qu Wenruo
2018-12-28  8:38 ` [PATCH 3/6] btrfs-progs: Enable read-write ability for 'bg_tree' feature Qu Wenruo
2018-12-28  8:38 ` [PATCH 4/6] btrfs-progs: mkfs: Introduce -O bg-tree Qu Wenruo
2018-12-28  8:38 ` [PATCH 5/6] btrfs-progs: dump-tree/dump-super: Introduce support for bg tree Qu Wenruo
2018-12-28  8:38 ` [PATCH 6/6] btrfs-progs: check: Introduce support for bg-tree feature Qu Wenruo
2019-02-25 16:36 ` [PATCH 0/6] btrfs-progs: Support for BG_TREE feature Hans van Kranenburg
2019-02-26  1:29   ` Qu Wenruo

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).