summaryrefslogtreecommitdiff
path: root/c_src/libbcachefs.c
diff options
context:
space:
mode:
Diffstat (limited to 'c_src/libbcachefs.c')
-rw-r--r--c_src/libbcachefs.c54
1 files changed, 43 insertions, 11 deletions
diff --git a/c_src/libbcachefs.c b/c_src/libbcachefs.c
index 81ad8cf1..ed84be1b 100644
--- a/c_src/libbcachefs.c
+++ b/c_src/libbcachefs.c
@@ -79,9 +79,25 @@ void bch2_sb_layout_init(struct bch_sb_layout *l,
}
}
-static u64 dev_max_bucket_size(u64 dev_size)
+static u64 dev_bucket_size_clamp(struct bch_opts fs_opts, u64 dev_size, u64 fs_bucket_size)
{
- return 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))
+ 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)
@@ -185,18 +201,20 @@ struct bch_sb *bch2_format(struct bch_opt_strs fs_opt_strs,
dev_opts_list devs)
{
struct bch_sb_handle sb = { NULL };
- unsigned max_dev_block_size = 0;
-
- darray_for_each(devs, i)
- max_dev_block_size = max(max_dev_block_size, get_blocksize(i->bdev->bd_fd));
/* calculate block size: */
- if (!opt_defined(fs_opts, block_size))
+ if (!opt_defined(fs_opts, block_size)) {
+ unsigned max_dev_block_size = 0;
+
+ darray_for_each(devs, i)
+ max_dev_block_size = max(max_dev_block_size, get_blocksize(i->bdev->bd_fd));
+
opt_set(fs_opts, block_size, max_dev_block_size);
+ }
- if (fs_opts.block_size < max_dev_block_size)
- die("blocksize too small: %u, must be greater than device blocksize %u",
- fs_opts.block_size, max_dev_block_size);
+ if (fs_opts.block_size < 512)
+ die("blocksize too small: %u, must be greater than one sector (512 bytes)",
+ fs_opts.block_size);
/* get device size, if it wasn't specified: */
darray_for_each(devs, i)
@@ -209,7 +227,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)));
+ 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;
@@ -574,6 +592,8 @@ struct bchfs_handle bchu_fs_open_by_dev(const char *path, int *idx)
if (len <= 0)
goto read_super;
+ buf[len] = '\0';
+
fs_str = strstr(buf, "bcachefs/");
if (!fs_str)
die("error parsing sysfs");
@@ -737,6 +757,12 @@ noopt:
return NULL;
}
+void bch_remove_arg_from_argv(int *argc, char *argv[], int index)
+{
+ memmove(&argv[index], &argv[index + 1], (*argc - index) * sizeof(char*));
+ (*argc)--;
+}
+
struct bch_opt_strs bch2_cmdline_opts_get(int *argc, char *argv[],
unsigned opt_types)
{
@@ -888,6 +914,8 @@ dev_names bchu_fs_get_devices(struct bchfs_handle fs)
struct dirent *d;
dev_names devs;
+ struct bch_sb *sb = bchu_read_super(fs, -1);
+
darray_init(&devs);
while ((errno = 0), (d = readdir(dir))) {
@@ -918,9 +946,13 @@ dev_names bchu_fs_get_devices(struct bchfs_handle fs)
n.durability = read_file_u64(fs.sysfs_fd, durability_attr);
free(durability_attr);
+ struct bch_member m = bch2_sb_member_get(sb, n.idx);
+ n.state = BCH_MEMBER_STATE(&m);
+
darray_push(&devs, n);
}
+ free(sb);
closedir(dir);
return devs;