diff --git a/bcache.c b/bcache.c index d0cf7c95..874fe96a 100644 --- a/bcache.c +++ b/bcache.c @@ -581,24 +581,20 @@ int dev_open(const char *dev, bool wipe_bcache) exit(EXIT_FAILURE); } -static unsigned min_bucket_size(int num_bucket_sizes, unsigned *bucket_sizes) -{ - int i; - unsigned min = bucket_sizes[0]; - - for (i = 0; i < num_bucket_sizes; i++) - min = bucket_sizes[i] < min ? bucket_sizes[i] : min; - - return min; -} - void write_cache_sbs(int *fds, struct cache_sb *sb, unsigned block_size, unsigned *bucket_sizes, - int num_bucket_sizes) + int num_bucket_sizes, unsigned btree_node_size) { char uuid_str[40], set_uuid_str[40]; size_t i; - unsigned min_size = min_bucket_size(num_bucket_sizes, bucket_sizes); + + if (!btree_node_size) { + btree_node_size = 512; + + for (i = 0; i < num_bucket_sizes; i++) + btree_node_size = min(btree_node_size, + bucket_sizes[i]); + } sb->offset = SB_SECTOR; sb->version = BCACHE_SB_VERSION_CDEV_V3; @@ -641,7 +637,7 @@ void write_cache_sbs(int *fds, struct cache_sb *sb, for (i = 0; i < sb->nr_in_set; i++) { struct cache_member *m = sb->members + i; - SET_CACHE_BTREE_NODE_SIZE(sb, min_size); + SET_CACHE_BTREE_NODE_SIZE(sb, btree_node_size); sb->disk_uuid = m->uuid; diff --git a/bcache.h b/bcache.h index 39fbb405..597bcee0 100644 --- a/bcache.h +++ b/bcache.h @@ -24,6 +24,12 @@ typedef __s64 s64; #define MAX_PATH 256 #define MAX_DEVS MAX_CACHES_PER_SET +#define min(x, y) ({ \ + typeof(x) _min1 = (x); \ + typeof(y) _min2 = (y); \ + (void) (&_min1 == &_min2); \ + _min1 < _min2 ? _min1 : _min2; }) + #define max(x, y) ({ \ typeof(x) _max1 = (x); \ typeof(y) _max2 = (y); \ @@ -67,7 +73,8 @@ unsigned hatoi_validate(const char *, const char *); void write_backingdev_sb(int, unsigned, unsigned *, unsigned, uint64_t, const char *, uuid_le, uuid_le); int dev_open(const char *, bool); -void write_cache_sbs(int *, struct cache_sb *, unsigned, unsigned *, int); +void write_cache_sbs(int *, struct cache_sb *, unsigned, + unsigned *, int, unsigned); void next_cache_device(struct cache_sb *, unsigned, int, unsigned, bool); unsigned get_blocksize(const char *); long strtoul_or_die(const char *, size_t, const char *); diff --git a/bcacheadm.c b/bcacheadm.c index d9dba68a..f5a7ef62 100644 --- a/bcacheadm.c +++ b/bcacheadm.c @@ -46,6 +46,7 @@ char *backing_devices[MAX_DEVS]; char *backing_dev_labels[MAX_DEVS]; size_t i, nr_backing_devices = 0, nr_cache_devices = 0; unsigned block_size = 0; +unsigned btree_node_size = 0; unsigned bucket_sizes[MAX_DEVS]; int num_bucket_sizes = 0; int writeback = 0, writearound = 0, discard = 0, wipe_bcache = 0; @@ -109,6 +110,12 @@ static int set_block_size(NihOption *option, const char *arg) return 0; } +static int set_btree_node_size(NihOption *option, const char *arg) +{ + btree_node_size = hatoi_validate(arg, "btree node size"); + return 0; +} + static int set_cache(NihOption *option, const char *arg) { bdev = 0; @@ -191,7 +198,10 @@ static NihOption make_bcache_options[] = { //Only one bucket_size supported until a list of bucket sizes is parsed correctly {'b', "bucket", N_("bucket size"), NULL, "size", NULL, set_bucket_sizes}, //Does the default setter automatically convert strings to an int? - {'w', "block", N_("block size (hard sector size of SSD, often 2k"), NULL,"size", NULL, set_block_size}, + {'w', "block", N_("block size (hard sector size of SSD, often 2k"), NULL, "size", NULL, set_block_size}, + + {'n', "btree-node", N_("Btree node size, default 256k"), NULL, "size", NULL, set_btree_node_size}, + {'t', "tier", N_("tier of subsequent devices"), NULL,"#", &tier, NULL}, {'p', "cache_replacement_policy", N_("one of (lru|fifo|random)"), NULL,"policy", &replacement_policy, NULL}, {'o', "data_offset", N_("data offset in sectors"), NULL,"offset", &data_offset, NULL}, @@ -386,7 +396,7 @@ int make_bcache(NihCommand *command, char *const *args) backing_dev_fd[i] = dev_open(backing_devices[i], wipe_bcache); write_cache_sbs(cache_dev_fd, cache_set_sb, block_size, - bucket_sizes, num_bucket_sizes); + bucket_sizes, num_bucket_sizes, btree_node_size); if (writeback) cache_mode = CACHE_MODE_WRITEBACK;