diff mbox series

[v2] btrfs-progs: mkfs use same stripe/chunk size as kernel when fs > 50G

Message ID 20220824123919.31208-1-wangyugui@e16-tech.com (mailing list archive)
State New, archived
Headers show
Series [v2] btrfs-progs: mkfs use same stripe/chunk size as kernel when fs > 50G | expand

Commit Message

Wang Yugui Aug. 24, 2022, 12:39 p.m. UTC
When mkfs.btrfs a 1TB device, the allocated chunks are
  Data:             single            8.00MiB
  Metadata:         DUP               1.00GiB
  System:           DUP               8.00MiB
After 'btrfs balance start -f', the allocated chunks are
  Data:             single            1.00GiB
  Metadata:         DUP               1.00GiB
  System:           DUP               32.00MiB

So here we sync stripe/chunk size with kernel for the most common case that
fs size > 50G, although there are still some cases to sync.

Signed-off-by: Wang Yugui <wangyugui@e16-tech.com>
---
changes since v1
  import BTRFS_MAX_DATA_CHUNK_SIZE from kernel

 kernel-shared/volumes.c | 30 +++++++++++++++++++++++-------
 kernel-shared/volumes.h |  2 ++
 2 files changed, 25 insertions(+), 7 deletions(-)
diff mbox series

Patch

diff --git a/kernel-shared/volumes.c b/kernel-shared/volumes.c
index 40032a4b..ac82e767 100644
--- a/kernel-shared/volumes.c
+++ b/kernel-shared/volumes.c
@@ -1189,6 +1189,11 @@  error:
 static void init_alloc_chunk_ctl_policy_regular(struct btrfs_fs_info *info,
 						struct alloc_chunk_ctl *ctl)
 {
+	/*
+	 * kernel: calc_chunk_size() init_alloc_chunk_ctl_policy_regular()
+	 * sync stripe/chunk size with kernel when fs size > 50G
+	 * and keep min btrfs file system size unchanged.
+	 */
 	u64 type = ctl->type;
 	u64 percent_max;
 
@@ -1200,23 +1205,34 @@  static void init_alloc_chunk_ctl_policy_regular(struct btrfs_fs_info *info,
 			ctl->max_stripes = BTRFS_MAX_DEVS_SYS_CHUNK;
 		} else if (type & BTRFS_BLOCK_GROUP_DATA) {
 			ctl->stripe_size = SZ_1G;
-			ctl->max_chunk_size = 10 * ctl->stripe_size;
+			ctl->max_chunk_size = BTRFS_MAX_DATA_CHUNK_SIZE;
 			ctl->min_stripe_size = SZ_64M;
 			ctl->max_stripes = BTRFS_MAX_DEVS(info);
 		} else if (type & BTRFS_BLOCK_GROUP_METADATA) {
-			/* For larger filesystems, use larger metadata chunks */
-			if (info->fs_devices->total_rw_bytes > 50ULL * SZ_1G)
-				ctl->max_chunk_size = SZ_1G;
-			else
-				ctl->max_chunk_size = SZ_256M;
+			ctl->max_chunk_size = SZ_256M;
 			ctl->stripe_size = ctl->max_chunk_size;
 			ctl->min_stripe_size = SZ_32M;
 			ctl->max_stripes = BTRFS_MAX_DEVS(info);
 		}
 	}
 
+	/* sync stripe/chunk size with kernel when fs size > 50G */
+	if (info->fs_devices->total_rw_bytes > 50ULL * SZ_1G){
+		if (type & BTRFS_BLOCK_GROUP_SYSTEM) {
+			ctl->stripe_size = SZ_32M;
+			ctl->max_chunk_size = ctl->stripe_size * 2;
+		} else if (type & BTRFS_BLOCK_GROUP_DATA) {
+			ctl->stripe_size = SZ_1G;
+			ctl->max_chunk_size = BTRFS_MAX_DATA_CHUNK_SIZE;
+		} else if (type & BTRFS_BLOCK_GROUP_METADATA) {
+			ctl->max_chunk_size = SZ_1G;
+			ctl->stripe_size = ctl->max_chunk_size;
+		}
+	}
+
 	/* We don't want a chunk larger than 10% of the FS */
-	percent_max = div_factor(btrfs_super_total_bytes(info->super_copy), 1);
+	ASSERT(btrfs_super_total_bytes(info->super_copy) == info->fs_devices->total_rw_bytes);
+	percent_max = div_factor(info->fs_devices->total_rw_bytes, 1);
 	ctl->max_chunk_size = min(percent_max, ctl->max_chunk_size);
 }
 
diff --git a/kernel-shared/volumes.h b/kernel-shared/volumes.h
index 6e9103a9..f5b6245a 100644
--- a/kernel-shared/volumes.h
+++ b/kernel-shared/volumes.h
@@ -23,6 +23,8 @@ 
 #include "kernel-shared/ctree.h"
 #include "kernel-lib/sizes.h"
 
+#define BTRFS_MAX_DATA_CHUNK_SIZE   (10ULL * SZ_1G)
+
 #define BTRFS_STRIPE_LEN	SZ_64K
 
 struct btrfs_device {