From: Kent Overstreet Date: Mon, 5 Nov 2018 03:09:51 +0000 (-0500) Subject: bcachefs: Assorted fixes for running on very small devices X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=8b335baef22768deb7140e45f32f37ea51a1faf4;p=linux.git bcachefs: Assorted fixes for running on very small devices It's now possible to create and use a filesystem on a 512k device with 4k buckets (though at that size we still waste almost half to internal reserves) Signed-off-by: Kent Overstreet --- diff --git a/fs/bcachefs/alloc_background.c b/fs/bcachefs/alloc_background.c index 1eb39283e7e2c..a4c4a08aed598 100644 --- a/fs/bcachefs/alloc_background.c +++ b/fs/bcachefs/alloc_background.c @@ -374,6 +374,11 @@ static void bch2_rescale_bucket_io_times(struct bch_fs *c, int rw) } } +static inline u64 bucket_clock_freq(u64 capacity) +{ + return max(capacity >> 10, 2028ULL); +} + static void bch2_inc_clock_hand(struct io_timer *timer) { struct bucket_clock *clock = container_of(timer, @@ -412,7 +417,7 @@ static void bch2_inc_clock_hand(struct io_timer *timer) * RW mode (that will be 0 when we're RO, yet we can still service * reads) */ - timer->expire += capacity >> 10; + timer->expire += bucket_clock_freq(capacity); bch2_io_timer_add(&c->io_clock[clock->rw], timer); } @@ -424,7 +429,7 @@ static void bch2_bucket_clock_init(struct bch_fs *c, int rw) clock->hand = 1; clock->rw = rw; clock->rescale.fn = bch2_inc_clock_hand; - clock->rescale.expire = c->capacity >> 10; + clock->rescale.expire = bucket_clock_freq(c->capacity); mutex_init(&clock->lock); } @@ -1011,8 +1016,6 @@ void bch2_recalc_capacity(struct bch_fs *c) for (j = 0; j < RESERVE_NONE; j++) dev_reserve += ca->free[j].size; - dev_reserve += ca->free_inc.size; - dev_reserve += 1; /* btree write point */ dev_reserve += 1; /* copygc write point */ dev_reserve += 1; /* rebalance write point */ diff --git a/fs/bcachefs/alloc_background.h b/fs/bcachefs/alloc_background.h index 245e037fbaea8..33224070e8272 100644 --- a/fs/bcachefs/alloc_background.h +++ b/fs/bcachefs/alloc_background.h @@ -6,7 +6,7 @@ #include "alloc_types.h" #include "debug.h" -#define ALLOC_SCAN_BATCH(ca) ((ca)->mi.nbuckets >> 9) +#define ALLOC_SCAN_BATCH(ca) max_t(size_t, 1, (ca)->mi.nbuckets >> 9) const char *bch2_alloc_invalid(const struct bch_fs *, struct bkey_s_c); int bch2_alloc_to_text(struct bch_fs *, char *, size_t, struct bkey_s_c); diff --git a/fs/bcachefs/bcachefs.h b/fs/bcachefs/bcachefs.h index 5665b93f200b7..22df84b78f4bf 100644 --- a/fs/bcachefs/bcachefs.h +++ b/fs/bcachefs/bcachefs.h @@ -325,7 +325,7 @@ enum bch_time_stats { #define BTREE_RESERVE_MAX (BTREE_MAX_DEPTH + (BTREE_MAX_DEPTH - 1)) /* Size of the freelist we allocate btree nodes from: */ -#define BTREE_NODE_RESERVE (BTREE_RESERVE_MAX * 4) +#define BTREE_NODE_RESERVE BTREE_RESERVE_MAX struct btree; diff --git a/fs/bcachefs/bcachefs_format.h b/fs/bcachefs/bcachefs_format.h index 46355f006793a..d74f1e5c21e0e 100644 --- a/fs/bcachefs/bcachefs_format.h +++ b/fs/bcachefs/bcachefs_format.h @@ -909,6 +909,8 @@ struct bch_sb_field_journal { /* BCH_SB_FIELD_members: */ +#define BCH_MIN_NR_NBUCKETS (1 << 6) + struct bch_member { __uuid_t uuid; __le64 nbuckets; /* device size */ @@ -1391,7 +1393,7 @@ struct jset { LE32_BITMASK(JSET_CSUM_TYPE, struct jset, flags, 0, 4); LE32_BITMASK(JSET_BIG_ENDIAN, struct jset, flags, 4, 5); -#define BCH_JOURNAL_BUCKETS_MIN 20 +#define BCH_JOURNAL_BUCKETS_MIN 8 /* Btree: */ diff --git a/fs/bcachefs/buckets.c b/fs/bcachefs/buckets.c index cfbe3ed41d0e0..28ec8a58319ca 100644 --- a/fs/bcachefs/buckets.c +++ b/fs/bcachefs/buckets.c @@ -887,9 +887,9 @@ int bch2_dev_buckets_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets) size_t btree_reserve = DIV_ROUND_UP(BTREE_NODE_RESERVE, ca->mi.bucket_size / c->opts.btree_node_size); /* XXX: these should be tunable */ - size_t reserve_none = max_t(size_t, 4, nbuckets >> 9); - size_t copygc_reserve = max_t(size_t, 16, nbuckets >> 7); - size_t free_inc_nr = max(max_t(size_t, 16, nbuckets >> 12), + size_t reserve_none = max_t(size_t, 1, nbuckets >> 9); + size_t copygc_reserve = max_t(size_t, 2, nbuckets >> 7); + size_t free_inc_nr = max(max_t(size_t, 1, nbuckets >> 12), btree_reserve); bool resize = ca->buckets != NULL, start_copygc = ca->copygc_thread != NULL; diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c index e21551e8d6cc5..696e01f4962f6 100644 --- a/fs/bcachefs/recovery.c +++ b/fs/bcachefs/recovery.c @@ -278,7 +278,7 @@ out: return ret; err: fsck_err: - BUG_ON(!ret); + pr_err("Error in recovery: %s (%i)", err, ret); goto out; } @@ -381,6 +381,6 @@ int bch2_fs_initialize(struct bch_fs *c) return 0; err: - BUG_ON(!ret); + pr_err("Error initializing new filesystem: %s (%i)", err, ret); return ret; } diff --git a/fs/bcachefs/super-io.c b/fs/bcachefs/super-io.c index 64c2375302a05..58c35d9665eb3 100644 --- a/fs/bcachefs/super-io.c +++ b/fs/bcachefs/super-io.c @@ -811,7 +811,7 @@ static const char *bch2_sb_validate_members(struct bch_sb *sb, return "Too many buckets"; if (le64_to_cpu(m->nbuckets) - - le16_to_cpu(m->first_bucket) < 1 << 10) + le16_to_cpu(m->first_bucket) < BCH_MIN_NR_NBUCKETS) return "Not enough buckets"; if (le16_to_cpu(m->bucket_size) <