linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/11] btrfs: extent tree v2, support for global roots
@ 2021-12-15 20:39 Josef Bacik
  2021-12-15 20:39 ` [PATCH v2 01/11] btrfs: add definition for EXTENT_TREE_V2 Josef Bacik
                   ` (12 more replies)
  0 siblings, 13 replies; 20+ messages in thread
From: Josef Bacik @ 2021-12-15 20:39 UTC (permalink / raw)
  To: linux-btrfs, kernel-team

v1->v2:
- Disabled some more operations for extent tree v2 that I found were problematic
  in testing.
- Rebased onto a recent misc-next

--- Original email ---
Hello,

This is the kernel side of the global roots and block group root support.  The
motivation for this change is described in the progs patches.  The important
part here is I've disabled qgroups and balance for now, this support will be
added back later.  I've also changed global block rsv size calculation, but it's
exactly the same result for !EXTENT_TREE_V2.  And finally there's the support
for loading the roots.  This doesn't panic and doesn't introduce any performance
regressions.  I've also hidden the support behind CONFIG_BTRFS_DEBUG so it
doesn't get used accidentally.  Thanks,

Josef

Josef Bacik (11):
  btrfs: add definition for EXTENT_TREE_V2
  btrfs: disable balance for extent tree v2 for now
  btrfs: disable device manipulation ioctl's EXTENT_TREE_V2
  btrfs: disable qgroups in extent tree v2
  btrfs: disable scrub for extent-tree-v2
  btrfs: disable snapshot creation/deletion for extent tree v2
  btrfs: disable space cache related mount options for extent tree v2
  btrfs: tree-checker: don't fail on empty extent roots for extent tree
    v2
  btrfs: abstract out loading the tree root
  btrfs: add code to support the block group root
  btrfs: add support for multiple global roots

 fs/btrfs/block-group.c          |  25 ++++-
 fs/btrfs/block-group.h          |   1 +
 fs/btrfs/ctree.h                |  46 ++++++++-
 fs/btrfs/disk-io.c              | 178 +++++++++++++++++++++++---------
 fs/btrfs/disk-io.h              |   2 +
 fs/btrfs/free-space-tree.c      |   2 +
 fs/btrfs/inode.c                |  11 +-
 fs/btrfs/ioctl.c                |  29 ++++++
 fs/btrfs/print-tree.c           |   1 +
 fs/btrfs/qgroup.c               |   6 ++
 fs/btrfs/super.c                |  20 ++++
 fs/btrfs/sysfs.c                |   5 +-
 fs/btrfs/transaction.c          |  15 +++
 fs/btrfs/tree-checker.c         |  35 ++++++-
 fs/btrfs/volumes.c              |  11 ++
 include/trace/events/btrfs.h    |   1 +
 include/uapi/linux/btrfs.h      |   1 +
 include/uapi/linux/btrfs_tree.h |   3 +
 18 files changed, 333 insertions(+), 59 deletions(-)

-- 
2.26.3


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

* [PATCH v2 01/11] btrfs: add definition for EXTENT_TREE_V2
  2021-12-15 20:39 [PATCH v2 00/11] btrfs: extent tree v2, support for global roots Josef Bacik
@ 2021-12-15 20:39 ` Josef Bacik
  2021-12-15 20:39 ` [PATCH v2 02/11] btrfs: disable balance for extent tree v2 for now Josef Bacik
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 20+ messages in thread
From: Josef Bacik @ 2021-12-15 20:39 UTC (permalink / raw)
  To: linux-btrfs, kernel-team

This adds the initial definition of the EXTENT_TREE_V2 incompat feature
flag.  This also hides the support behind CONFIG_BTRFS_DEBUG.

THIS IS A IN DEVELOPMENT FORMAT CHANGE, DO NOT USE UNLESS YOU ARE A
DEVELOPER OR A TESTER.

The format is in flux and will be added in stages, any fs will need to
be re-made between updates to the format.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/ctree.h           | 18 ++++++++++++++++++
 fs/btrfs/sysfs.c           |  5 ++++-
 include/uapi/linux/btrfs.h |  1 +
 3 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 02f06ee02e4e..f70b6772b3ad 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -297,6 +297,23 @@ static_assert(sizeof(struct btrfs_super_block) == BTRFS_SUPER_INFO_SIZE);
 #define BTRFS_FEATURE_COMPAT_RO_SAFE_SET	0ULL
 #define BTRFS_FEATURE_COMPAT_RO_SAFE_CLEAR	0ULL
 
+#ifdef CONFIG_BTRFS_DEBUG
+#define BTRFS_FEATURE_INCOMPAT_SUPP			\
+	(BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF |		\
+	 BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL |	\
+	 BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS |		\
+	 BTRFS_FEATURE_INCOMPAT_BIG_METADATA |		\
+	 BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO |		\
+	 BTRFS_FEATURE_INCOMPAT_COMPRESS_ZSTD |		\
+	 BTRFS_FEATURE_INCOMPAT_RAID56 |		\
+	 BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF |		\
+	 BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA |	\
+	 BTRFS_FEATURE_INCOMPAT_NO_HOLES	|	\
+	 BTRFS_FEATURE_INCOMPAT_METADATA_UUID	|	\
+	 BTRFS_FEATURE_INCOMPAT_RAID1C34	|	\
+	 BTRFS_FEATURE_INCOMPAT_ZONED		|	\
+	 BTRFS_FEATURE_INCOMPAT_EXTENT_TREE_V2)
+#else
 #define BTRFS_FEATURE_INCOMPAT_SUPP			\
 	(BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF |		\
 	 BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL |	\
@@ -311,6 +328,7 @@ static_assert(sizeof(struct btrfs_super_block) == BTRFS_SUPER_INFO_SIZE);
 	 BTRFS_FEATURE_INCOMPAT_METADATA_UUID	|	\
 	 BTRFS_FEATURE_INCOMPAT_RAID1C34	|	\
 	 BTRFS_FEATURE_INCOMPAT_ZONED)
+#endif
 
 #define BTRFS_FEATURE_INCOMPAT_SAFE_SET			\
 	(BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF)
diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c
index beb7f72d50b8..5f4812fd8b50 100644
--- a/fs/btrfs/sysfs.c
+++ b/fs/btrfs/sysfs.c
@@ -283,9 +283,11 @@ BTRFS_FEAT_ATTR_INCOMPAT(no_holes, NO_HOLES);
 BTRFS_FEAT_ATTR_INCOMPAT(metadata_uuid, METADATA_UUID);
 BTRFS_FEAT_ATTR_COMPAT_RO(free_space_tree, FREE_SPACE_TREE);
 BTRFS_FEAT_ATTR_INCOMPAT(raid1c34, RAID1C34);
-/* Remove once support for zoned allocation is feature complete */
 #ifdef CONFIG_BTRFS_DEBUG
+/* Remove once support for zoned allocation is feature complete */
 BTRFS_FEAT_ATTR_INCOMPAT(zoned, ZONED);
+/* Remove once support for extent tree v2 is feature complete */
+BTRFS_FEAT_ATTR_INCOMPAT(extent_tree_v2, EXTENT_TREE_V2);
 #endif
 #ifdef CONFIG_FS_VERITY
 BTRFS_FEAT_ATTR_COMPAT_RO(verity, VERITY);
@@ -314,6 +316,7 @@ static struct attribute *btrfs_supported_feature_attrs[] = {
 	BTRFS_FEAT_ATTR_PTR(raid1c34),
 #ifdef CONFIG_BTRFS_DEBUG
 	BTRFS_FEAT_ATTR_PTR(zoned),
+	BTRFS_FEAT_ATTR_PTR(extent_tree_v2),
 #endif
 #ifdef CONFIG_FS_VERITY
 	BTRFS_FEAT_ATTR_PTR(verity),
diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h
index 738619994e26..1cb1a3860f1d 100644
--- a/include/uapi/linux/btrfs.h
+++ b/include/uapi/linux/btrfs.h
@@ -309,6 +309,7 @@ struct btrfs_ioctl_fs_info_args {
 #define BTRFS_FEATURE_INCOMPAT_METADATA_UUID	(1ULL << 10)
 #define BTRFS_FEATURE_INCOMPAT_RAID1C34		(1ULL << 11)
 #define BTRFS_FEATURE_INCOMPAT_ZONED		(1ULL << 12)
+#define BTRFS_FEATURE_INCOMPAT_EXTENT_TREE_V2	(1ULL << 13)
 
 struct btrfs_ioctl_feature_flags {
 	__u64 compat_flags;
-- 
2.26.3


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

* [PATCH v2 02/11] btrfs: disable balance for extent tree v2 for now
  2021-12-15 20:39 [PATCH v2 00/11] btrfs: extent tree v2, support for global roots Josef Bacik
  2021-12-15 20:39 ` [PATCH v2 01/11] btrfs: add definition for EXTENT_TREE_V2 Josef Bacik
@ 2021-12-15 20:39 ` Josef Bacik
  2021-12-15 20:40 ` [PATCH v2 03/11] btrfs: disable device manipulation ioctl's EXTENT_TREE_V2 Josef Bacik
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 20+ messages in thread
From: Josef Bacik @ 2021-12-15 20:39 UTC (permalink / raw)
  To: linux-btrfs, kernel-team

With global root id's it makes it problematic to do backref lookups for
balance.  This isn't hard to deal with, but future changes are going to
make it impossible to lookup backrefs on any cowonly roots, so go ahead
and disable balance for now on extent tree v2 until we can add balance
support back in future patches.

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

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index a7071f34fe64..802bfc63aa21 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -3253,6 +3253,12 @@ int btrfs_relocate_chunk(struct btrfs_fs_info *fs_info, u64 chunk_offset)
 	u64 length;
 	int ret;
 
+	if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2)) {
+		btrfs_err(fs_info,
+			  "relocate: not supported on extent tree v2 yet.");
+		return -EINVAL;
+	}
+
 	/*
 	 * Prevent races with automatic removal of unused block groups.
 	 * After we relocate and before we remove the chunk with offset
-- 
2.26.3


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

* [PATCH v2 03/11] btrfs: disable device manipulation ioctl's EXTENT_TREE_V2
  2021-12-15 20:39 [PATCH v2 00/11] btrfs: extent tree v2, support for global roots Josef Bacik
  2021-12-15 20:39 ` [PATCH v2 01/11] btrfs: add definition for EXTENT_TREE_V2 Josef Bacik
  2021-12-15 20:39 ` [PATCH v2 02/11] btrfs: disable balance for extent tree v2 for now Josef Bacik
@ 2021-12-15 20:40 ` Josef Bacik
  2021-12-15 20:40 ` [PATCH v2 04/11] btrfs: disable qgroups in extent tree v2 Josef Bacik
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 20+ messages in thread
From: Josef Bacik @ 2021-12-15 20:40 UTC (permalink / raw)
  To: linux-btrfs, kernel-team

Device add, remove, and replace all require balance, which doesn't work
right now on extent tree v2, so disable these for now.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/ioctl.c   | 10 ++++++++++
 fs/btrfs/volumes.c |  5 +++++
 2 files changed, 15 insertions(+)

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 61c90086072d..4ae87f44ce46 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -3178,6 +3178,11 @@ static long btrfs_ioctl_add_dev(struct btrfs_fs_info *fs_info, void __user *arg)
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
+	if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2)) {
+		btrfs_err(fs_info, "device add not supported on extent tree v2 yet.");
+		return -EINVAL;
+	}
+
 	if (!btrfs_exclop_start(fs_info, BTRFS_EXCLOP_DEV_ADD)) {
 		if (!btrfs_exclop_start_try_lock(fs_info, BTRFS_EXCLOP_DEV_ADD))
 			return BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS;
@@ -3802,6 +3807,11 @@ static long btrfs_ioctl_dev_replace(struct btrfs_fs_info *fs_info,
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
+	if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2)) {
+		btrfs_err(fs_info, "device replace not supported on extent tree v2 yet.");
+		return -EINVAL;
+	}
+
 	p = memdup_user(arg, sizeof(*p));
 	if (IS_ERR(p))
 		return PTR_ERR(p);
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 802bfc63aa21..9b7ad5002508 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -2101,6 +2101,11 @@ int btrfs_rm_device(struct btrfs_fs_info *fs_info,
 	u64 num_devices;
 	int ret = 0;
 
+	if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2)) {
+		btrfs_err(fs_info, "device remove not supported on extent tree v2 yet.");
+		return -EINVAL;
+	}
+
 	/*
 	 * The device list in fs_devices is accessed without locks (neither
 	 * uuid_mutex nor device_list_mutex) as it won't change on a mounted
-- 
2.26.3


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

* [PATCH v2 04/11] btrfs: disable qgroups in extent tree v2
  2021-12-15 20:39 [PATCH v2 00/11] btrfs: extent tree v2, support for global roots Josef Bacik
                   ` (2 preceding siblings ...)
  2021-12-15 20:40 ` [PATCH v2 03/11] btrfs: disable device manipulation ioctl's EXTENT_TREE_V2 Josef Bacik
@ 2021-12-15 20:40 ` Josef Bacik
  2021-12-15 20:40 ` [PATCH v2 05/11] btrfs: disable scrub for extent-tree-v2 Josef Bacik
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 20+ messages in thread
From: Josef Bacik @ 2021-12-15 20:40 UTC (permalink / raw)
  To: linux-btrfs, kernel-team

Backref lookups are going to be drastically different with extent tree
v2, disable qgroups until we do the work to add this support for extent
tree v2.

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

diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index b126cc39ffd4..1c686c0be352 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -948,6 +948,12 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info)
 	 */
 	lockdep_assert_held_write(&fs_info->subvol_sem);
 
+	if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2)) {
+		btrfs_err(fs_info,
+			  "qgroups are currently unsupported in extent tree v2");
+		return -EINVAL;
+	}
+
 	mutex_lock(&fs_info->qgroup_ioctl_lock);
 	if (fs_info->quota_root)
 		goto out;
-- 
2.26.3


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

* [PATCH v2 05/11] btrfs: disable scrub for extent-tree-v2
  2021-12-15 20:39 [PATCH v2 00/11] btrfs: extent tree v2, support for global roots Josef Bacik
                   ` (3 preceding siblings ...)
  2021-12-15 20:40 ` [PATCH v2 04/11] btrfs: disable qgroups in extent tree v2 Josef Bacik
@ 2021-12-15 20:40 ` Josef Bacik
  2021-12-15 20:40 ` [PATCH v2 06/11] btrfs: disable snapshot creation/deletion for extent tree v2 Josef Bacik
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 20+ messages in thread
From: Josef Bacik @ 2021-12-15 20:40 UTC (permalink / raw)
  To: linux-btrfs, kernel-team

Scrub depends on extent references for every block, and with extent tree
v2 we won't have that, so disable scrub until we can add back the proper
code to handle extent-tree-v2.

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

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 4ae87f44ce46..c81f50774cec 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -3708,6 +3708,11 @@ static long btrfs_ioctl_scrub(struct file *file, void __user *arg)
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
+	if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2)) {
+		btrfs_err(fs_info, "scrub is not supported on extent tree v2 yet.");
+		return -EINVAL;
+	}
+
 	sa = memdup_user(arg, sizeof(*sa));
 	if (IS_ERR(sa))
 		return PTR_ERR(sa);
-- 
2.26.3


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

* [PATCH v2 06/11] btrfs: disable snapshot creation/deletion for extent tree v2
  2021-12-15 20:39 [PATCH v2 00/11] btrfs: extent tree v2, support for global roots Josef Bacik
                   ` (4 preceding siblings ...)
  2021-12-15 20:40 ` [PATCH v2 05/11] btrfs: disable scrub for extent-tree-v2 Josef Bacik
@ 2021-12-15 20:40 ` Josef Bacik
  2021-12-15 20:40 ` [PATCH v2 07/11] btrfs: disable space cache related mount options " Josef Bacik
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 20+ messages in thread
From: Josef Bacik @ 2021-12-15 20:40 UTC (permalink / raw)
  To: linux-btrfs, kernel-team

When we stop tracking metadata blocks all of snapshotting will break, so
disable it until I add the snapshot root and drop tree support.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/inode.c | 11 +++++++++--
 fs/btrfs/ioctl.c | 14 ++++++++++++++
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index a88130c7782e..3d590a96f5d0 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -4565,14 +4565,21 @@ int btrfs_delete_subvolume(struct inode *dir, struct dentry *dentry)
 static int btrfs_rmdir(struct inode *dir, struct dentry *dentry)
 {
 	struct inode *inode = d_inode(dentry);
+	struct btrfs_fs_info *fs_info = BTRFS_I(inode)->root->fs_info;
 	int err = 0;
 	struct btrfs_trans_handle *trans;
 	u64 last_unlink_trans;
 
 	if (inode->i_size > BTRFS_EMPTY_DIR_SIZE)
 		return -ENOTEMPTY;
-	if (btrfs_ino(BTRFS_I(inode)) == BTRFS_FIRST_FREE_OBJECTID)
+	if (btrfs_ino(BTRFS_I(inode)) == BTRFS_FIRST_FREE_OBJECTID) {
+		if (unlikely(btrfs_fs_incompat(fs_info, EXTENT_TREE_V2))) {
+			btrfs_err(fs_info,
+				  "extent tree v2 doesn't support snapshot deletion yet.");
+			return -EOPNOTSUPP;
+		}
 		return btrfs_delete_subvolume(dir, dentry);
+	}
 
 	trans = __unlink_start_trans(dir);
 	if (IS_ERR(trans))
@@ -4611,7 +4618,7 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry)
 	}
 out:
 	btrfs_end_transaction(trans);
-	btrfs_btree_balance_dirty(BTRFS_I(dir)->root->fs_info);
+	btrfs_btree_balance_dirty(fs_info);
 
 	return err;
 }
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index c81f50774cec..cfcffb69d5fe 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -751,6 +751,13 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
 	struct btrfs_trans_handle *trans;
 	int ret;
 
+	/* We do not support snapshotting right now. */
+	if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2)) {
+		btrfs_warn(fs_info,
+			   "extent tree v2 doesn't support snapshotting yet.");
+		return -EOPNOTSUPP;
+	}
+
 	if (!test_bit(BTRFS_ROOT_SHAREABLE, &root->state))
 		return -EINVAL;
 
@@ -2901,6 +2908,13 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
 	int err = 0;
 	bool destroy_parent = false;
 
+	/* We don't support snapshots with extent tree v2 yet. */
+	if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2)) {
+		btrfs_err(fs_info,
+			  "extent tree v2 doesn't support snapshot deletion yet.");
+		return -EOPNOTSUPP;
+	}
+
 	if (destroy_v2) {
 		vol_args2 = memdup_user(arg, sizeof(*vol_args2));
 		if (IS_ERR(vol_args2))
-- 
2.26.3


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

* [PATCH v2 07/11] btrfs: disable space cache related mount options for extent tree v2
  2021-12-15 20:39 [PATCH v2 00/11] btrfs: extent tree v2, support for global roots Josef Bacik
                   ` (5 preceding siblings ...)
  2021-12-15 20:40 ` [PATCH v2 06/11] btrfs: disable snapshot creation/deletion for extent tree v2 Josef Bacik
@ 2021-12-15 20:40 ` Josef Bacik
  2021-12-15 20:40 ` [PATCH v2 08/11] btrfs: tree-checker: don't fail on empty extent roots " Josef Bacik
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 20+ messages in thread
From: Josef Bacik @ 2021-12-15 20:40 UTC (permalink / raw)
  To: linux-btrfs, kernel-team

We cannot fall back on the slow caching for extent tree v2, which means
we can't just arbitrarily clear the free space trees at mount time.
Furthermore we can't do v1 space cache with extent tree v2.  Simply
ignore these mount options for extent tree v2 as they aren't relevant.

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

diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index a1c54a2c787c..7c7c0c36f461 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -862,6 +862,14 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
 			break;
 		case Opt_space_cache:
 		case Opt_space_cache_version:
+			/*
+			 * We already set FREE_SPACE_TREE above because we have
+			 * compat_ro(FREE_SPACE_TREE) set, and we aren't going
+			 * to allow v1 to be set for extent tree v2, simply
+			 * ignore this setting if we're extent tree v2.
+			 */
+			if (btrfs_fs_incompat(info, EXTENT_TREE_V2))
+				break;
 			if (token == Opt_space_cache ||
 			    strcmp(args[0].from, "v1") == 0) {
 				btrfs_clear_opt(info->mount_opt,
@@ -882,6 +890,12 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
 			btrfs_set_opt(info->mount_opt, RESCAN_UUID_TREE);
 			break;
 		case Opt_no_space_cache:
+			/*
+			 * We cannot operate without the free space tree with
+			 * extent tree v2, ignore this option.
+			 */
+			if (btrfs_fs_incompat(info, EXTENT_TREE_V2))
+				break;
 			if (btrfs_test_opt(info, SPACE_CACHE)) {
 				btrfs_clear_and_info(info, SPACE_CACHE,
 					     "disabling disk space caching");
@@ -897,6 +911,12 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
 	"the 'inode_cache' option is deprecated and has no effect since 5.11");
 			break;
 		case Opt_clear_cache:
+			/*
+			 * We cannot clear the free space tree with extent tree
+			 * v2, ignore this option.
+			 */
+			if (btrfs_fs_incompat(info, EXTENT_TREE_V2))
+				break;
 			btrfs_set_and_info(info, CLEAR_CACHE,
 					   "force clearing of disk cache");
 			break;
-- 
2.26.3


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

* [PATCH v2 08/11] btrfs: tree-checker: don't fail on empty extent roots for extent tree v2
  2021-12-15 20:39 [PATCH v2 00/11] btrfs: extent tree v2, support for global roots Josef Bacik
                   ` (6 preceding siblings ...)
  2021-12-15 20:40 ` [PATCH v2 07/11] btrfs: disable space cache related mount options " Josef Bacik
@ 2021-12-15 20:40 ` Josef Bacik
  2021-12-15 20:40 ` [PATCH v2 09/11] btrfs: abstract out loading the tree root Josef Bacik
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 20+ messages in thread
From: Josef Bacik @ 2021-12-15 20:40 UTC (permalink / raw)
  To: linux-btrfs, kernel-team

For extent tree v2 we can definitely have empty extent roots, so skip
this particular check if we have that set.

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

diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c
index 72e1c942197d..ef7d624b0672 100644
--- a/fs/btrfs/tree-checker.c
+++ b/fs/btrfs/tree-checker.c
@@ -1633,7 +1633,6 @@ static int check_leaf(struct extent_buffer *leaf, bool check_item_data)
 		/* These trees must never be empty */
 		if (unlikely(owner == BTRFS_ROOT_TREE_OBJECTID ||
 			     owner == BTRFS_CHUNK_TREE_OBJECTID ||
-			     owner == BTRFS_EXTENT_TREE_OBJECTID ||
 			     owner == BTRFS_DEV_TREE_OBJECTID ||
 			     owner == BTRFS_FS_TREE_OBJECTID ||
 			     owner == BTRFS_DATA_RELOC_TREE_OBJECTID)) {
@@ -1642,12 +1641,25 @@ static int check_leaf(struct extent_buffer *leaf, bool check_item_data)
 				    owner);
 			return -EUCLEAN;
 		}
+
 		/* Unknown tree */
 		if (unlikely(owner == 0)) {
 			generic_err(leaf, 0,
 				"invalid owner, root 0 is not defined");
 			return -EUCLEAN;
 		}
+
+		/* EXTENT_TREE_V2 can have empty extent trees. */
+		if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2))
+			return 0;
+
+		if (unlikely(owner == BTRFS_EXTENT_TREE_OBJECTID)) {
+			generic_err(leaf, 0,
+			"invalid root, root %llu must never be empty",
+				    owner);
+			return -EUCLEAN;
+		}
+
 		return 0;
 	}
 
-- 
2.26.3


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

* [PATCH v2 09/11] btrfs: abstract out loading the tree root
  2021-12-15 20:39 [PATCH v2 00/11] btrfs: extent tree v2, support for global roots Josef Bacik
                   ` (7 preceding siblings ...)
  2021-12-15 20:40 ` [PATCH v2 08/11] btrfs: tree-checker: don't fail on empty extent roots " Josef Bacik
@ 2021-12-15 20:40 ` Josef Bacik
  2022-01-13  9:20   ` Nikolay Borisov
  2021-12-15 20:40 ` [PATCH v2 10/11] btrfs: add code to support the block group root Josef Bacik
                   ` (3 subsequent siblings)
  12 siblings, 1 reply; 20+ messages in thread
From: Josef Bacik @ 2021-12-15 20:40 UTC (permalink / raw)
  To: linux-btrfs, kernel-team

We're going to be adding more roots that need to be loaded from the
super block, so abstract out the code to read the tree_root from the
super block, and use this helper for the chunk root as well.  This will
make it simpler to load the new trees in the future.

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

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 5c598e124c25..ddc3b9fcbabc 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2934,6 +2934,46 @@ static int btrfs_validate_write_super(struct btrfs_fs_info *fs_info,
 	return ret;
 }
 
+static int load_super_root(struct btrfs_root *root, u64 bytenr, u64 gen,
+			   int level)
+{
+	int ret = 0;
+
+	root->node = read_tree_block(root->fs_info, bytenr,
+				     root->root_key.objectid, gen, level, NULL);
+	if (IS_ERR(root->node)) {
+		ret = PTR_ERR(root->node);
+		root->node = NULL;
+	} else if (!extent_buffer_uptodate(root->node)) {
+		free_extent_buffer(root->node);
+		root->node = NULL;
+		ret = -EIO;
+	}
+
+	if (ret)
+		return ret;
+
+	btrfs_set_root_node(&root->root_item, root->node);
+	root->commit_root = btrfs_root_node(root);
+	btrfs_set_root_refs(&root->root_item, 1);
+	return ret;
+}
+
+static int load_important_roots(struct btrfs_fs_info *fs_info)
+{
+	struct btrfs_super_block *sb = fs_info->super_copy;
+	u64 gen, bytenr;
+	int level, ret;
+
+	bytenr = btrfs_super_root(sb);
+	gen = btrfs_super_generation(sb);
+	level = btrfs_super_root_level(sb);
+	ret = load_super_root(fs_info->tree_root, bytenr, gen, level);
+	if (ret)
+		btrfs_warn(fs_info, "couldn't read tree root");
+	return ret;
+}
+
 static int __cold init_tree_roots(struct btrfs_fs_info *fs_info)
 {
 	int backup_index = find_newest_super_backup(fs_info);
@@ -2944,9 +2984,6 @@ static int __cold init_tree_roots(struct btrfs_fs_info *fs_info)
 	int i;
 
 	for (i = 0; i < BTRFS_NUM_BACKUP_ROOTS; i++) {
-		u64 generation;
-		int level;
-
 		if (handle_error) {
 			if (!IS_ERR(tree_root->node))
 				free_extent_buffer(tree_root->node);
@@ -2971,29 +3008,13 @@ static int __cold init_tree_roots(struct btrfs_fs_info *fs_info)
 			if (ret < 0)
 				return ret;
 		}
-		generation = btrfs_super_generation(sb);
-		level = btrfs_super_root_level(sb);
-		tree_root->node = read_tree_block(fs_info, btrfs_super_root(sb),
-						  BTRFS_ROOT_TREE_OBJECTID,
-						  generation, level, NULL);
-		if (IS_ERR(tree_root->node)) {
-			handle_error = true;
-			ret = PTR_ERR(tree_root->node);
-			tree_root->node = NULL;
-			btrfs_warn(fs_info, "couldn't read tree root");
-			continue;
 
-		} else if (!extent_buffer_uptodate(tree_root->node)) {
+		ret = load_important_roots(fs_info);
+		if (ret) {
 			handle_error = true;
-			ret = -EIO;
-			btrfs_warn(fs_info, "error while reading tree root");
 			continue;
 		}
 
-		btrfs_set_root_node(&tree_root->root_item, tree_root->node);
-		tree_root->commit_root = btrfs_root_node(tree_root);
-		btrfs_set_root_refs(&tree_root->root_item, 1);
-
 		/*
 		 * No need to hold btrfs_root::objectid_mutex since the fs
 		 * hasn't been fully initialised and we are the only user
@@ -3013,8 +3034,8 @@ static int __cold init_tree_roots(struct btrfs_fs_info *fs_info)
 		}
 
 		/* All successful */
-		fs_info->generation = generation;
-		fs_info->last_trans_committed = generation;
+		fs_info->generation = btrfs_header_generation(tree_root->node);
+		fs_info->last_trans_committed = fs_info->generation;
 		fs_info->last_reloc_trans = 0;
 
 		/* Always begin writing backup roots after the one being used */
@@ -3602,21 +3623,12 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
 
 	generation = btrfs_super_chunk_root_generation(disk_super);
 	level = btrfs_super_chunk_root_level(disk_super);
-
-	chunk_root->node = read_tree_block(fs_info,
-					   btrfs_super_chunk_root(disk_super),
-					   BTRFS_CHUNK_TREE_OBJECTID,
-					   generation, level, NULL);
-	if (IS_ERR(chunk_root->node) ||
-	    !extent_buffer_uptodate(chunk_root->node)) {
+	ret = load_super_root(chunk_root, btrfs_super_chunk_root(disk_super),
+			      generation, level);
+	if (ret) {
 		btrfs_err(fs_info, "failed to read chunk root");
-		if (!IS_ERR(chunk_root->node))
-			free_extent_buffer(chunk_root->node);
-		chunk_root->node = NULL;
 		goto fail_tree_roots;
 	}
-	btrfs_set_root_node(&chunk_root->root_item, chunk_root->node);
-	chunk_root->commit_root = btrfs_root_node(chunk_root);
 
 	read_extent_buffer(chunk_root->node, fs_info->chunk_tree_uuid,
 			   offsetof(struct btrfs_header, chunk_tree_uuid),
-- 
2.26.3


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

* [PATCH v2 10/11] btrfs: add code to support the block group root
  2021-12-15 20:39 [PATCH v2 00/11] btrfs: extent tree v2, support for global roots Josef Bacik
                   ` (8 preceding siblings ...)
  2021-12-15 20:40 ` [PATCH v2 09/11] btrfs: abstract out loading the tree root Josef Bacik
@ 2021-12-15 20:40 ` Josef Bacik
  2022-01-12 15:16   ` Nikolay Borisov
  2021-12-15 20:40 ` [PATCH v2 11/11] btrfs: add support for multiple global roots Josef Bacik
                   ` (2 subsequent siblings)
  12 siblings, 1 reply; 20+ messages in thread
From: Josef Bacik @ 2021-12-15 20:40 UTC (permalink / raw)
  To: linux-btrfs, kernel-team

This code adds the on disk structures for the block group root, which
will hold the block group items for extent tree v2.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/ctree.h                | 26 ++++++++++++++++-
 fs/btrfs/disk-io.c              | 49 ++++++++++++++++++++++++++++-----
 fs/btrfs/disk-io.h              |  2 ++
 fs/btrfs/print-tree.c           |  1 +
 include/trace/events/btrfs.h    |  1 +
 include/uapi/linux/btrfs_tree.h |  3 ++
 6 files changed, 74 insertions(+), 8 deletions(-)

diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index f70b6772b3ad..40c1e5869cef 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -271,8 +271,13 @@ struct btrfs_super_block {
 	/* the UUID written into btree blocks */
 	u8 metadata_uuid[BTRFS_FSID_SIZE];
 
+	__le64 block_group_root;
+	__le64 block_group_root_generation;
+	u8 block_group_root_level;
+
 	/* future expansion */
-	__le64 reserved[28];
+	u8 reserved8[7];
+	__le64 reserved[25];
 	u8 sys_chunk_array[BTRFS_SYSTEM_CHUNK_ARRAY_SIZE];
 	struct btrfs_root_backup super_roots[BTRFS_NUM_BACKUP_ROOTS];
 
@@ -648,6 +653,7 @@ struct btrfs_fs_info {
 	struct btrfs_root *quota_root;
 	struct btrfs_root *uuid_root;
 	struct btrfs_root *data_reloc_root;
+	struct btrfs_root *block_group_root;
 
 	/* the log root tree is a directory of all the other log roots */
 	struct btrfs_root *log_root_tree;
@@ -2336,6 +2342,17 @@ BTRFS_SETGET_STACK_FUNCS(backup_bytes_used, struct btrfs_root_backup,
 BTRFS_SETGET_STACK_FUNCS(backup_num_devices, struct btrfs_root_backup,
 		   num_devices, 64);
 
+/*
+ * for extent tree v2 we overload the extent root with the block group root, as
+ * we will have multiple extent roots.
+ */
+BTRFS_SETGET_STACK_FUNCS(backup_block_group_root, struct btrfs_root_backup,
+			 extent_root, 64);
+BTRFS_SETGET_STACK_FUNCS(backup_block_group_root_gen, struct btrfs_root_backup,
+			 extent_root_gen, 64);
+BTRFS_SETGET_STACK_FUNCS(backup_block_group_root_level,
+			 struct btrfs_root_backup, extent_root_level, 8);
+
 /* struct btrfs_balance_item */
 BTRFS_SETGET_FUNCS(balance_flags, struct btrfs_balance_item, flags, 64);
 
@@ -2470,6 +2487,13 @@ BTRFS_SETGET_STACK_FUNCS(super_cache_generation, struct btrfs_super_block,
 BTRFS_SETGET_STACK_FUNCS(super_magic, struct btrfs_super_block, magic, 64);
 BTRFS_SETGET_STACK_FUNCS(super_uuid_tree_generation, struct btrfs_super_block,
 			 uuid_tree_generation, 64);
+BTRFS_SETGET_STACK_FUNCS(super_block_group_root, struct btrfs_super_block,
+			 block_group_root, 64);
+BTRFS_SETGET_STACK_FUNCS(super_block_group_root_generation,
+			 struct btrfs_super_block,
+			 block_group_root_generation, 64);
+BTRFS_SETGET_STACK_FUNCS(super_block_group_root_level, struct btrfs_super_block,
+			 block_group_root_level, 8);
 
 int btrfs_super_csum_size(const struct btrfs_super_block *s);
 const char *btrfs_super_csum_name(u16 csum_type);
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index ddc3b9fcbabc..b31f20a9da2f 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1734,6 +1734,7 @@ void btrfs_free_fs_info(struct btrfs_fs_info *fs_info)
 	btrfs_put_root(fs_info->uuid_root);
 	btrfs_put_root(fs_info->fs_root);
 	btrfs_put_root(fs_info->data_reloc_root);
+	btrfs_put_root(fs_info->block_group_root);
 	btrfs_check_leaked_roots(fs_info);
 	btrfs_extent_buffer_leak_debug_check(fs_info);
 	kfree(fs_info->super_copy);
@@ -2094,7 +2095,6 @@ static void backup_super_roots(struct btrfs_fs_info *info)
 {
 	const int next_backup = info->backup_root_index;
 	struct btrfs_root_backup *root_backup;
-	struct btrfs_root *extent_root = btrfs_extent_root(info, 0);
 	struct btrfs_root *csum_root = btrfs_csum_root(info, 0);
 
 	root_backup = info->super_for_commit->super_roots + next_backup;
@@ -2120,11 +2120,23 @@ static void backup_super_roots(struct btrfs_fs_info *info)
 	btrfs_set_backup_chunk_root_level(root_backup,
 			       btrfs_header_level(info->chunk_root->node));
 
-	btrfs_set_backup_extent_root(root_backup, extent_root->node->start);
-	btrfs_set_backup_extent_root_gen(root_backup,
-			       btrfs_header_generation(extent_root->node));
-	btrfs_set_backup_extent_root_level(root_backup,
-			       btrfs_header_level(extent_root->node));
+	if (btrfs_fs_incompat(info, EXTENT_TREE_V2)) {
+		btrfs_set_backup_block_group_root(root_backup,
+					info->block_group_root->node->start);
+		btrfs_set_backup_block_group_root_gen(root_backup,
+			btrfs_header_generation(info->block_group_root->node));
+		btrfs_set_backup_block_group_root_level(root_backup,
+			btrfs_header_level(info->block_group_root->node));
+	} else {
+		struct btrfs_root *extent_root = btrfs_extent_root(info, 0);
+
+		btrfs_set_backup_extent_root(root_backup,
+					     extent_root->node->start);
+		btrfs_set_backup_extent_root_gen(root_backup,
+				btrfs_header_generation(extent_root->node));
+		btrfs_set_backup_extent_root_level(root_backup,
+					btrfs_header_level(extent_root->node));
+	}
 
 	/*
 	 * we might commit during log recovery, which happens before we set
@@ -2269,6 +2281,7 @@ static void free_root_pointers(struct btrfs_fs_info *info, bool free_chunk_root)
 	free_root_extent_buffers(info->uuid_root);
 	free_root_extent_buffers(info->fs_root);
 	free_root_extent_buffers(info->data_reloc_root);
+	free_root_extent_buffers(info->block_group_root);
 	if (free_chunk_root)
 		free_root_extent_buffers(info->chunk_root);
 }
@@ -2969,8 +2982,20 @@ static int load_important_roots(struct btrfs_fs_info *fs_info)
 	gen = btrfs_super_generation(sb);
 	level = btrfs_super_root_level(sb);
 	ret = load_super_root(fs_info->tree_root, bytenr, gen, level);
-	if (ret)
+	if (ret) {
 		btrfs_warn(fs_info, "couldn't read tree root");
+		return ret;
+	}
+
+	if (!btrfs_fs_incompat(fs_info, EXTENT_TREE_V2))
+		return 0;
+
+	bytenr = btrfs_super_block_group_root(sb);
+	gen = btrfs_super_block_group_root_generation(sb);
+	level = btrfs_super_block_group_root_level(sb);
+	ret = load_super_root(fs_info->block_group_root, bytenr, gen, level);
+	if (ret)
+		btrfs_warn(fs_info, "couldn't read block group root");
 	return ret;
 }
 
@@ -2983,6 +3008,16 @@ static int __cold init_tree_roots(struct btrfs_fs_info *fs_info)
 	int ret = 0;
 	int i;
 
+	if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2)) {
+		struct btrfs_root *root;
+		root = btrfs_alloc_root(fs_info,
+					BTRFS_BLOCK_GROUP_TREE_OBJECTID,
+					GFP_KERNEL);
+		if (!root)
+			return -ENOMEM;
+		fs_info->block_group_root = root;
+	}
+
 	for (i = 0; i < BTRFS_NUM_BACKUP_ROOTS; i++) {
 		if (handle_error) {
 			if (!IS_ERR(tree_root->node))
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
index 5e8bef4b7563..2e10514ecda8 100644
--- a/fs/btrfs/disk-io.h
+++ b/fs/btrfs/disk-io.h
@@ -111,6 +111,8 @@ static inline struct btrfs_root *btrfs_grab_root(struct btrfs_root *root)
 
 static inline struct btrfs_root *btrfs_block_group_root(struct btrfs_fs_info *fs_info)
 {
+	if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2))
+		return fs_info->block_group_root;
 	return btrfs_extent_root(fs_info, 0);
 }
 
diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c
index 0775ae9f4419..524fdb0ddd74 100644
--- a/fs/btrfs/print-tree.c
+++ b/fs/btrfs/print-tree.c
@@ -23,6 +23,7 @@ static const struct root_name_map root_map[] = {
 	{ BTRFS_QUOTA_TREE_OBJECTID,		"QUOTA_TREE"		},
 	{ BTRFS_UUID_TREE_OBJECTID,		"UUID_TREE"		},
 	{ BTRFS_FREE_SPACE_TREE_OBJECTID,	"FREE_SPACE_TREE"	},
+	{ BTRFS_BLOCK_GROUP_TREE_OBJECTID,	"BLOCK_GROUP_TREE"	},
 	{ BTRFS_DATA_RELOC_TREE_OBJECTID,	"DATA_RELOC_TREE"	},
 };
 
diff --git a/include/trace/events/btrfs.h b/include/trace/events/btrfs.h
index 0d729664b4b4..f068ff30d654 100644
--- a/include/trace/events/btrfs.h
+++ b/include/trace/events/btrfs.h
@@ -53,6 +53,7 @@ struct btrfs_space_info;
 		{ BTRFS_TREE_RELOC_OBJECTID,	"TREE_RELOC"	},	\
 		{ BTRFS_UUID_TREE_OBJECTID,	"UUID_TREE"	},	\
 		{ BTRFS_FREE_SPACE_TREE_OBJECTID, "FREE_SPACE_TREE" },	\
+		{ BTRFS_BLOCK_GROUP_TREE_OBJECTID, "BLOCK_GROUP_TREE" },\
 		{ BTRFS_DATA_RELOC_TREE_OBJECTID, "DATA_RELOC_TREE" })
 
 #define show_root_type(obj)						\
diff --git a/include/uapi/linux/btrfs_tree.h b/include/uapi/linux/btrfs_tree.h
index 5416f1f1a77a..854df92520a1 100644
--- a/include/uapi/linux/btrfs_tree.h
+++ b/include/uapi/linux/btrfs_tree.h
@@ -53,6 +53,9 @@
 /* tracks free space in block groups. */
 #define BTRFS_FREE_SPACE_TREE_OBJECTID 10ULL
 
+/* holds the block group items for extent tree v2. */
+#define BTRFS_BLOCK_GROUP_TREE_OBJECTID 11ULL
+
 /* device stats in the device tree */
 #define BTRFS_DEV_STATS_OBJECTID 0ULL
 
-- 
2.26.3


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

* [PATCH v2 11/11] btrfs: add support for multiple global roots
  2021-12-15 20:39 [PATCH v2 00/11] btrfs: extent tree v2, support for global roots Josef Bacik
                   ` (9 preceding siblings ...)
  2021-12-15 20:40 ` [PATCH v2 10/11] btrfs: add code to support the block group root Josef Bacik
@ 2021-12-15 20:40 ` Josef Bacik
  2022-01-12 15:09 ` [PATCH v2 00/11] btrfs: extent tree v2, support for " Nikolay Borisov
  2022-01-26 15:54 ` David Sterba
  12 siblings, 0 replies; 20+ messages in thread
From: Josef Bacik @ 2021-12-15 20:40 UTC (permalink / raw)
  To: linux-btrfs, kernel-team

With extent tree v2 you will be able to create multiple csum, extent,
and free space trees.  They will be used based on the block group, which
will now use the block_group_item->chunk_objectid to point to the set of
global roots that it will use.  When allocating new block groups we'll
simply mod the gigabyte offset of the block group against the number of
global roots we have and that will be the block groups global id.

From there we can take the bytenr that we're modifying in the respective
tree, look up the block group and get that block groups corresponding
global root id.  From there we can get to the appropriate global root
for that bytenr.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/block-group.c     | 25 +++++++++++++++++--
 fs/btrfs/block-group.h     |  1 +
 fs/btrfs/ctree.h           |  2 ++
 fs/btrfs/disk-io.c         | 49 +++++++++++++++++++++++++++++++-------
 fs/btrfs/free-space-tree.c |  2 ++
 fs/btrfs/transaction.c     | 15 ++++++++++++
 fs/btrfs/tree-checker.c    | 21 ++++++++++++++--
 7 files changed, 102 insertions(+), 13 deletions(-)

diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
index 1db24e6d6d90..6215bc53b219 100644
--- a/fs/btrfs/block-group.c
+++ b/fs/btrfs/block-group.c
@@ -1997,6 +1997,7 @@ static int read_one_block_group(struct btrfs_fs_info *info,
 	cache->length = key->offset;
 	cache->used = btrfs_stack_block_group_used(bgi);
 	cache->flags = btrfs_stack_block_group_flags(bgi);
+	cache->global_root_id = btrfs_stack_block_group_chunk_objectid(bgi);
 
 	set_free_space_tree_thresholds(cache);
 
@@ -2279,7 +2280,7 @@ static int insert_block_group_item(struct btrfs_trans_handle *trans,
 	spin_lock(&block_group->lock);
 	btrfs_set_stack_block_group_used(&bgi, block_group->used);
 	btrfs_set_stack_block_group_chunk_objectid(&bgi,
-				BTRFS_FIRST_CHUNK_TREE_OBJECTID);
+						   block_group->global_root_id);
 	btrfs_set_stack_block_group_flags(&bgi, block_group->flags);
 	key.objectid = block_group->start;
 	key.type = BTRFS_BLOCK_GROUP_ITEM_KEY;
@@ -2435,6 +2436,24 @@ void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans)
 	btrfs_trans_release_chunk_metadata(trans);
 }
 
+/*
+ * For extent tree v2 we use the block_group_item->chunk_offset to point at our
+ * global root id.  For v1 it's always set to BTRFS_FIRST_CHUNK_TREE_OBJECTID.
+ */
+static u64 calculate_global_root_id(struct btrfs_fs_info *fs_info, u64 offset)
+{
+	u64 div = SZ_1G;
+
+	if (!btrfs_fs_incompat(fs_info, EXTENT_TREE_V2))
+		return BTRFS_FIRST_CHUNK_TREE_OBJECTID;
+
+	/* If we have a smaller fs index based on 128m. */
+	if (btrfs_super_total_bytes(fs_info->super_copy) <= (SZ_1G * 10ULL))
+		div = SZ_128M;
+
+	return (div_u64(offset, div) % fs_info->nr_global_roots);
+}
+
 struct btrfs_block_group *btrfs_make_block_group(struct btrfs_trans_handle *trans,
 						 u64 bytes_used, u64 type,
 						 u64 chunk_offset, u64 size)
@@ -2455,6 +2474,8 @@ struct btrfs_block_group *btrfs_make_block_group(struct btrfs_trans_handle *tran
 	cache->flags = type;
 	cache->last_byte_to_unpin = (u64)-1;
 	cache->cached = BTRFS_CACHE_FINISHED;
+	cache->global_root_id = calculate_global_root_id(fs_info, cache->start);
+
 	if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE))
 		cache->needs_free_space = 1;
 
@@ -2671,7 +2692,7 @@ static int update_block_group_item(struct btrfs_trans_handle *trans,
 	bi = btrfs_item_ptr_offset(leaf, path->slots[0]);
 	btrfs_set_stack_block_group_used(&bgi, cache->used);
 	btrfs_set_stack_block_group_chunk_objectid(&bgi,
-			BTRFS_FIRST_CHUNK_TREE_OBJECTID);
+						   cache->global_root_id);
 	btrfs_set_stack_block_group_flags(&bgi, cache->flags);
 	write_extent_buffer(leaf, &bgi, bi, sizeof(bgi));
 	btrfs_mark_buffer_dirty(leaf);
diff --git a/fs/btrfs/block-group.h b/fs/btrfs/block-group.h
index 5878b7ce3b78..93aabc68bb6a 100644
--- a/fs/btrfs/block-group.h
+++ b/fs/btrfs/block-group.h
@@ -68,6 +68,7 @@ struct btrfs_block_group {
 	u64 bytes_super;
 	u64 flags;
 	u64 cache_generation;
+	u64 global_root_id;
 
 	/*
 	 * If the free space extent count exceeds this number, convert the block
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 40c1e5869cef..2a5ed393eb21 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -1056,6 +1056,8 @@ struct btrfs_fs_info {
 	spinlock_t relocation_bg_lock;
 	u64 data_reloc_bg;
 
+	u64 nr_global_roots;
+
 	spinlock_t zone_active_bgs_lock;
 	struct list_head zone_active_bgs;
 
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index b31f20a9da2f..2a70f61345aa 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1296,12 +1296,32 @@ struct btrfs_root *btrfs_global_root(struct btrfs_fs_info *fs_info,
 	return root;
 }
 
+static u64 btrfs_global_root_id(struct btrfs_fs_info *fs_info, u64 bytenr)
+{
+	struct btrfs_block_group *block_group;
+	u64 ret;
+
+	if (!btrfs_fs_incompat(fs_info, EXTENT_TREE_V2))
+		return 0;
+
+	if (likely(bytenr))
+		block_group = btrfs_lookup_block_group(fs_info, bytenr);
+	else
+		block_group = btrfs_lookup_first_block_group(fs_info, bytenr);
+	ASSERT(block_group);
+	if (!block_group)
+		return 0;
+	ret = block_group->global_root_id;
+	btrfs_put_block_group(block_group);
+	return ret;
+}
+
 struct btrfs_root *btrfs_csum_root(struct btrfs_fs_info *fs_info, u64 bytenr)
 {
 	struct btrfs_key key = {
 		.objectid = BTRFS_CSUM_TREE_OBJECTID,
 		.type = BTRFS_ROOT_ITEM_KEY,
-		.offset = 0,
+		.offset = btrfs_global_root_id(fs_info, bytenr),
 	};
 
 	return btrfs_global_root(fs_info, &key);
@@ -1312,7 +1332,7 @@ struct btrfs_root *btrfs_extent_root(struct btrfs_fs_info *fs_info, u64 bytenr)
 	struct btrfs_key key = {
 		.objectid = BTRFS_EXTENT_TREE_OBJECTID,
 		.type = BTRFS_ROOT_ITEM_KEY,
-		.offset = 0,
+		.offset = btrfs_global_root_id(fs_info, bytenr),
 	};
 
 	return btrfs_global_root(fs_info, &key);
@@ -2095,7 +2115,6 @@ static void backup_super_roots(struct btrfs_fs_info *info)
 {
 	const int next_backup = info->backup_root_index;
 	struct btrfs_root_backup *root_backup;
-	struct btrfs_root *csum_root = btrfs_csum_root(info, 0);
 
 	root_backup = info->super_for_commit->super_roots + next_backup;
 
@@ -2129,6 +2148,7 @@ static void backup_super_roots(struct btrfs_fs_info *info)
 			btrfs_header_level(info->block_group_root->node));
 	} else {
 		struct btrfs_root *extent_root = btrfs_extent_root(info, 0);
+		struct btrfs_root *csum_root = btrfs_csum_root(info, 0);
 
 		btrfs_set_backup_extent_root(root_backup,
 					     extent_root->node->start);
@@ -2136,6 +2156,12 @@ static void backup_super_roots(struct btrfs_fs_info *info)
 				btrfs_header_generation(extent_root->node));
 		btrfs_set_backup_extent_root_level(root_backup,
 					btrfs_header_level(extent_root->node));
+
+		btrfs_set_backup_csum_root(root_backup, csum_root->node->start);
+		btrfs_set_backup_csum_root_gen(root_backup,
+					       btrfs_header_generation(csum_root->node));
+		btrfs_set_backup_csum_root_level(root_backup,
+						 btrfs_header_level(csum_root->node));
 	}
 
 	/*
@@ -2157,12 +2183,6 @@ static void backup_super_roots(struct btrfs_fs_info *info)
 	btrfs_set_backup_dev_root_level(root_backup,
 				       btrfs_header_level(info->dev_root->node));
 
-	btrfs_set_backup_csum_root(root_backup, csum_root->node->start);
-	btrfs_set_backup_csum_root_gen(root_backup,
-				       btrfs_header_generation(csum_root->node));
-	btrfs_set_backup_csum_root_level(root_backup,
-					 btrfs_header_level(csum_root->node));
-
 	btrfs_set_backup_total_bytes(root_backup,
 			     btrfs_super_total_bytes(info->super_copy));
 	btrfs_set_backup_bytes_used(root_backup,
@@ -2550,6 +2570,7 @@ static int load_global_roots_objectid(struct btrfs_root *tree_root,
 {
 	struct btrfs_fs_info *fs_info = tree_root->fs_info;
 	struct btrfs_root *root;
+	u64 max_global_id = 0;
 	int ret;
 	struct btrfs_key key = {
 		.objectid = objectid,
@@ -2585,6 +2606,13 @@ static int load_global_roots_objectid(struct btrfs_root *tree_root,
 			break;
 		btrfs_release_path(path);
 
+		/*
+		 * Just worry about this for extent tree, it'll be the same for
+		 * everybody.
+		 */
+		if (objectid == BTRFS_EXTENT_TREE_OBJECTID)
+			max_global_id = max(max_global_id, key.offset);
+
 		found = true;
 		root = read_tree_root_path(tree_root, path, &key);
 		if (IS_ERR(root)) {
@@ -2602,6 +2630,9 @@ static int load_global_roots_objectid(struct btrfs_root *tree_root,
 	}
 	btrfs_release_path(path);
 
+	if (objectid == BTRFS_EXTENT_TREE_OBJECTID)
+		fs_info->nr_global_roots = max_global_id + 1;
+
 	if (!found || ret) {
 		if (objectid == BTRFS_CSUM_TREE_OBJECTID)
 			set_bit(BTRFS_FS_STATE_NO_CSUMS, &fs_info->fs_state);
diff --git a/fs/btrfs/free-space-tree.c b/fs/btrfs/free-space-tree.c
index a3eb6bce2a4d..67d723b9ce0f 100644
--- a/fs/btrfs/free-space-tree.c
+++ b/fs/btrfs/free-space-tree.c
@@ -25,6 +25,8 @@ static struct btrfs_root *btrfs_free_space_root(
 		.offset = 0,
 	};
 
+	if (btrfs_fs_incompat(block_group->fs_info, EXTENT_TREE_V2))
+		key.offset = block_group->global_root_id;
 	return btrfs_global_root(block_group->fs_info, &key);
 }
 
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 03de89b45f27..0b73b3ad1e57 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -1850,6 +1850,14 @@ static void update_super_roots(struct btrfs_fs_info *fs_info)
 		super->cache_generation = 0;
 	if (test_bit(BTRFS_FS_UPDATE_UUID_TREE_GEN, &fs_info->flags))
 		super->uuid_tree_generation = root_item->generation;
+
+	if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2)) {
+		root_item = &fs_info->block_group_root->root_item;
+
+		super->block_group_root = root_item->bytenr;
+		super->block_group_root_generation = root_item->generation;
+		super->block_group_root_level = root_item->level;
+	}
 }
 
 int btrfs_transaction_in_commit(struct btrfs_fs_info *info)
@@ -2269,6 +2277,13 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
 	list_add_tail(&fs_info->chunk_root->dirty_list,
 		      &cur_trans->switch_commits);
 
+	if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2)) {
+		btrfs_set_root_node(&fs_info->block_group_root->root_item,
+				    fs_info->block_group_root->node);
+		list_add_tail(&fs_info->block_group_root->dirty_list,
+			      &cur_trans->switch_commits);
+	}
+
 	switch_commit_roots(trans);
 
 	ASSERT(list_empty(&cur_trans->dirty_bgs));
diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c
index ef7d624b0672..96b687e0f820 100644
--- a/fs/btrfs/tree-checker.c
+++ b/fs/btrfs/tree-checker.c
@@ -639,8 +639,10 @@ static void block_group_err(const struct extent_buffer *eb, int slot,
 static int check_block_group_item(struct extent_buffer *leaf,
 				  struct btrfs_key *key, int slot)
 {
+	struct btrfs_fs_info *fs_info = leaf->fs_info;
 	struct btrfs_block_group_item bgi;
 	u32 item_size = btrfs_item_size(leaf, slot);
+	u64 chunk_objectid;
 	u64 flags;
 	u64 type;
 
@@ -663,8 +665,23 @@ static int check_block_group_item(struct extent_buffer *leaf,
 
 	read_extent_buffer(leaf, &bgi, btrfs_item_ptr_offset(leaf, slot),
 			   sizeof(bgi));
-	if (unlikely(btrfs_stack_block_group_chunk_objectid(&bgi) !=
-		     BTRFS_FIRST_CHUNK_TREE_OBJECTID)) {
+	chunk_objectid = btrfs_stack_block_group_chunk_objectid(&bgi);
+	if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2)) {
+		/*
+		 * We don't init the nr_global_roots until we load the global
+		 * roots, so this could be 0 at mount time.  If it's 0 we'll
+		 * just assume we're fine, and later we'll check against our
+		 * actual value.
+		 */
+		if (unlikely(fs_info->nr_global_roots &&
+			     chunk_objectid >= fs_info->nr_global_roots)) {
+			block_group_err(leaf, slot,
+	"invalid block group global root id, have %llu, needs to be <= %llu",
+					chunk_objectid,
+					fs_info->nr_global_roots);
+			return -EUCLEAN;
+		}
+	} else if (unlikely(chunk_objectid != BTRFS_FIRST_CHUNK_TREE_OBJECTID)) {
 		block_group_err(leaf, slot,
 		"invalid block group chunk objectid, have %llu expect %llu",
 				btrfs_stack_block_group_chunk_objectid(&bgi),
-- 
2.26.3


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

* Re: [PATCH v2 00/11] btrfs: extent tree v2, support for global roots
  2021-12-15 20:39 [PATCH v2 00/11] btrfs: extent tree v2, support for global roots Josef Bacik
                   ` (10 preceding siblings ...)
  2021-12-15 20:40 ` [PATCH v2 11/11] btrfs: add support for multiple global roots Josef Bacik
@ 2022-01-12 15:09 ` Nikolay Borisov
  2022-01-26 15:52   ` David Sterba
  2022-01-26 15:54 ` David Sterba
  12 siblings, 1 reply; 20+ messages in thread
From: Nikolay Borisov @ 2022-01-12 15:09 UTC (permalink / raw)
  To: Josef Bacik, linux-btrfs, kernel-team



On 15.12.21 г. 22:39, Josef Bacik wrote:
> v1->v2:
> - Disabled some more operations for extent tree v2 that I found were problematic
>   in testing.
> - Rebased onto a recent misc-next
> 
> --- Original email ---
> Hello,
> 
> This is the kernel side of the global roots and block group root support.  The
> motivation for this change is described in the progs patches.  The important
> part here is I've disabled qgroups and balance for now, this support will be
> added back later.  I've also changed global block rsv size calculation, but it's
> exactly the same result for !EXTENT_TREE_V2.  And finally there's the support
> for loading the roots.  This doesn't panic and doesn't introduce any performance
> regressions.  I've also hidden the support behind CONFIG_BTRFS_DEBUG so it
> doesn't get used accidentally.  Thanks,
> 
> Josef
> 
> Josef Bacik (11):
>   btrfs: add definition for EXTENT_TREE_V2
>   btrfs: disable balance for extent tree v2 for now
>   btrfs: disable device manipulation ioctl's EXTENT_TREE_V2
>   btrfs: disable qgroups in extent tree v2
>   btrfs: disable scrub for extent-tree-v2
>   btrfs: disable snapshot creation/deletion for extent tree v2
>   btrfs: disable space cache related mount options for extent tree v2
>   btrfs: tree-checker: don't fail on empty extent roots for extent tree
>     v2
>   btrfs: abstract out loading the tree root
>   btrfs: add code to support the block group root
>   btrfs: add support for multiple global roots
> 
>  fs/btrfs/block-group.c          |  25 ++++-
>  fs/btrfs/block-group.h          |   1 +
>  fs/btrfs/ctree.h                |  46 ++++++++-
>  fs/btrfs/disk-io.c              | 178 +++++++++++++++++++++++---------
>  fs/btrfs/disk-io.h              |   2 +
>  fs/btrfs/free-space-tree.c      |   2 +
>  fs/btrfs/inode.c                |  11 +-
>  fs/btrfs/ioctl.c                |  29 ++++++
>  fs/btrfs/print-tree.c           |   1 +
>  fs/btrfs/qgroup.c               |   6 ++
>  fs/btrfs/super.c                |  20 ++++
>  fs/btrfs/sysfs.c                |   5 +-
>  fs/btrfs/transaction.c          |  15 +++
>  fs/btrfs/tree-checker.c         |  35 ++++++-
>  fs/btrfs/volumes.c              |  11 ++
>  include/trace/events/btrfs.h    |   1 +
>  include/uapi/linux/btrfs.h      |   1 +
>  include/uapi/linux/btrfs_tree.h |   3 +
>  18 files changed, 333 insertions(+), 59 deletions(-)
> 

Overall this is a low-risk series and generally looks LGTM. I have a
couple of points which apply too all patches and I'm gonna list them here:

1. This is minor but might be a bit more informative - instead of
returning -EINVAL when an operation which is forbidden returning
-EOPNOTSUPP is closer to what is actually meant. ANd not that something
is invalid per-se. This is a minor point given for now this is purely a
developer feature.

2. The extent tree would be in development for quite some time, perhaps
at least 3-4 release if not more, during that time the code will be
sprinkled with the checks for the forbidden ops and even everyone will
be paying the (arguably small cost) of having them in the code. My point
is can't those compatibility checks be also gated behind
CONFIG_BTRFS_DEBUG? Eventually they will be removed but until this time
comes we'll have them in the respective call paths.

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

* Re: [PATCH v2 10/11] btrfs: add code to support the block group root
  2021-12-15 20:40 ` [PATCH v2 10/11] btrfs: add code to support the block group root Josef Bacik
@ 2022-01-12 15:16   ` Nikolay Borisov
  2022-01-26 15:34     ` David Sterba
  0 siblings, 1 reply; 20+ messages in thread
From: Nikolay Borisov @ 2022-01-12 15:16 UTC (permalink / raw)
  To: Josef Bacik, linux-btrfs, kernel-team



On 15.12.21 г. 22:40, Josef Bacik wrote:
> This code adds the on disk structures for the block group root, which
> will hold the block group items for extent tree v2.
> 
> Signed-off-by: Josef Bacik <josef@toxicpanda.com>

Ok, this is formally not needed for the extent v2 but the major rework
for extent v2 is used to introduce this change and it's idea is to speed
up fs mount right? If so I'd like this to be stated more explicitly in
the changelog of the patch. I guess this can be done by David as well.

<snip>

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

* Re: [PATCH v2 09/11] btrfs: abstract out loading the tree root
  2021-12-15 20:40 ` [PATCH v2 09/11] btrfs: abstract out loading the tree root Josef Bacik
@ 2022-01-13  9:20   ` Nikolay Borisov
  2022-01-26 15:32     ` David Sterba
  0 siblings, 1 reply; 20+ messages in thread
From: Nikolay Borisov @ 2022-01-13  9:20 UTC (permalink / raw)
  To: Josef Bacik, linux-btrfs, kernel-team



On 15.12.21 г. 22:40, Josef Bacik wrote:
> We're going to be adding more roots that need to be loaded from the
> super block, so abstract out the code to read the tree_root from the
> super block, and use this helper for the chunk root as well.  This will
> make it simpler to load the new trees in the future.
> 
> Signed-off-by: Josef Bacik <josef@toxicpanda.com>
> ---
>  fs/btrfs/disk-io.c | 82 ++++++++++++++++++++++++++--------------------
>  1 file changed, 47 insertions(+), 35 deletions(-)
> 
> diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
> index 5c598e124c25..ddc3b9fcbabc 100644
> --- a/fs/btrfs/disk-io.c
> +++ b/fs/btrfs/disk-io.c
> @@ -2934,6 +2934,46 @@ static int btrfs_validate_write_super(struct btrfs_fs_info *fs_info,
>  	return ret;
>  }
>  
> +static int load_super_root(struct btrfs_root *root, u64 bytenr, u64 gen,
> +			   int level)

nit: 'super' here sounds a bit off. Perhaps 'meta' (no pun intended!) or
'main' or 'core' or simply 'load_root' ?

> +{
> +	int ret = 0;
> +
> +	root->node = read_tree_block(root->fs_info, bytenr,
> +				     root->root_key.objectid, gen, level, NULL);
> +	if (IS_ERR(root->node)) {
> +		ret = PTR_ERR(root->node);
> +		root->node = NULL;
> +	} else if (!extent_buffer_uptodate(root->node)) {
> +		free_extent_buffer(root->node);
> +		root->node = NULL;
> +		ret = -EIO;
> +	}
> +
> +	if (ret)
> +		return ret;
> +
> +	btrfs_set_root_node(&root->root_item, root->node);
> +	root->commit_root = btrfs_root_node(root);
> +	btrfs_set_root_refs(&root->root_item, 1);
> +	return ret;
> +}
> +
> +static int load_important_roots(struct btrfs_fs_info *fs_info)

nit: This name is somewhat colloquial and naming something important
doesn't really convey much useful information about what it is. So I'm
wondering what a more becoming name might look like. I was thinking of
load_main_roots - but I have a feeling it's not much better than
'important' or load_core_roots but this introduces 'core' as a new
concept which we haven't had so far in the code.

> +{
> +	struct btrfs_super_block *sb = fs_info->super_copy;
> +	u64 gen, bytenr;
> +	int level, ret;
> +
> +	bytenr = btrfs_super_root(sb);
> +	gen = btrfs_super_generation(sb);
> +	level = btrfs_super_root_level(sb);
> +	ret = load_super_root(fs_info->tree_root, bytenr, gen, level);
> +	if (ret)
> +		btrfs_warn(fs_info, "couldn't read tree root");
> +	return ret;
> +}
> +
>  static int __cold init_tree_roots(struct btrfs_fs_info *fs_info)
>  {
>  	int backup_index = find_newest_super_backup(fs_info);

<snip>

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

* Re: [PATCH v2 09/11] btrfs: abstract out loading the tree root
  2022-01-13  9:20   ` Nikolay Borisov
@ 2022-01-26 15:32     ` David Sterba
  0 siblings, 0 replies; 20+ messages in thread
From: David Sterba @ 2022-01-26 15:32 UTC (permalink / raw)
  To: Nikolay Borisov; +Cc: Josef Bacik, linux-btrfs, kernel-team

On Thu, Jan 13, 2022 at 11:20:43AM +0200, Nikolay Borisov wrote:
> 
> 
> On 15.12.21 г. 22:40, Josef Bacik wrote:
> > We're going to be adding more roots that need to be loaded from the
> > super block, so abstract out the code to read the tree_root from the
> > super block, and use this helper for the chunk root as well.  This will
> > make it simpler to load the new trees in the future.
> > 
> > Signed-off-by: Josef Bacik <josef@toxicpanda.com>
> > ---
> >  fs/btrfs/disk-io.c | 82 ++++++++++++++++++++++++++--------------------
> >  1 file changed, 47 insertions(+), 35 deletions(-)
> > 
> > diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
> > index 5c598e124c25..ddc3b9fcbabc 100644
> > --- a/fs/btrfs/disk-io.c
> > +++ b/fs/btrfs/disk-io.c
> > @@ -2934,6 +2934,46 @@ static int btrfs_validate_write_super(struct btrfs_fs_info *fs_info,
> >  	return ret;
> >  }
> >  
> > +static int load_super_root(struct btrfs_root *root, u64 bytenr, u64 gen,
> > +			   int level)
> 
> nit: 'super' here sounds a bit off. Perhaps 'meta' (no pun intended!) or
> 'main' or 'core' or simply 'load_root' ?

Yeah as we have 'superblock' referred to as 'super', so this is
confusing. I don't have suggestion for final name and will leave as it
is. Looking to dictionary there are several terms we haven't used so
far, like pivotal, crucial, essential, principal, cardinal, major, or
maybe even central.

> > +{
> > +	int ret = 0;
> > +
> > +	root->node = read_tree_block(root->fs_info, bytenr,
> > +				     root->root_key.objectid, gen, level, NULL);
> > +	if (IS_ERR(root->node)) {
> > +		ret = PTR_ERR(root->node);
> > +		root->node = NULL;
> > +	} else if (!extent_buffer_uptodate(root->node)) {
> > +		free_extent_buffer(root->node);
> > +		root->node = NULL;
> > +		ret = -EIO;
> > +	}
> > +
> > +	if (ret)
> > +		return ret;
> > +
> > +	btrfs_set_root_node(&root->root_item, root->node);
> > +	root->commit_root = btrfs_root_node(root);
> > +	btrfs_set_root_refs(&root->root_item, 1);
> > +	return ret;
> > +}
> > +
> > +static int load_important_roots(struct btrfs_fs_info *fs_info)
> 
> nit: This name is somewhat colloquial and naming something important
> doesn't really convey much useful information about what it is. So I'm
> wondering what a more becoming name might look like. I was thinking of
> load_main_roots - but I have a feeling it's not much better than
> 'important' or load_core_roots but this introduces 'core' as a new
> concept which we haven't had so far in the code.

Same here, naming changes in the future expected.

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

* Re: [PATCH v2 10/11] btrfs: add code to support the block group root
  2022-01-12 15:16   ` Nikolay Borisov
@ 2022-01-26 15:34     ` David Sterba
  2022-01-26 15:58       ` Nikolay Borisov
  0 siblings, 1 reply; 20+ messages in thread
From: David Sterba @ 2022-01-26 15:34 UTC (permalink / raw)
  To: Nikolay Borisov; +Cc: Josef Bacik, linux-btrfs, kernel-team

On Wed, Jan 12, 2022 at 05:16:29PM +0200, Nikolay Borisov wrote:
> 
> 
> On 15.12.21 г. 22:40, Josef Bacik wrote:
> > This code adds the on disk structures for the block group root, which
> > will hold the block group items for extent tree v2.
> > 
> > Signed-off-by: Josef Bacik <josef@toxicpanda.com>
> 
> Ok, this is formally not needed for the extent v2 but the major rework
> for extent v2 is used to introduce this change and it's idea is to speed
> up fs mount right? If so I'd like this to be stated more explicitly in
> the changelog of the patch. I guess this can be done by David as well.

You mean that extent tree v2 is mainly for speeding up mount? AFAIK it's
only one of the improvements it brings. I'm not sure what you'd like to
see in the commit message but could update it eventually.

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

* Re: [PATCH v2 00/11] btrfs: extent tree v2, support for global roots
  2022-01-12 15:09 ` [PATCH v2 00/11] btrfs: extent tree v2, support for " Nikolay Borisov
@ 2022-01-26 15:52   ` David Sterba
  0 siblings, 0 replies; 20+ messages in thread
From: David Sterba @ 2022-01-26 15:52 UTC (permalink / raw)
  To: Nikolay Borisov; +Cc: Josef Bacik, linux-btrfs, kernel-team

On Wed, Jan 12, 2022 at 05:09:15PM +0200, Nikolay Borisov wrote:
> Overall this is a low-risk series and generally looks LGTM. I have a
> couple of points which apply too all patches and I'm gonna list them here:
> 
> 1. This is minor but might be a bit more informative - instead of
> returning -EINVAL when an operation which is forbidden returning
> -EOPNOTSUPP is closer to what is actually meant. ANd not that something
> is invalid per-se. This is a minor point given for now this is purely a
> developer feature.

Makes sense to use EOPNOTSUPP.

> 2. The extent tree would be in development for quite some time, perhaps
> at least 3-4 release if not more, during that time the code will be
> sprinkled with the checks for the forbidden ops and even everyone will
> be paying the (arguably small cost) of having them in the code. My point
> is can't those compatibility checks be also gated behind
> CONFIG_BTRFS_DEBUG? Eventually they will be removed but until this time
> comes we'll have them in the respective call paths.

That's a good point, we could make it compile-time condition with some
magic that should remove any cost of the checks. Something like

	if (EXTENT_V2_ENABLED(fs_info)) {
		...
	}

where the macro is

#ifdef CONFIG_BTRFS_DEBUG
#define EXTENT_V2_ENABLED(fs_info) 	btrfs_incompat(fs_info, EXTENT_TREE_V2)
#else
#define EXTENT_V2_ENABLED(fs_info)	false
#endif

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

* Re: [PATCH v2 00/11] btrfs: extent tree v2, support for global roots
  2021-12-15 20:39 [PATCH v2 00/11] btrfs: extent tree v2, support for global roots Josef Bacik
                   ` (11 preceding siblings ...)
  2022-01-12 15:09 ` [PATCH v2 00/11] btrfs: extent tree v2, support for " Nikolay Borisov
@ 2022-01-26 15:54 ` David Sterba
  12 siblings, 0 replies; 20+ messages in thread
From: David Sterba @ 2022-01-26 15:54 UTC (permalink / raw)
  To: Josef Bacik; +Cc: linux-btrfs, kernel-team

On Wed, Dec 15, 2021 at 03:39:57PM -0500, Josef Bacik wrote:
> v1->v2:
> - Disabled some more operations for extent tree v2 that I found were problematic
>   in testing.
> - Rebased onto a recent misc-next
> 
> --- Original email ---
> Hello,
> 
> This is the kernel side of the global roots and block group root support.  The
> motivation for this change is described in the progs patches.  The important
> part here is I've disabled qgroups and balance for now, this support will be
> added back later.  I've also changed global block rsv size calculation, but it's
> exactly the same result for !EXTENT_TREE_V2.  And finally there's the support
> for loading the roots.  This doesn't panic and doesn't introduce any performance
> regressions.  I've also hidden the support behind CONFIG_BTRFS_DEBUG so it
> doesn't get used accidentally.  Thanks,
> 
> Josef
> 
> Josef Bacik (11):
>   btrfs: add definition for EXTENT_TREE_V2
>   btrfs: disable balance for extent tree v2 for now
>   btrfs: disable device manipulation ioctl's EXTENT_TREE_V2
>   btrfs: disable qgroups in extent tree v2
>   btrfs: disable scrub for extent-tree-v2
>   btrfs: disable snapshot creation/deletion for extent tree v2
>   btrfs: disable space cache related mount options for extent tree v2
>   btrfs: tree-checker: don't fail on empty extent roots for extent tree
>     v2
>   btrfs: abstract out loading the tree root
>   btrfs: add code to support the block group root
>   btrfs: add support for multiple global roots

Added to misc-next. I did only a few tweaks, some messages updates,
added comments. As this is is going to be a long series I'd like to
suggest do do development and cleanup stages. The development so that
you can drop new functional changes but the cleanup seems to be
necessary as there's a lot of repeated code and otherwise it needs to be
kept at sane level regarding the other code.

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

* Re: [PATCH v2 10/11] btrfs: add code to support the block group root
  2022-01-26 15:34     ` David Sterba
@ 2022-01-26 15:58       ` Nikolay Borisov
  0 siblings, 0 replies; 20+ messages in thread
From: Nikolay Borisov @ 2022-01-26 15:58 UTC (permalink / raw)
  To: dsterba, Josef Bacik, linux-btrfs, kernel-team



On 26.01.22 г. 17:34 ч., David Sterba wrote:
> You mean that extent tree v2 is mainly for speeding up mount? AFAIK it's
> only one of the improvements it brings. I'm not sure what you'd like to
> see in the commit message but could update it eventually.

No, I mean the block group root is speeding up the mount, extent v2 has 
a lot more features like the gc, changed metadata blocks management etc.

My point is that the block group root is not strictly required by extent 
v2 just that it's convenient time to be added. I meant this could have 
been made more explicit in the changelog.

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

end of thread, other threads:[~2022-01-26 15:59 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-15 20:39 [PATCH v2 00/11] btrfs: extent tree v2, support for global roots Josef Bacik
2021-12-15 20:39 ` [PATCH v2 01/11] btrfs: add definition for EXTENT_TREE_V2 Josef Bacik
2021-12-15 20:39 ` [PATCH v2 02/11] btrfs: disable balance for extent tree v2 for now Josef Bacik
2021-12-15 20:40 ` [PATCH v2 03/11] btrfs: disable device manipulation ioctl's EXTENT_TREE_V2 Josef Bacik
2021-12-15 20:40 ` [PATCH v2 04/11] btrfs: disable qgroups in extent tree v2 Josef Bacik
2021-12-15 20:40 ` [PATCH v2 05/11] btrfs: disable scrub for extent-tree-v2 Josef Bacik
2021-12-15 20:40 ` [PATCH v2 06/11] btrfs: disable snapshot creation/deletion for extent tree v2 Josef Bacik
2021-12-15 20:40 ` [PATCH v2 07/11] btrfs: disable space cache related mount options " Josef Bacik
2021-12-15 20:40 ` [PATCH v2 08/11] btrfs: tree-checker: don't fail on empty extent roots " Josef Bacik
2021-12-15 20:40 ` [PATCH v2 09/11] btrfs: abstract out loading the tree root Josef Bacik
2022-01-13  9:20   ` Nikolay Borisov
2022-01-26 15:32     ` David Sterba
2021-12-15 20:40 ` [PATCH v2 10/11] btrfs: add code to support the block group root Josef Bacik
2022-01-12 15:16   ` Nikolay Borisov
2022-01-26 15:34     ` David Sterba
2022-01-26 15:58       ` Nikolay Borisov
2021-12-15 20:40 ` [PATCH v2 11/11] btrfs: add support for multiple global roots Josef Bacik
2022-01-12 15:09 ` [PATCH v2 00/11] btrfs: extent tree v2, support for " Nikolay Borisov
2022-01-26 15:52   ` David Sterba
2022-01-26 15:54 ` David Sterba

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