From 6687752a1d0904442dd9946157248b5496bd6e50 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Fri, 9 Aug 2024 14:43:59 -0400 Subject: [PATCH] Update bcachefs sources to 070f7d6a382a bcachefs: bch2_sb_nr_devices() Signed-off-by: Kent Overstreet --- .bcachefs_revision | 2 +- c_src/cmd_dump.c | 10 ++--- c_src/cmd_kill_btree_node.c | 67 +++++++++++++--------------- libbcachefs/alloc_foreground.c | 2 +- libbcachefs/backpointers.c | 15 +++---- libbcachefs/bcachefs_format.h | 3 +- libbcachefs/btree_iter.c | 1 + libbcachefs/btree_iter.h | 42 ++++++++++------- libbcachefs/buckets.c | 12 +++-- libbcachefs/buckets.h | 2 +- libbcachefs/debug.c | 38 ++++------------ libbcachefs/disk_accounting.c | 65 ++++++++++++++++++++++++++- libbcachefs/disk_accounting_format.h | 15 +++---- libbcachefs/replicas.c | 1 - libbcachefs/sb-downgrade.c | 27 ++++++++++- libbcachefs/sb-errors_format.h | 6 ++- 16 files changed, 193 insertions(+), 115 deletions(-) diff --git a/.bcachefs_revision b/.bcachefs_revision index fafb2859..062f1192 100644 --- a/.bcachefs_revision +++ b/.bcachefs_revision @@ -1 +1 @@ -dfc7b2c9433ed926cad881b8fbee55e36105989b +070f7d6a382a0d67628756727751c24f70eb48ea diff --git a/c_src/cmd_dump.c b/c_src/cmd_dump.c index f89d83ae..86ff507d 100644 --- a/c_src/cmd_dump.c +++ b/c_src/cmd_dump.c @@ -70,26 +70,24 @@ static void dump_one_device(struct bch_fs *c, struct bch_dev *ca, int fd, /* Btree: */ for (i = 0; i < BTREE_ID_NR; i++) { struct btree_trans *trans = bch2_trans_get(c); - struct btree_iter iter; - struct btree *b; - __for_each_btree_node(trans, iter, i, POS_MIN, 0, 1, 0, b, ret) { + ret = __for_each_btree_node(trans, iter, i, POS_MIN, 0, 1, 0, b, ({ struct btree_node_iter iter; struct bkey u; struct bkey_s_c k; for_each_btree_node_key_unpack(b, k, &iter, &u) dump_node(c, ca, k, &data); - } + 0; + })); if (ret) die("error %s walking btree nodes", bch2_err_str(ret)); - b = bch2_btree_id_root(c, i)->b; + struct btree *b = bch2_btree_id_root(c, i)->b; if (!btree_node_fake(b)) dump_node(c, ca, bkey_i_to_s_c(&b->key), &data); - bch2_trans_iter_exit(trans, &iter); bch2_trans_put(trans); } diff --git a/c_src/cmd_kill_btree_node.c b/c_src/cmd_kill_btree_node.c index fe551d94..dd230752 100644 --- a/c_src/cmd_kill_btree_node.c +++ b/c_src/cmd_kill_btree_node.c @@ -64,9 +64,6 @@ int cmd_kill_btree_node(int argc, char *argv[]) if (IS_ERR(c)) die("error opening %s: %s", argv[0], bch2_err_str(PTR_ERR(c))); - struct btree_trans *trans = bch2_trans_get(c); - struct btree_iter iter; - struct btree *b; int ret; void *zeroes; @@ -74,46 +71,46 @@ int cmd_kill_btree_node(int argc, char *argv[]) if (ret) die("error %s from posix_memalign", bch2_err_str(ret)); - __for_each_btree_node(trans, iter, btree_id, POS_MIN, 0, level, 0, b, ret) { - if (b->c.level != level) - continue; + ret = bch2_trans_run(c, + __for_each_btree_node(trans, iter, btree_id, POS_MIN, 0, level, 0, b, ({ + if (b->c.level != level) + continue; - if (!node_index) { - struct printbuf buf = PRINTBUF; - bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&b->key)); - bch_info(c, "killing btree node %s", buf.buf); - printbuf_exit(&buf); + int ret2 = 0; + if (!node_index) { + struct printbuf buf = PRINTBUF; + bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&b->key)); + bch_info(c, "killing btree node %s", buf.buf); + printbuf_exit(&buf); - struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(bkey_i_to_s_c(&b->key)); - bkey_for_each_ptr(ptrs, ptr) { - struct bch_dev *ca = bch2_dev_tryget(c, ptr->dev); - if (!ca) - continue; + ret2 = 1; - ret = pwrite(ca->disk_sb.bdev->bd_fd, zeroes, - c->opts.block_size, ptr->offset << 9); - bch2_dev_put(ca); - if (ret != c->opts.block_size) { - bch_err(c, "pwrite error: expected %u got %i %s", - c->opts.block_size, ret, strerror(errno)); - ret = EXIT_FAILURE; - goto done; + struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(bkey_i_to_s_c(&b->key)); + bkey_for_each_ptr(ptrs, ptr) { + struct bch_dev *ca = bch2_dev_tryget(c, ptr->dev); + if (!ca) + continue; + + int ret3 = pwrite(ca->disk_sb.bdev->bd_fd, zeroes, + c->opts.block_size, ptr->offset << 9); + bch2_dev_put(ca); + if (ret3 != c->opts.block_size) { + bch_err(c, "pwrite error: expected %u got %i %s", + c->opts.block_size, ret, strerror(errno)); + ret2 = EXIT_FAILURE; + } } } - ret = 0; - goto done; - } - node_index--; - } - if (ret) + node_index--; + ret2; + }))); + if (ret < 0) bch_err(c, "error %i walking btree nodes", ret); - else + else if (!ret) { bch_err(c, "node at specified index not found"); - ret = EXIT_FAILURE; -done: - bch2_trans_iter_exit(trans, &iter); - bch2_trans_put(trans); + ret = EXIT_FAILURE; + } bch2_fs_stop(c); return ret; diff --git a/libbcachefs/alloc_foreground.c b/libbcachefs/alloc_foreground.c index 922bf2fb..084b03b8 100644 --- a/libbcachefs/alloc_foreground.c +++ b/libbcachefs/alloc_foreground.c @@ -1737,7 +1737,7 @@ void bch2_dev_alloc_debug_to_text(struct printbuf *out, struct bch_dev *ca) printbuf_tabstop_push(out, 16); printbuf_tabstop_push(out, 16); - bch2_dev_usage_to_text(out, &stats); + bch2_dev_usage_to_text(out, ca, &stats); prt_newline(out); diff --git a/libbcachefs/backpointers.c b/libbcachefs/backpointers.c index 3cc02479..9edc4c5f 100644 --- a/libbcachefs/backpointers.c +++ b/libbcachefs/backpointers.c @@ -763,27 +763,22 @@ static int bch2_get_btree_in_memory_pos(struct btree_trans *trans, btree < BTREE_ID_NR && !ret; btree++) { unsigned depth = (BIT_ULL(btree) & btree_leaf_mask) ? 0 : 1; - struct btree_iter iter; - struct btree *b; if (!(BIT_ULL(btree) & btree_leaf_mask) && !(BIT_ULL(btree) & btree_interior_mask)) continue; - bch2_trans_begin(trans); - - __for_each_btree_node(trans, iter, btree, + ret = __for_each_btree_node(trans, iter, btree, btree == start.btree ? start.pos : POS_MIN, - 0, depth, BTREE_ITER_prefetch, b, ret) { + 0, depth, BTREE_ITER_prefetch, b, ({ mem_may_pin -= btree_buf_bytes(b); if (mem_may_pin <= 0) { c->btree_cache.pinned_nodes_end = *end = BBPOS(btree, b->key.k.p); - bch2_trans_iter_exit(trans, &iter); - return 0; + break; } - } - bch2_trans_iter_exit(trans, &iter); + 0; + })); } return ret; diff --git a/libbcachefs/bcachefs_format.h b/libbcachefs/bcachefs_format.h index 7861473b..27f971a5 100644 --- a/libbcachefs/bcachefs_format.h +++ b/libbcachefs/bcachefs_format.h @@ -675,7 +675,8 @@ struct bch_sb_field_ext { x(btree_subvolume_children, BCH_VERSION(1, 6)) \ x(mi_btree_bitmap, BCH_VERSION(1, 7)) \ x(bucket_stripe_sectors, BCH_VERSION(1, 8)) \ - x(disk_accounting_v2, BCH_VERSION(1, 9)) + x(disk_accounting_v2, BCH_VERSION(1, 9)) \ + x(disk_accounting_v3, BCH_VERSION(1, 10)) enum bcachefs_metadata_version { bcachefs_metadata_version_min = 9, diff --git a/libbcachefs/btree_iter.c b/libbcachefs/btree_iter.c index afbb35ab..bfe9f0c1 100644 --- a/libbcachefs/btree_iter.c +++ b/libbcachefs/btree_iter.c @@ -1913,6 +1913,7 @@ err: goto out; } +/* Only kept for -tools */ struct btree *bch2_btree_iter_peek_node_and_restart(struct btree_iter *iter) { struct btree *b; diff --git a/libbcachefs/btree_iter.h b/libbcachefs/btree_iter.h index b241f544..523a2867 100644 --- a/libbcachefs/btree_iter.h +++ b/libbcachefs/btree_iter.h @@ -618,23 +618,35 @@ void bch2_trans_srcu_unlock(struct btree_trans *); u32 bch2_trans_begin(struct btree_trans *); -/* - * XXX - * this does not handle transaction restarts from bch2_btree_iter_next_node() - * correctly - */ -#define __for_each_btree_node(_trans, _iter, _btree_id, _start, \ - _locks_want, _depth, _flags, _b, _ret) \ - for (bch2_trans_node_iter_init((_trans), &(_iter), (_btree_id), \ - _start, _locks_want, _depth, _flags); \ - (_b) = bch2_btree_iter_peek_node_and_restart(&(_iter)), \ - !((_ret) = PTR_ERR_OR_ZERO(_b)) && (_b); \ - (_b) = bch2_btree_iter_next_node(&(_iter))) +#define __for_each_btree_node(_trans, _iter, _btree_id, _start, \ + _locks_want, _depth, _flags, _b, _do) \ +({ \ + bch2_trans_begin((_trans)); \ + \ + struct btree_iter _iter; \ + bch2_trans_node_iter_init((_trans), &_iter, (_btree_id), \ + _start, _locks_want, _depth, _flags); \ + int _ret3 = 0; \ + do { \ + _ret3 = lockrestart_do((_trans), ({ \ + struct btree *_b = bch2_btree_iter_peek_node(&_iter); \ + if (!_b) \ + break; \ + \ + PTR_ERR_OR_ZERO(_b) ?: (_do); \ + })) ?: \ + lockrestart_do((_trans), \ + PTR_ERR_OR_ZERO(bch2_btree_iter_next_node(&_iter))); \ + } while (!_ret3); \ + \ + bch2_trans_iter_exit((_trans), &(_iter)); \ + _ret3; \ +}) #define for_each_btree_node(_trans, _iter, _btree_id, _start, \ - _flags, _b, _ret) \ - __for_each_btree_node(_trans, _iter, _btree_id, _start, \ - 0, 0, _flags, _b, _ret) + _flags, _b, _do) \ + __for_each_btree_node(_trans, _iter, _btree_id, _start, \ + 0, 0, _flags, _b, _do) static inline struct bkey_s_c bch2_btree_iter_peek_prev_type(struct btree_iter *iter, unsigned flags) diff --git a/libbcachefs/buckets.c b/libbcachefs/buckets.c index 2650a0d2..9f7004e9 100644 --- a/libbcachefs/buckets.c +++ b/libbcachefs/buckets.c @@ -71,17 +71,21 @@ bch2_fs_usage_read_short(struct bch_fs *c) return ret; } -void bch2_dev_usage_to_text(struct printbuf *out, struct bch_dev_usage *usage) +void bch2_dev_usage_to_text(struct printbuf *out, + struct bch_dev *ca, + struct bch_dev_usage *usage) { prt_printf(out, "\tbuckets\rsectors\rfragmented\r\n"); for (unsigned i = 0; i < BCH_DATA_NR; i++) { bch2_prt_data_type(out, i); prt_printf(out, "\t%llu\r%llu\r%llu\r\n", - usage->d[i].buckets, - usage->d[i].sectors, - usage->d[i].fragmented); + usage->d[i].buckets, + usage->d[i].sectors, + usage->d[i].fragmented); } + + prt_printf(out, "capacity\t%llu\r\n", ca->mi.nbuckets); } static int bch2_check_fix_ptr(struct btree_trans *trans, diff --git a/libbcachefs/buckets.h b/libbcachefs/buckets.h index 2d35eeb2..edbdffd5 100644 --- a/libbcachefs/buckets.h +++ b/libbcachefs/buckets.h @@ -212,7 +212,7 @@ static inline struct bch_dev_usage bch2_dev_usage_read(struct bch_dev *ca) return ret; } -void bch2_dev_usage_to_text(struct printbuf *, struct bch_dev_usage *); +void bch2_dev_usage_to_text(struct printbuf *, struct bch_dev *, struct bch_dev_usage *); static inline u64 bch2_dev_buckets_reserved(struct bch_dev *ca, enum bch_watermark watermark) { diff --git a/libbcachefs/debug.c b/libbcachefs/debug.c index ebabab17..45aec1af 100644 --- a/libbcachefs/debug.c +++ b/libbcachefs/debug.c @@ -397,47 +397,27 @@ static ssize_t bch2_read_btree_formats(struct file *file, char __user *buf, size_t size, loff_t *ppos) { struct dump_iter *i = file->private_data; - struct btree_trans *trans; - struct btree_iter iter; - struct btree *b; - ssize_t ret; i->ubuf = buf; i->size = size; i->ret = 0; - ret = flush_buf(i); + ssize_t ret = flush_buf(i); if (ret) return ret; if (bpos_eq(SPOS_MAX, i->from)) return i->ret; - trans = bch2_trans_get(i->c); -retry: - bch2_trans_begin(trans); + return bch2_trans_run(i->c, + for_each_btree_node(trans, iter, i->id, i->from, 0, b, ({ + bch2_btree_node_to_text(&i->buf, i->c, b); + i->from = !bpos_eq(SPOS_MAX, b->key.k.p) + ? bpos_successor(b->key.k.p) + : b->key.k.p; - for_each_btree_node(trans, iter, i->id, i->from, 0, b, ret) { - bch2_btree_node_to_text(&i->buf, i->c, b); - i->from = !bpos_eq(SPOS_MAX, b->key.k.p) - ? bpos_successor(b->key.k.p) - : b->key.k.p; - - ret = drop_locks_do(trans, flush_buf(i)); - if (ret) - break; - } - bch2_trans_iter_exit(trans, &iter); - - if (bch2_err_matches(ret, BCH_ERR_transaction_restart)) - goto retry; - - bch2_trans_put(trans); - - if (!ret) - ret = flush_buf(i); - - return ret ?: i->ret; + drop_locks_do(trans, flush_buf(i)); + }))) ?: i->ret; } static const struct file_operations btree_format_debug_ops = { diff --git a/libbcachefs/disk_accounting.c b/libbcachefs/disk_accounting.c index dcdd5924..046ac92b 100644 --- a/libbcachefs/disk_accounting.c +++ b/libbcachefs/disk_accounting.c @@ -114,11 +114,74 @@ int bch2_mod_dev_cached_sectors(struct btree_trans *trans, return bch2_disk_accounting_mod(trans, &acc, §ors, 1, gc); } +static inline bool is_zero(char *start, char *end) +{ + BUG_ON(start > end); + + for (; start < end; start++) + if (*start) + return false; + return true; +} + +#define field_end(p, member) (((void *) (&p.member)) + sizeof(p.member)) + int bch2_accounting_invalid(struct bch_fs *c, struct bkey_s_c k, enum bch_validate_flags flags, struct printbuf *err) { - return 0; + struct disk_accounting_pos acc_k; + bpos_to_disk_accounting_pos(&acc_k, k.k->p); + void *end = &acc_k + 1; + int ret = 0; + + switch (acc_k.type) { + case BCH_DISK_ACCOUNTING_nr_inodes: + end = field_end(acc_k, nr_inodes); + break; + case BCH_DISK_ACCOUNTING_persistent_reserved: + end = field_end(acc_k, persistent_reserved); + break; + case BCH_DISK_ACCOUNTING_replicas: + bkey_fsck_err_on(!acc_k.replicas.nr_devs, + c, err, accounting_key_replicas_nr_devs_0, + "accounting key replicas entry with nr_devs=0"); + + bkey_fsck_err_on(acc_k.replicas.nr_required > acc_k.replicas.nr_devs || + (acc_k.replicas.nr_required > 1 && + acc_k.replicas.nr_required == acc_k.replicas.nr_devs), + c, err, accounting_key_replicas_nr_required_bad, + "accounting key replicas entry with bad nr_required"); + + for (unsigned i = 0; i + 1 < acc_k.replicas.nr_devs; i++) + bkey_fsck_err_on(acc_k.replicas.devs[i] > acc_k.replicas.devs[i + 1], + c, err, accounting_key_replicas_devs_unsorted, + "accounting key replicas entry with unsorted devs"); + + end = (void *) &acc_k.replicas + replicas_entry_bytes(&acc_k.replicas); + break; + case BCH_DISK_ACCOUNTING_dev_data_type: + end = field_end(acc_k, dev_data_type); + break; + case BCH_DISK_ACCOUNTING_compression: + end = field_end(acc_k, compression); + break; + case BCH_DISK_ACCOUNTING_snapshot: + end = field_end(acc_k, snapshot); + break; + case BCH_DISK_ACCOUNTING_btree: + end = field_end(acc_k, btree); + break; + case BCH_DISK_ACCOUNTING_rebalance_work: + end = field_end(acc_k, rebalance_work); + break; + } + + bkey_fsck_err_on(!is_zero(end, (void *) (&acc_k + 1)), + c, err, accounting_key_junk_at_end, + "junk at end of accounting key"); +fsck_err: + return ret; } void bch2_accounting_key_to_text(struct printbuf *out, struct disk_accounting_pos *k) diff --git a/libbcachefs/disk_accounting_format.h b/libbcachefs/disk_accounting_format.h index cba41706..a93cf26f 100644 --- a/libbcachefs/disk_accounting_format.h +++ b/libbcachefs/disk_accounting_format.h @@ -124,20 +124,19 @@ struct bch_dev_data_type { __u8 data_type; }; -struct bch_dev_stripe_buckets { - __u8 dev; -}; - struct bch_acct_compression { __u8 type; }; struct bch_acct_snapshot { __u32 id; -}; +} __packed; struct bch_acct_btree { __u32 id; +} __packed; + +struct bch_acct_rebalance_work { }; struct disk_accounting_pos { @@ -149,12 +148,12 @@ struct disk_accounting_pos { struct bch_persistent_reserved persistent_reserved; struct bch_replicas_entry_v1 replicas; struct bch_dev_data_type dev_data_type; - struct bch_dev_stripe_buckets dev_stripe_buckets; struct bch_acct_compression compression; struct bch_acct_snapshot snapshot; struct bch_acct_btree btree; - }; - }; + struct bch_acct_rebalance_work rebalance_work; + } __packed; + } __packed; struct bpos _pad; }; }; diff --git a/libbcachefs/replicas.c b/libbcachefs/replicas.c index 10c96cb2..1223b710 100644 --- a/libbcachefs/replicas.c +++ b/libbcachefs/replicas.c @@ -24,7 +24,6 @@ static int bch2_memcmp(const void *l, const void *r, const void *priv) static void verify_replicas_entry(struct bch_replicas_entry_v1 *e) { #ifdef CONFIG_BCACHEFS_DEBUG - BUG_ON(e->data_type >= BCH_DATA_NR); BUG_ON(!e->nr_devs); BUG_ON(e->nr_required > 1 && e->nr_required >= e->nr_devs); diff --git a/libbcachefs/sb-downgrade.c b/libbcachefs/sb-downgrade.c index dfbbd33c..6c4469f5 100644 --- a/libbcachefs/sb-downgrade.c +++ b/libbcachefs/sb-downgrade.c @@ -61,12 +61,37 @@ BCH_FSCK_ERR_dev_usage_buckets_wrong, \ BCH_FSCK_ERR_dev_usage_sectors_wrong, \ BCH_FSCK_ERR_dev_usage_fragmented_wrong, \ - BCH_FSCK_ERR_accounting_mismatch) + BCH_FSCK_ERR_accounting_mismatch) \ + x(disk_accounting_v3, \ + BIT_ULL(BCH_RECOVERY_PASS_check_allocations), \ + BCH_FSCK_ERR_bkey_version_in_future, \ + BCH_FSCK_ERR_dev_usage_buckets_wrong, \ + BCH_FSCK_ERR_dev_usage_sectors_wrong, \ + BCH_FSCK_ERR_dev_usage_fragmented_wrong, \ + BCH_FSCK_ERR_accounting_mismatch, \ + BCH_FSCK_ERR_accounting_key_replicas_nr_devs_0, \ + BCH_FSCK_ERR_accounting_key_replicas_nr_required_bad, \ + BCH_FSCK_ERR_accounting_key_replicas_devs_unsorted, \ + BCH_FSCK_ERR_accounting_key_junk_at_end) #define DOWNGRADE_TABLE() \ x(bucket_stripe_sectors, \ 0) \ x(disk_accounting_v2, \ + BIT_ULL(BCH_RECOVERY_PASS_check_allocations), \ + BCH_FSCK_ERR_dev_usage_buckets_wrong, \ + BCH_FSCK_ERR_dev_usage_sectors_wrong, \ + BCH_FSCK_ERR_dev_usage_fragmented_wrong, \ + BCH_FSCK_ERR_fs_usage_hidden_wrong, \ + BCH_FSCK_ERR_fs_usage_btree_wrong, \ + BCH_FSCK_ERR_fs_usage_data_wrong, \ + BCH_FSCK_ERR_fs_usage_cached_wrong, \ + BCH_FSCK_ERR_fs_usage_reserved_wrong, \ + BCH_FSCK_ERR_fs_usage_nr_inodes_wrong, \ + BCH_FSCK_ERR_fs_usage_persistent_reserved_wrong, \ + BCH_FSCK_ERR_fs_usage_replicas_wrong, \ + BCH_FSCK_ERR_bkey_version_in_future) \ + x(disk_accounting_v3, \ BIT_ULL(BCH_RECOVERY_PASS_check_allocations), \ BCH_FSCK_ERR_dev_usage_buckets_wrong, \ BCH_FSCK_ERR_dev_usage_sectors_wrong, \ diff --git a/libbcachefs/sb-errors_format.h b/libbcachefs/sb-errors_format.h index d1b2f2aa..d3a49861 100644 --- a/libbcachefs/sb-errors_format.h +++ b/libbcachefs/sb-errors_format.h @@ -287,7 +287,11 @@ enum bch_fsck_flags { x(accounting_replicas_not_marked, 273, 0) \ x(invalid_btree_id, 274, 0) \ x(alloc_key_io_time_bad, 275, 0) \ - x(alloc_key_fragmentation_lru_wrong, 276, FSCK_AUTOFIX) + x(alloc_key_fragmentation_lru_wrong, 276, FSCK_AUTOFIX) \ + x(accounting_key_junk_at_end, 277, 0) \ + x(accounting_key_replicas_nr_devs_0, 278, 0) \ + x(accounting_key_replicas_nr_required_bad, 279, 0) \ + x(accounting_key_replicas_devs_unsorted, 280, 0) \ enum bch_sb_error_id { #define x(t, n, ...) BCH_FSCK_ERR_##t = n,