@@ -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);
}
@@ -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 {
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(-)