summaryrefslogtreecommitdiff
path: root/c_src
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2025-07-24 12:02:22 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2025-07-24 12:02:22 -0400
commit43bca0cd6394f3b9c4f5742c2ea918821e71554d (patch)
tree92ec79b6c4a7bf339164e83dae696501ea0c3376 /c_src
parent5023292623e8f1dedc138a20daabbcc4772a0d86 (diff)
Enforce a soft minimum limit of 64k for bucket size
< 64k buckets don't work reliably anymore, we deadlock in the journal when we try to write too big of a journal entry. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'c_src')
-rw-r--r--c_src/libbcachefs.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/c_src/libbcachefs.c b/c_src/libbcachefs.c
index 6b31d56f..2b5ca211 100644
--- a/c_src/libbcachefs.c
+++ b/c_src/libbcachefs.c
@@ -79,14 +79,25 @@ void bch2_sb_layout_init(struct bch_sb_layout *l,
}
}
-static u64 dev_max_bucket_size(struct bch_opts fs_opts, u64 dev_size)
+static u64 dev_bucket_size_clamp(struct bch_opts fs_opts, u64 dev_size, u64 fs_bucket_size)
{
- u64 size = rounddown_pow_of_two(dev_size / (BCH_MIN_NR_NBUCKETS * 4));
+ u64 max_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;
+ max_size = max(max_size, fs_opts.btree_node_size);
+ if (max_size * BCH_MIN_NR_NBUCKETS > dev_size)
+ die("bucket size %llu too big for device size", max_size);
+
+ u64 dev_bucket_size = min(max_size, fs_bucket_size);
+
+ /*
+ * Use encoded_extent_max instead of 64k?
+ */
+
+ while (dev_bucket_size < 64 << 10 &&
+ dev_size / (dev_bucket_size * 2) >= BCH_MIN_NR_NBUCKETS)
+ dev_bucket_size *= 2;
+
+ return dev_bucket_size;
}
u64 bch2_pick_bucket_size(struct bch_opts opts, dev_opts_list devs)
@@ -214,7 +225,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(fs_opts, i->fs_size)));
+ dev_bucket_size_clamp(fs_opts, i->fs_size, fs_bucket_size));
darray_for_each(devs, i) {
i->nbuckets = i->fs_size / i->opts.bucket_size;