summaryrefslogtreecommitdiff
path: root/c_src
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2025-07-20 22:48:44 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2025-07-20 22:48:44 -0400
commit5023292623e8f1dedc138a20daabbcc4772a0d86 (patch)
tree90c5d600b45107e17e805bdd43d9f316dbcaa15f /c_src
parentfe7acffa4adf1c01374ec2a9ec903cd7b22c1f06 (diff)
bcachefs: Fixes for bucket size calculationsHEADmaster
Make sure bucket size >= btree_node_size when adding a device, and cmd_image_update needs to make sure the metadata device is big enough for the minimum number of buckets. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'c_src')
-rw-r--r--c_src/cmd_image.c5
-rw-r--r--c_src/libbcachefs.c11
2 files changed, 12 insertions, 4 deletions
diff --git a/c_src/cmd_image.c b/c_src/cmd_image.c
index d00d85cf..467378b0 100644
--- a/c_src/cmd_image.c
+++ b/c_src/cmd_image.c
@@ -665,7 +665,10 @@ static int image_update(const char *src_path, const char *dst_image,
goto err;
}
- if (ftruncate(dev_opts.bdev->bd_fd, input_bytes)) {
+ u64 metadata_dev_size = max(input_bytes,
+ c->opts.btree_node_size * BCH_MIN_NR_NBUCKETS);
+
+ if (ftruncate(dev_opts.bdev->bd_fd, metadata_dev_size)) {
fprintf(stderr, "ftruncate error: %m");
goto err;
}
diff --git a/c_src/libbcachefs.c b/c_src/libbcachefs.c
index 935b13ce..6b31d56f 100644
--- a/c_src/libbcachefs.c
+++ b/c_src/libbcachefs.c
@@ -79,9 +79,14 @@ void bch2_sb_layout_init(struct bch_sb_layout *l,
}
}
-static u64 dev_max_bucket_size(u64 dev_size)
+static u64 dev_max_bucket_size(struct bch_opts fs_opts, u64 dev_size)
{
- return rounddown_pow_of_two(dev_size / (BCH_MIN_NR_NBUCKETS * 4));
+ u64 size = rounddown_pow_of_two(dev_size / (BCH_MIN_NR_NBUCKETS * 4));
+ if (opt_defined(fs_opts, btree_node_size))
+ size = max(size, fs_opts.btree_node_size);
+ if (size * BCH_MIN_NR_NBUCKETS > dev_size)
+ die("bucket size %llu too big for device size", size);
+ return size;
}
u64 bch2_pick_bucket_size(struct bch_opts opts, dev_opts_list devs)
@@ -209,7 +214,7 @@ struct bch_sb *bch2_format(struct bch_opt_strs fs_opt_strs,
darray_for_each(devs, i)
if (!opt_defined(i->opts, bucket_size))
opt_set(i->opts, bucket_size,
- min(fs_bucket_size, dev_max_bucket_size(i->fs_size)));
+ min(fs_bucket_size, dev_max_bucket_size(fs_opts, i->fs_size)));
darray_for_each(devs, i) {
i->nbuckets = i->fs_size / i->opts.bucket_size;