From 97de91cb580a2e31352860dfc0642579d21d3b7a Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Thu, 25 Aug 2016 20:55:43 -0800 Subject: minimum number of buckets now 1024 --- libbcache.c | 53 ++++++++++++++++++++++++++++++++++++++++------------- util.h | 2 ++ 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/libbcache.c b/libbcache.c index b565fa8..4cdeb51 100644 --- a/libbcache.c +++ b/libbcache.c @@ -17,6 +17,11 @@ #include "libbcache.h" #include "crypto.h" +#define BCH_MIN_NR_NBUCKETS (1 << 10) + +/* first bucket should start 1 mb in, in sectors: */ +#define FIRST_BUCKET_OFFSET (1 << 11) + void __do_write_sb(int fd, void *sb, size_t bytes) { char zeroes[SB_SECTOR << 9] = {0}; @@ -67,24 +72,46 @@ void bcache_format(struct dev_opts *devs, size_t nr_devs, i->size = get_size(i->path, i->fd); if (!i->bucket_size) { - u64 bytes = i->size << 9; - - if (bytes < 1 << 20) /* 1M device - 256 4k buckets*/ - i->bucket_size = rounddown_pow_of_two(bytes >> 17); - else - /* Max 1M bucket at around 256G */ - i->bucket_size = 8 << min((ilog2(bytes >> 20) / 2), 9U); + /* + * minimum size filesystem we can create, given a bucket + * size: + */ + u64 min_size(unsigned bucket_size) { + return (DIV_ROUND_UP(FIRST_BUCKET_OFFSET, bucket_size) + + BCH_MIN_NR_NBUCKETS) * bucket_size; + } + + if (i->size < min_size(block_size)) + die("cannot format %s, too small (%llu sectors, min %llu)", + i->path, i->size, min_size(block_size)); + + /* Want a bucket size of at least 128k, if possible: */ + i->bucket_size = max(block_size, 256U); + + if (i->size >= min_size(i->bucket_size)) { + unsigned scale = max(1U, + ilog2(i->size / min_size(i->bucket_size)) / 4); + + /* max bucket size 1 mb */ + i->bucket_size = min(i->bucket_size * scale, 1U << 11); + } else { + do { + i->bucket_size /= 2; + } while (i->size < min_size(i->bucket_size)); + } } + /* first bucket: 1 mb in */ + i->first_bucket = DIV_ROUND_UP(FIRST_BUCKET_OFFSET, i->bucket_size); + i->nbuckets = i->size / i->bucket_size; + if (i->bucket_size < block_size) die("Bucket size cannot be smaller than block size"); - i->nbuckets = i->size / i->bucket_size; - i->first_bucket = (23 / i->bucket_size) + 3; - - if (i->nbuckets < 1 << 7) - die("Not enough buckets: %llu, need %u", - i->nbuckets, 1 << 7); + if (i->nbuckets - i->first_bucket < BCH_MIN_NR_NBUCKETS) + die("Not enough buckets: %llu, need %u (bucket size %u)", + i->nbuckets - i->first_bucket, BCH_MIN_NR_NBUCKETS, + i->bucket_size); } /* calculate btree node size: */ diff --git a/util.h b/util.h index 34afccb..463416a 100644 --- a/util.h +++ b/util.h @@ -20,6 +20,8 @@ typedef __s16 s16; typedef __s32 s32; typedef __s64 s64; +#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) + #define min(x, y) ({ \ typeof(x) _min1 = (x); \ typeof(y) _min2 = (y); \ -- cgit v1.2.3