Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'bcachefs-2025-03-31' of git://evilpiepirate.org/bcachefs

Pull more bcachefs updates from Kent Overstreet:
"All bugfixes and logging improvements"

* tag 'bcachefs-2025-03-31' of git://evilpiepirate.org/bcachefs: (35 commits)
bcachefs: fix bch2_write_point_to_text() units
bcachefs: Log original key being moved in data updates
bcachefs: BCH_JSET_ENTRY_log_bkey
bcachefs: Reorder error messages that include journal debug
bcachefs: Don't use designated initializers for disk_accounting_pos
bcachefs: Silence errors after emergency shutdown
bcachefs: fix units in rebalance_status
bcachefs: bch2_ioctl_subvolume_destroy() fixes
bcachefs: Clear fs_path_parent on subvolume unlink
bcachefs: Change btree_insert_node() assertion to error
bcachefs: Better printing of inconsistency errors
bcachefs: bch2_count_fsck_err()
bcachefs: Better helpers for inconsistency errors
bcachefs: Consistent indentation of multiline fsck errors
bcachefs: Add an "ignore unknown" option to bch2_parse_mount_opts()
bcachefs: bch2_time_stats_init_no_pcpu()
bcachefs: Fix bch2_fs_get_tree() error path
bcachefs: fix logging in journal_entry_err_msg()
bcachefs: add missing newline in bch2_trans_updates_to_text()
bcachefs: print_string_as_lines: fix extra newline
...

+857 -507
+11 -11
fs/bcachefs/alloc_background.c
··· 589 589 590 590 int bch2_alloc_read(struct bch_fs *c) 591 591 { 592 + down_read(&c->state_lock); 593 + 592 594 struct btree_trans *trans = bch2_trans_get(c); 593 595 struct bch_dev *ca = NULL; 594 596 int ret; ··· 654 652 bch2_dev_put(ca); 655 653 bch2_trans_put(trans); 656 654 655 + up_read(&c->state_lock); 657 656 bch_err_fn(c, ret); 658 657 return ret; 659 658 } ··· 676 673 bch2_bkey_val_to_text(&buf, c, alloc_k); 677 674 678 675 int ret = __bch2_fsck_err(NULL, trans, flags, err_id, 679 - "bucket incorrectly %sset in %s btree\n" 680 - " %s", 676 + "bucket incorrectly %sset in %s btree\n%s", 681 677 set ? "" : "un", 682 678 bch2_btree_id_str(btree), 683 679 buf.buf); ··· 1029 1027 bch2_dev_put(ca); 1030 1028 return ret; 1031 1029 invalid_bucket: 1032 - bch2_fs_inconsistent(c, "reference to invalid bucket\n %s", 1030 + bch2_fs_inconsistent(c, "reference to invalid bucket\n%s", 1033 1031 (bch2_bkey_val_to_text(&buf, c, new.s_c), buf.buf)); 1034 1032 ret = -BCH_ERR_trigger_alloc; 1035 1033 goto err; ··· 1203 1201 1204 1202 if (fsck_err_on(a->gen != alloc_gen(k, gens_offset), 1205 1203 trans, bucket_gens_key_wrong, 1206 - "incorrect gen in bucket_gens btree (got %u should be %u)\n" 1207 - " %s", 1204 + "incorrect gen in bucket_gens btree (got %u should be %u)\n%s", 1208 1205 alloc_gen(k, gens_offset), a->gen, 1209 1206 (printbuf_reset(&buf), 1210 1207 bch2_bkey_val_to_text(&buf, c, alloc_k), buf.buf))) { ··· 1261 1260 if (fsck_err_on(k.k->type != KEY_TYPE_set, 1262 1261 trans, freespace_hole_missing, 1263 1262 "hole in alloc btree missing in freespace btree\n" 1264 - " device %llu buckets %llu-%llu", 1263 + "device %llu buckets %llu-%llu", 1265 1264 freespace_iter->pos.inode, 1266 1265 freespace_iter->pos.offset, 1267 1266 end->offset)) { ··· 1420 1419 (state == BCH_DATA_free && 1421 1420 genbits != alloc_freespace_genbits(*a))) { 1422 1421 if (fsck_err(trans, need_discard_freespace_key_bad, 1423 - "%s\n incorrectly set at %s:%llu:%llu:0 (free %u, genbits %llu should be %llu)", 1422 + "%s\nincorrectly set at %s:%llu:%llu:0 (free %u, genbits %llu should be %llu)", 1424 1423 (bch2_bkey_val_to_text(&buf, c, alloc_k), buf.buf), 1425 1424 bch2_btree_id_str(iter->btree_id), 1426 1425 iter->pos.inode, ··· 1501 1500 struct bch_dev *ca = bch2_dev_tryget_noerror(c, k.k->p.inode); 1502 1501 if (!ca) { 1503 1502 if (fsck_err(trans, bucket_gens_to_invalid_dev, 1504 - "bucket_gens key for invalid device:\n %s", 1503 + "bucket_gens key for invalid device:\n%s", 1505 1504 (bch2_bkey_val_to_text(&buf, c, k), buf.buf))) 1506 1505 ret = bch2_btree_delete_at(trans, iter, 0); 1507 1506 goto out; ··· 1510 1509 if (fsck_err_on(end <= ca->mi.first_bucket || 1511 1510 start >= ca->mi.nbuckets, 1512 1511 trans, bucket_gens_to_invalid_buckets, 1513 - "bucket_gens key for invalid buckets:\n %s", 1512 + "bucket_gens key for invalid buckets:\n%s", 1514 1513 (bch2_bkey_val_to_text(&buf, c, k), buf.buf))) { 1515 1514 ret = bch2_btree_delete_at(trans, iter, 0); 1516 1515 goto out; ··· 1713 1712 1714 1713 if (fsck_err_on(!a->io_time[READ], 1715 1714 trans, alloc_key_cached_but_read_time_zero, 1716 - "cached bucket with read_time 0\n" 1717 - " %s", 1715 + "cached bucket with read_time 0\n%s", 1718 1716 (printbuf_reset(&buf), 1719 1717 bch2_bkey_val_to_text(&buf, c, alloc_k), buf.buf))) { 1720 1718 struct bkey_i_alloc_v4 *a_mut =
+1 -1
fs/bcachefs/alloc_foreground.c
··· 1560 1560 unsigned i; 1561 1561 1562 1562 prt_printf(out, "%lu: ", wp->write_point); 1563 - prt_human_readable_u64(out, wp->sectors_allocated); 1563 + prt_human_readable_u64(out, wp->sectors_allocated << 9); 1564 1564 1565 1565 prt_printf(out, " last wrote: "); 1566 1566 bch2_pr_time_units(out, sched_clock() - wp->last_used);
+21 -22
fs/bcachefs/backpointers.c
··· 96 96 { 97 97 struct bch_fs *c = trans->c; 98 98 struct printbuf buf = PRINTBUF; 99 + int ret = 0; 99 100 100 101 if (insert) { 101 102 prt_printf(&buf, "existing backpointer found when inserting "); ··· 126 125 127 126 prt_printf(&buf, "for "); 128 127 bch2_bkey_val_to_text(&buf, c, orig_k); 129 - 130 - bch_err(c, "%s", buf.buf); 131 128 } 132 129 130 + if (c->curr_recovery_pass > BCH_RECOVERY_PASS_check_extents_to_backpointers && 131 + __bch2_inconsistent_error(c, &buf)) 132 + ret = -BCH_ERR_erofs_unfixed_errors; 133 + 134 + bch_err(c, "%s", buf.buf); 133 135 printbuf_exit(&buf); 134 - 135 - if (c->curr_recovery_pass > BCH_RECOVERY_PASS_check_extents_to_backpointers) { 136 - return bch2_inconsistent_error(c) ? BCH_ERR_erofs_unfixed_errors : 0; 137 - } else { 138 - return 0; 139 - } 136 + return ret; 140 137 } 141 138 142 139 int bch2_bucket_backpointer_mod_nowritebuffer(struct btree_trans *trans, ··· 209 210 if (ret) 210 211 return ret; 211 212 212 - prt_printf(&buf, "backpointer doesn't match %s it points to:\n ", 213 + prt_printf(&buf, "backpointer doesn't match %s it points to:\n", 213 214 bp.v->level ? "btree node" : "extent"); 214 215 bch2_bkey_val_to_text(&buf, c, bp.s_c); 215 216 216 - prt_printf(&buf, "\n "); 217 + prt_newline(&buf); 217 218 bch2_bkey_val_to_text(&buf, c, target_k); 218 219 219 220 struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(target_k); ··· 221 222 struct extent_ptr_decoded p; 222 223 bkey_for_each_ptr_decode(target_k.k, ptrs, p, entry) 223 224 if (p.ptr.dev == bp.k->p.inode) { 224 - prt_printf(&buf, "\n "); 225 + prt_newline(&buf); 225 226 struct bkey_i_backpointer bp2; 226 227 bch2_extent_ptr_to_bp(c, bp.v->btree_id, bp.v->level, target_k, p, entry, &bp2); 227 228 bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&bp2.k_i)); ··· 442 443 if (ret) 443 444 goto err; 444 445 445 - prt_str(&buf, "extents pointing to same space, but first extent checksum bad:"); 446 - prt_printf(&buf, "\n "); 446 + prt_printf(&buf, "extents pointing to same space, but first extent checksum bad:\n"); 447 447 bch2_btree_id_to_text(&buf, btree); 448 448 prt_str(&buf, " "); 449 449 bch2_bkey_val_to_text(&buf, c, extent); 450 - prt_printf(&buf, "\n "); 450 + prt_newline(&buf); 451 451 bch2_btree_id_to_text(&buf, o_btree); 452 452 prt_str(&buf, " "); 453 453 bch2_bkey_val_to_text(&buf, c, extent2); ··· 537 539 538 540 if (bch2_extents_match(orig_k, other_extent)) { 539 541 printbuf_reset(&buf); 540 - prt_printf(&buf, "duplicate versions of same extent, deleting smaller\n "); 542 + prt_printf(&buf, "duplicate versions of same extent, deleting smaller\n"); 541 543 bch2_bkey_val_to_text(&buf, c, orig_k); 542 - prt_str(&buf, "\n "); 544 + prt_newline(&buf); 543 545 bch2_bkey_val_to_text(&buf, c, other_extent); 544 546 bch_err(c, "%s", buf.buf); 545 547 ··· 578 580 } 579 581 580 582 printbuf_reset(&buf); 581 - prt_printf(&buf, "duplicate extents pointing to same space on dev %llu\n ", bp->k.p.inode); 583 + prt_printf(&buf, "duplicate extents pointing to same space on dev %llu\n", bp->k.p.inode); 582 584 bch2_bkey_val_to_text(&buf, c, orig_k); 583 - prt_str(&buf, "\n "); 585 + prt_newline(&buf); 584 586 bch2_bkey_val_to_text(&buf, c, other_extent); 585 587 bch_err(c, "%s", buf.buf); 586 588 ret = -BCH_ERR_fsck_repair_unimplemented; 587 589 goto err; 588 590 missing: 589 591 printbuf_reset(&buf); 590 - prt_str(&buf, "missing backpointer\n for: "); 592 + prt_str(&buf, "missing backpointer\nfor: "); 591 593 bch2_bkey_val_to_text(&buf, c, orig_k); 592 - prt_printf(&buf, "\n want: "); 594 + prt_printf(&buf, "\nwant: "); 593 595 bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&bp->k_i)); 594 - prt_printf(&buf, "\n got: "); 596 + prt_printf(&buf, "\ngot: "); 595 597 bch2_bkey_val_to_text(&buf, c, bp_k); 596 598 597 599 if (fsck_err(trans, ptr_to_missing_backpointer, "%s", buf.buf)) ··· 1021 1023 * Can't allow devices to come/go/resize while we have bucket bitmaps 1022 1024 * allocated 1023 1025 */ 1024 - lockdep_assert_held(&c->state_lock); 1026 + down_read(&c->state_lock); 1025 1027 1026 1028 for_each_member_device(c, ca) { 1027 1029 BUG_ON(ca->bucket_backpointer_mismatches); ··· 1106 1108 ca->bucket_backpointer_mismatches = NULL; 1107 1109 } 1108 1110 1111 + up_read(&c->state_lock); 1109 1112 bch_err_fn(c, ret); 1110 1113 return ret; 1111 1114 }
+2 -1
fs/bcachefs/bcachefs_format.h
··· 1143 1143 x(log, 9) \ 1144 1144 x(overwrite, 10) \ 1145 1145 x(write_buffer_keys, 11) \ 1146 - x(datetime, 12) 1146 + x(datetime, 12) \ 1147 + x(log_bkey, 13) 1147 1148 1148 1149 enum bch_jset_entry_type { 1149 1150 #define x(f, nr) BCH_JSET_ENTRY_##f = nr,
+1 -1
fs/bcachefs/btree_cache.c
··· 1417 1417 prt_printf(out, "%u", r->level); 1418 1418 else 1419 1419 prt_printf(out, "(unknown)"); 1420 - prt_printf(out, "\n "); 1420 + prt_newline(out); 1421 1421 1422 1422 bch2_bkey_val_to_text(out, c, k); 1423 1423 }
+11 -12
fs/bcachefs/btree_gc.c
··· 213 213 214 214 prt_printf(&buf, " at "); 215 215 bch2_btree_id_level_to_text(&buf, b->c.btree_id, b->c.level); 216 - prt_printf(&buf, ":\n parent: "); 216 + prt_printf(&buf, ":\nparent: "); 217 217 bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&b->key)); 218 218 219 219 if (prev) { 220 - prt_printf(&buf, "\n prev: "); 220 + prt_printf(&buf, "\nprev: "); 221 221 bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&prev->key)); 222 222 } 223 223 224 - prt_str(&buf, "\n next: "); 224 + prt_str(&buf, "\nnext: "); 225 225 bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&cur->key)); 226 226 227 227 if (bpos_lt(expected_start, cur->data->min_key)) { /* gap */ ··· 280 280 if (bpos_eq(child->key.k.p, b->key.k.p)) 281 281 return 0; 282 282 283 - prt_printf(&buf, " at "); 283 + prt_printf(&buf, "\nat: "); 284 284 bch2_btree_id_level_to_text(&buf, b->c.btree_id, b->c.level); 285 - prt_printf(&buf, ":\n parent: "); 285 + prt_printf(&buf, "\nparent: "); 286 286 bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&b->key)); 287 287 288 - prt_str(&buf, "\n child: "); 288 + prt_str(&buf, "\nchild: "); 289 289 bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&child->key)); 290 290 291 291 if (mustfix_fsck_err(trans, btree_node_topology_bad_max_key, ··· 351 351 352 352 if (mustfix_fsck_err_on(bch2_err_matches(ret, EIO), 353 353 trans, btree_node_read_error, 354 - "Topology repair: unreadable btree node at\n" 355 - " %s", 354 + "Topology repair: unreadable btree node at\n%s", 356 355 buf.buf)) { 357 356 bch2_btree_node_evict(trans, cur_k.k); 358 357 cur = NULL; ··· 611 612 if (fsck_err_on(btree_id != BTREE_ID_accounting && 612 613 k.k->bversion.lo > atomic64_read(&c->key_version), 613 614 trans, bkey_version_in_future, 614 - "key version number higher than recorded %llu\n %s", 615 + "key version number higher than recorded %llu\n%s", 615 616 atomic64_read(&c->key_version), 616 617 (bch2_bkey_val_to_text(&buf, c, k), buf.buf))) 617 618 atomic64_set(&c->key_version, k.k->bversion.lo); ··· 619 620 620 621 if (mustfix_fsck_err_on(level && !bch2_dev_btree_bitmap_marked(c, k), 621 622 trans, btree_bitmap_not_marked, 622 - "btree ptr not marked in member info btree allocated bitmap\n %s", 623 + "btree ptr not marked in member info btree allocated bitmap\n%s", 623 624 (printbuf_reset(&buf), 624 625 bch2_bkey_val_to_text(&buf, c, k), 625 626 buf.buf))) { ··· 1020 1021 { 1021 1022 int ret; 1022 1023 1023 - lockdep_assert_held(&c->state_lock); 1024 - 1024 + down_read(&c->state_lock); 1025 1025 down_write(&c->gc_lock); 1026 1026 1027 1027 bch2_btree_interior_updates_flush(c); ··· 1058 1060 percpu_up_write(&c->mark_lock); 1059 1061 1060 1062 up_write(&c->gc_lock); 1063 + up_read(&c->state_lock); 1061 1064 1062 1065 /* 1063 1066 * At startup, allocations can happen directly instead of via the
+33 -32
fs/bcachefs/btree_io.c
··· 525 525 prt_printf(out, "at btree "); 526 526 bch2_btree_pos_to_text(out, c, b); 527 527 528 - printbuf_indent_add(out, 2); 529 - 530 528 prt_printf(out, "\nnode offset %u/%u", 531 529 b->written, btree_ptr_sectors_written(bkey_i_to_s_c(&b->key))); 532 530 if (i) ··· 548 550 enum bch_sb_error_id err_type, 549 551 const char *fmt, ...) 550 552 { 551 - struct printbuf out = PRINTBUF; 552 553 bool silent = c->curr_recovery_pass == BCH_RECOVERY_PASS_scan_for_btree_nodes; 553 - va_list args; 554 - 555 - btree_err_msg(&out, c, ca, b, i, k, b->written, write); 556 - 557 - va_start(args, fmt); 558 - prt_vprintf(&out, fmt, args); 559 - va_end(args); 560 - 561 - if (write == WRITE) { 562 - bch2_print_string_as_lines(KERN_ERR, out.buf); 563 - ret = c->opts.errors == BCH_ON_ERROR_continue 564 - ? 0 565 - : -BCH_ERR_fsck_errors_not_fixed; 566 - goto out; 567 - } 568 554 569 555 if (!have_retry && ret == -BCH_ERR_btree_node_read_err_want_retry) 570 556 ret = -BCH_ERR_btree_node_read_err_fixable; ··· 557 575 558 576 if (!silent && ret != -BCH_ERR_btree_node_read_err_fixable) 559 577 bch2_sb_error_count(c, err_type); 578 + 579 + struct printbuf out = PRINTBUF; 580 + if (write != WRITE && ret != -BCH_ERR_btree_node_read_err_fixable) { 581 + printbuf_indent_add_nextline(&out, 2); 582 + #ifdef BCACHEFS_LOG_PREFIX 583 + prt_printf(&out, bch2_log_msg(c, "")); 584 + #endif 585 + } 586 + 587 + btree_err_msg(&out, c, ca, b, i, k, b->written, write); 588 + 589 + va_list args; 590 + va_start(args, fmt); 591 + prt_vprintf(&out, fmt, args); 592 + va_end(args); 593 + 594 + if (write == WRITE) { 595 + prt_str(&out, ", "); 596 + ret = __bch2_inconsistent_error(c, &out) 597 + ? -BCH_ERR_fsck_errors_not_fixed 598 + : 0; 599 + silent = false; 600 + } 560 601 561 602 switch (ret) { 562 603 case -BCH_ERR_btree_node_read_err_fixable: ··· 590 585 ret != -BCH_ERR_fsck_ignore) 591 586 goto fsck_err; 592 587 ret = -BCH_ERR_fsck_fix; 593 - break; 594 - case -BCH_ERR_btree_node_read_err_want_retry: 595 - case -BCH_ERR_btree_node_read_err_must_retry: 596 - if (!silent) 597 - bch2_print_string_as_lines(KERN_ERR, out.buf); 598 - break; 588 + goto out; 599 589 case -BCH_ERR_btree_node_read_err_bad_node: 600 - if (!silent) 601 - bch2_print_string_as_lines(KERN_ERR, out.buf); 602 - ret = bch2_topology_error(c); 590 + prt_str(&out, ", "); 591 + ret = __bch2_topology_error(c, &out); 592 + if (ret) 593 + silent = false; 603 594 break; 604 595 case -BCH_ERR_btree_node_read_err_incompatible: 605 - if (!silent) 606 - bch2_print_string_as_lines(KERN_ERR, out.buf); 607 596 ret = -BCH_ERR_fsck_errors_not_fixed; 597 + silent = false; 608 598 break; 609 - default: 610 - BUG(); 611 599 } 600 + 601 + if (!silent) 602 + bch2_print_string_as_lines(KERN_ERR, out.buf); 612 603 out: 613 604 fsck_err: 614 605 printbuf_exit(&out); ··· 818 817 -BCH_ERR_btree_node_read_err_bad_node, 819 818 c, ca, b, i, NULL, 820 819 btree_node_bad_format, 821 - "invalid bkey format: %s\n %s", buf1.buf, 820 + "invalid bkey format: %s\n%s", buf1.buf, 822 821 (printbuf_reset(&buf2), 823 822 bch2_bkey_format_to_text(&buf2, &bn->format), buf2.buf)); 824 823 printbuf_reset(&buf1);
+3 -11
fs/bcachefs/btree_iter.c
··· 1487 1487 1488 1488 for (struct jset_entry *e = trans->journal_entries; 1489 1489 e != btree_trans_journal_entries_top(trans); 1490 - e = vstruct_next(e)) 1490 + e = vstruct_next(e)) { 1491 1491 bch2_journal_entry_to_text(buf, trans->c, e); 1492 + prt_newline(buf); 1493 + } 1492 1494 1493 1495 printbuf_indent_sub(buf, 2); 1494 - } 1495 - 1496 - noinline __cold 1497 - void bch2_dump_trans_updates(struct btree_trans *trans) 1498 - { 1499 - struct printbuf buf = PRINTBUF; 1500 - 1501 - bch2_trans_updates_to_text(&buf, trans); 1502 - bch2_print_str(trans->c, buf.buf); 1503 - printbuf_exit(&buf); 1504 1496 } 1505 1497 1506 1498 static void bch2_btree_path_to_text_short(struct printbuf *out, struct btree_trans *trans, btree_path_idx_t path_idx)
-1
fs/bcachefs/btree_iter.h
··· 9 9 void bch2_trans_updates_to_text(struct printbuf *, struct btree_trans *); 10 10 void bch2_btree_path_to_text(struct printbuf *, struct btree_trans *, btree_path_idx_t); 11 11 void bch2_trans_paths_to_text(struct printbuf *, struct btree_trans *); 12 - void bch2_dump_trans_updates(struct btree_trans *); 13 12 void bch2_dump_trans_paths_updates(struct btree_trans *); 14 13 15 14 static inline int __bkey_err(const struct bkey *k)
+2
fs/bcachefs/btree_journal_iter.c
··· 644 644 */ 645 645 static int journal_sort_key_cmp(const void *_l, const void *_r) 646 646 { 647 + cond_resched(); 648 + 647 649 const struct journal_key *l = _l; 648 650 const struct journal_key *r = _r; 649 651
+9 -5
fs/bcachefs/btree_node_scan.c
··· 13 13 14 14 #include <linux/kthread.h> 15 15 #include <linux/min_heap.h> 16 + #include <linux/sched/sysctl.h> 16 17 #include <linux/sort.h> 17 18 18 19 struct find_btree_nodes_worker { ··· 314 313 wake_up_process(t); 315 314 } 316 315 err: 317 - closure_sync(&cl); 316 + while (closure_sync_timeout(&cl, sysctl_hung_task_timeout_secs * HZ / 2)) 317 + ; 318 318 return f->ret ?: ret; 319 319 } 320 320 ··· 579 577 580 578 found_btree_node_to_key(&tmp.k, &n); 581 579 582 - struct printbuf buf = PRINTBUF; 583 - bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&tmp.k)); 584 - bch_verbose(c, "%s(): recovering %s", __func__, buf.buf); 585 - printbuf_exit(&buf); 580 + if (c->opts.verbose) { 581 + struct printbuf buf = PRINTBUF; 582 + bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&tmp.k)); 583 + bch_verbose(c, "%s(): recovering %s", __func__, buf.buf); 584 + printbuf_exit(&buf); 585 + } 586 586 587 587 BUG_ON(bch2_bkey_validate(c, bkey_i_to_s_c(&tmp.k), 588 588 (struct bkey_validate_context) {
+13
fs/bcachefs/btree_update.c
··· 846 846 return 0; 847 847 } 848 848 849 + int bch2_trans_log_bkey(struct btree_trans *trans, enum btree_id btree, 850 + unsigned level, struct bkey_i *k) 851 + { 852 + struct jset_entry *e = bch2_trans_jset_entry_alloc(trans, jset_u64s(k->k.u64s)); 853 + int ret = PTR_ERR_OR_ZERO(e); 854 + if (ret) 855 + return ret; 856 + 857 + journal_entry_init(e, BCH_JSET_ENTRY_log_bkey, btree, level, k->k.u64s); 858 + bkey_copy(e->start, k); 859 + return 0; 860 + } 861 + 849 862 __printf(3, 0) 850 863 static int 851 864 __bch2_fs_log_msg(struct bch_fs *c, unsigned commit_flags, const char *fmt,
+2
fs/bcachefs/btree_update.h
··· 170 170 int __bch2_trans_commit(struct btree_trans *, unsigned); 171 171 172 172 int bch2_trans_log_msg(struct btree_trans *, struct printbuf *); 173 + int bch2_trans_log_bkey(struct btree_trans *, enum btree_id, unsigned, struct bkey_i *); 174 + 173 175 __printf(2, 3) int bch2_fs_log_msg(struct bch_fs *, const char *, ...); 174 176 __printf(2, 3) int bch2_journal_log_msg(struct bch_fs *, const char *, ...); 175 177
+53 -36
fs/bcachefs/btree_update_interior.c
··· 35 35 NULL 36 36 }; 37 37 38 + static void bch2_btree_update_to_text(struct printbuf *, struct btree_update *); 39 + 38 40 static int bch2_btree_insert_node(struct btree_update *, struct btree_trans *, 39 41 btree_path_idx_t, struct btree *, struct keylist *); 40 42 static void bch2_btree_update_add_new_node(struct btree_update *, struct btree *); ··· 56 54 struct bkey_buf prev; 57 55 int ret = 0; 58 56 57 + printbuf_indent_add_nextline(&buf, 2); 58 + 59 59 BUG_ON(b->key.k.type == KEY_TYPE_btree_ptr_v2 && 60 60 !bpos_eq(bkey_i_to_btree_ptr_v2(&b->key)->v.min_key, 61 61 b->data->min_key)); ··· 68 64 69 65 if (b == btree_node_root(c, b)) { 70 66 if (!bpos_eq(b->data->min_key, POS_MIN)) { 71 - printbuf_reset(&buf); 67 + ret = __bch2_topology_error(c, &buf); 68 + 72 69 bch2_bpos_to_text(&buf, b->data->min_key); 73 70 log_fsck_err(trans, btree_root_bad_min_key, 74 71 "btree root with incorrect min_key: %s", buf.buf); 75 - goto topology_repair; 72 + goto out; 76 73 } 77 74 78 75 if (!bpos_eq(b->data->max_key, SPOS_MAX)) { 79 - printbuf_reset(&buf); 76 + ret = __bch2_topology_error(c, &buf); 80 77 bch2_bpos_to_text(&buf, b->data->max_key); 81 78 log_fsck_err(trans, btree_root_bad_max_key, 82 79 "btree root with incorrect max_key: %s", buf.buf); 83 - goto topology_repair; 80 + goto out; 84 81 } 85 82 } 86 83 ··· 99 94 : bpos_successor(prev.k->k.p); 100 95 101 96 if (!bpos_eq(expected_min, bp.v->min_key)) { 102 - bch2_topology_error(c); 97 + ret = __bch2_topology_error(c, &buf); 103 98 104 - printbuf_reset(&buf); 105 - prt_str(&buf, "end of prev node doesn't match start of next node\n in "); 99 + prt_str(&buf, "end of prev node doesn't match start of next node\nin "); 106 100 bch2_btree_id_level_to_text(&buf, b->c.btree_id, b->c.level); 107 101 prt_str(&buf, " node "); 108 102 bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&b->key)); 109 - prt_str(&buf, "\n prev "); 103 + prt_str(&buf, "\nprev "); 110 104 bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(prev.k)); 111 - prt_str(&buf, "\n next "); 105 + prt_str(&buf, "\nnext "); 112 106 bch2_bkey_val_to_text(&buf, c, k); 113 107 114 108 log_fsck_err(trans, btree_node_topology_bad_min_key, "%s", buf.buf); 115 - goto topology_repair; 109 + goto out; 116 110 } 117 111 118 112 bch2_bkey_buf_reassemble(&prev, c, k); ··· 119 115 } 120 116 121 117 if (bkey_deleted(&prev.k->k)) { 122 - bch2_topology_error(c); 118 + ret = __bch2_topology_error(c, &buf); 123 119 124 - printbuf_reset(&buf); 125 - prt_str(&buf, "empty interior node\n in "); 120 + prt_str(&buf, "empty interior node\nin "); 126 121 bch2_btree_id_level_to_text(&buf, b->c.btree_id, b->c.level); 127 122 prt_str(&buf, " node "); 128 123 bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&b->key)); 129 124 130 125 log_fsck_err(trans, btree_node_topology_empty_interior_node, "%s", buf.buf); 131 - goto topology_repair; 132 126 } else if (!bpos_eq(prev.k->k.p, b->key.k.p)) { 133 - bch2_topology_error(c); 127 + ret = __bch2_topology_error(c, &buf); 134 128 135 - printbuf_reset(&buf); 136 - prt_str(&buf, "last child node doesn't end at end of parent node\n in "); 129 + prt_str(&buf, "last child node doesn't end at end of parent node\nin "); 137 130 bch2_btree_id_level_to_text(&buf, b->c.btree_id, b->c.level); 138 131 prt_str(&buf, " node "); 139 132 bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&b->key)); 140 - prt_str(&buf, "\n last key "); 133 + prt_str(&buf, "\nlast key "); 141 134 bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(prev.k)); 142 135 143 136 log_fsck_err(trans, btree_node_topology_bad_max_key, "%s", buf.buf); 144 - goto topology_repair; 145 137 } 146 138 out: 147 139 fsck_err: ··· 145 145 bch2_bkey_buf_exit(&prev, c); 146 146 printbuf_exit(&buf); 147 147 return ret; 148 - topology_repair: 149 - ret = bch2_topology_error(c); 150 - goto out; 151 148 } 152 149 153 150 /* Calculate ideal packed bkey format for new btree nodes: */ ··· 1268 1271 bch2_btree_update_free(as, trans); 1269 1272 if (!bch2_err_matches(ret, ENOSPC) && 1270 1273 !bch2_err_matches(ret, EROFS) && 1271 - ret != -BCH_ERR_journal_reclaim_would_deadlock) 1274 + ret != -BCH_ERR_journal_reclaim_would_deadlock && 1275 + ret != -BCH_ERR_journal_shutdown) 1272 1276 bch_err_fn_ratelimited(c, ret); 1273 1277 return ERR_PTR(ret); 1274 1278 } ··· 1780 1782 int ret; 1781 1783 1782 1784 lockdep_assert_held(&c->gc_lock); 1783 - BUG_ON(!btree_node_intent_locked(path, b->c.level)); 1784 1785 BUG_ON(!b->c.level); 1785 1786 BUG_ON(!as || as->b); 1786 1787 bch2_verify_keylist_sorted(keys); 1788 + 1789 + if (!btree_node_intent_locked(path, b->c.level)) { 1790 + struct printbuf buf = PRINTBUF; 1791 + bch2_log_msg_start(c, &buf); 1792 + prt_printf(&buf, "%s(): node not locked at level %u\n", 1793 + __func__, b->c.level); 1794 + bch2_btree_update_to_text(&buf, as); 1795 + bch2_btree_path_to_text(&buf, trans, path_idx); 1796 + 1797 + bch2_print_string_as_lines(KERN_ERR, buf.buf); 1798 + printbuf_exit(&buf); 1799 + bch2_fs_emergency_read_only(c); 1800 + return -EIO; 1801 + } 1787 1802 1788 1803 ret = bch2_btree_node_lock_write(trans, path, &b->c); 1789 1804 if (ret) ··· 2018 2007 } 2019 2008 2020 2009 if (!bpos_eq(bpos_successor(prev->data->max_key), next->data->min_key)) { 2021 - struct printbuf buf1 = PRINTBUF, buf2 = PRINTBUF; 2010 + struct printbuf buf = PRINTBUF; 2022 2011 2023 - bch2_bpos_to_text(&buf1, prev->data->max_key); 2024 - bch2_bpos_to_text(&buf2, next->data->min_key); 2025 - bch_err(c, 2026 - "%s(): btree topology error:\n" 2027 - " prev ends at %s\n" 2028 - " next starts at %s", 2029 - __func__, buf1.buf, buf2.buf); 2030 - printbuf_exit(&buf1); 2031 - printbuf_exit(&buf2); 2032 - ret = bch2_topology_error(c); 2012 + printbuf_indent_add_nextline(&buf, 2); 2013 + prt_printf(&buf, "%s(): ", __func__); 2014 + ret = __bch2_topology_error(c, &buf); 2015 + prt_newline(&buf); 2016 + 2017 + prt_printf(&buf, "prev ends at "); 2018 + bch2_bpos_to_text(&buf, prev->data->max_key); 2019 + prt_newline(&buf); 2020 + 2021 + prt_printf(&buf, "next starts at "); 2022 + bch2_bpos_to_text(&buf, next->data->min_key); 2023 + 2024 + bch_err(c, "%s", buf.buf); 2025 + printbuf_exit(&buf); 2033 2026 goto err; 2034 2027 } 2035 2028 ··· 2303 2288 2304 2289 int ret = bch2_trans_do(c, bch2_btree_node_rewrite_key(trans, 2305 2290 a->btree_id, a->level, a->key.k, 0)); 2306 - if (ret != -ENOENT) 2291 + if (ret != -ENOENT && 2292 + !bch2_err_matches(ret, EROFS) && 2293 + ret != -BCH_ERR_journal_shutdown) 2307 2294 bch_err_fn_ratelimited(c, ret); 2308 2295 2309 2296 spin_lock(&c->btree_node_rewrites_lock);
+89 -72
fs/bcachefs/buckets.c
··· 381 381 return ret; 382 382 } 383 383 384 + static int bucket_ref_update_err(struct btree_trans *trans, struct printbuf *buf, 385 + struct bkey_s_c k, bool insert, enum bch_sb_error_id id) 386 + { 387 + struct bch_fs *c = trans->c; 388 + bool repeat = false, print = true, suppress = false; 389 + 390 + prt_printf(buf, "\nwhile marking "); 391 + bch2_bkey_val_to_text(buf, c, k); 392 + prt_newline(buf); 393 + 394 + __bch2_count_fsck_err(c, id, buf->buf, &repeat, &print, &suppress); 395 + 396 + int ret = bch2_run_explicit_recovery_pass(c, BCH_RECOVERY_PASS_check_allocations); 397 + 398 + if (insert) { 399 + print = true; 400 + suppress = false; 401 + 402 + bch2_trans_updates_to_text(buf, trans); 403 + __bch2_inconsistent_error(c, buf); 404 + ret = -BCH_ERR_bucket_ref_update; 405 + } 406 + 407 + if (suppress) 408 + prt_printf(buf, "Ratelimiting new instances of previous error\n"); 409 + if (print) 410 + bch2_print_string_as_lines(KERN_ERR, buf->buf); 411 + return ret; 412 + } 413 + 384 414 int bch2_bucket_ref_update(struct btree_trans *trans, struct bch_dev *ca, 385 415 struct bkey_s_c k, 386 416 const struct bch_extent_ptr *ptr, ··· 426 396 427 397 BUG_ON(!sectors); 428 398 429 - if (gen_after(ptr->gen, b_gen)) { 430 - bch2_run_explicit_recovery_pass(c, BCH_RECOVERY_PASS_check_allocations); 431 - log_fsck_err(trans, ptr_gen_newer_than_bucket_gen, 432 - "bucket %u:%zu gen %u data type %s: ptr gen %u newer than bucket gen\n" 433 - "while marking %s", 399 + if (unlikely(gen_after(ptr->gen, b_gen))) { 400 + bch2_log_msg_start(c, &buf); 401 + prt_printf(&buf, 402 + "bucket %u:%zu gen %u data type %s: ptr gen %u newer than bucket gen", 434 403 ptr->dev, bucket_nr, b_gen, 435 404 bch2_data_type_str(bucket_data_type ?: ptr_data_type), 436 - ptr->gen, 437 - (bch2_bkey_val_to_text(&buf, c, k), buf.buf)); 438 - if (inserting) 439 - goto err; 405 + ptr->gen); 406 + 407 + ret = bucket_ref_update_err(trans, &buf, k, inserting, 408 + BCH_FSCK_ERR_ptr_gen_newer_than_bucket_gen); 440 409 goto out; 441 410 } 442 411 443 - if (gen_cmp(b_gen, ptr->gen) > BUCKET_GC_GEN_MAX) { 444 - bch2_run_explicit_recovery_pass(c, BCH_RECOVERY_PASS_check_allocations); 445 - log_fsck_err(trans, ptr_too_stale, 446 - "bucket %u:%zu gen %u data type %s: ptr gen %u too stale\n" 447 - "while marking %s", 412 + if (unlikely(gen_cmp(b_gen, ptr->gen) > BUCKET_GC_GEN_MAX)) { 413 + bch2_log_msg_start(c, &buf); 414 + prt_printf(&buf, 415 + "bucket %u:%zu gen %u data type %s: ptr gen %u too stale", 448 416 ptr->dev, bucket_nr, b_gen, 449 417 bch2_data_type_str(bucket_data_type ?: ptr_data_type), 450 - ptr->gen, 451 - (printbuf_reset(&buf), 452 - bch2_bkey_val_to_text(&buf, c, k), buf.buf)); 453 - if (inserting) 454 - goto err; 418 + ptr->gen); 419 + 420 + ret = bucket_ref_update_err(trans, &buf, k, inserting, 421 + BCH_FSCK_ERR_ptr_too_stale); 455 422 goto out; 456 423 } 457 424 ··· 457 430 goto out; 458 431 } 459 432 460 - if (b_gen != ptr->gen) { 461 - bch2_run_explicit_recovery_pass(c, BCH_RECOVERY_PASS_check_allocations); 462 - log_fsck_err(trans, stale_dirty_ptr, 463 - "bucket %u:%zu gen %u (mem gen %u) data type %s: stale dirty ptr (gen %u)\n" 464 - "while marking %s", 433 + if (unlikely(b_gen != ptr->gen)) { 434 + bch2_log_msg_start(c, &buf); 435 + prt_printf(&buf, 436 + "bucket %u:%zu gen %u (mem gen %u) data type %s: stale dirty ptr (gen %u)", 465 437 ptr->dev, bucket_nr, b_gen, 466 438 bucket_gen_get(ca, bucket_nr), 467 439 bch2_data_type_str(bucket_data_type ?: ptr_data_type), 468 - ptr->gen, 469 - (printbuf_reset(&buf), 470 - bch2_bkey_val_to_text(&buf, c, k), buf.buf)); 471 - if (inserting) 472 - goto err; 440 + ptr->gen); 441 + 442 + ret = bucket_ref_update_err(trans, &buf, k, inserting, 443 + BCH_FSCK_ERR_stale_dirty_ptr); 473 444 goto out; 474 445 } 475 446 476 - if (bucket_data_type_mismatch(bucket_data_type, ptr_data_type)) { 477 - bch2_run_explicit_recovery_pass(c, BCH_RECOVERY_PASS_check_allocations); 478 - log_fsck_err(trans, ptr_bucket_data_type_mismatch, 479 - "bucket %u:%zu gen %u different types of data in same bucket: %s, %s\n" 480 - "while marking %s", 481 - ptr->dev, bucket_nr, b_gen, 482 - bch2_data_type_str(bucket_data_type), 483 - bch2_data_type_str(ptr_data_type), 484 - (printbuf_reset(&buf), 485 - bch2_bkey_val_to_text(&buf, c, k), buf.buf)); 486 - if (inserting) 487 - goto err; 447 + if (unlikely(bucket_data_type_mismatch(bucket_data_type, ptr_data_type))) { 448 + bch2_log_msg_start(c, &buf); 449 + prt_printf(&buf, "bucket %u:%zu gen %u different types of data in same bucket: %s, %s", 450 + ptr->dev, bucket_nr, b_gen, 451 + bch2_data_type_str(bucket_data_type), 452 + bch2_data_type_str(ptr_data_type)); 453 + 454 + ret = bucket_ref_update_err(trans, &buf, k, inserting, 455 + BCH_FSCK_ERR_ptr_bucket_data_type_mismatch); 488 456 goto out; 489 457 } 490 458 491 - if ((u64) *bucket_sectors + sectors > U32_MAX) { 492 - bch2_run_explicit_recovery_pass(c, BCH_RECOVERY_PASS_check_allocations); 493 - log_fsck_err(trans, bucket_sector_count_overflow, 494 - "bucket %u:%zu gen %u data type %s sector count overflow: %u + %lli > U32_MAX\n" 495 - "while marking %s", 459 + if (unlikely((u64) *bucket_sectors + sectors > U32_MAX)) { 460 + bch2_log_msg_start(c, &buf); 461 + prt_printf(&buf, 462 + "bucket %u:%zu gen %u data type %s sector count overflow: %u + %lli > U32_MAX", 496 463 ptr->dev, bucket_nr, b_gen, 497 464 bch2_data_type_str(bucket_data_type ?: ptr_data_type), 498 - *bucket_sectors, sectors, 499 - (printbuf_reset(&buf), 500 - bch2_bkey_val_to_text(&buf, c, k), buf.buf)); 501 - if (inserting) 502 - goto err; 465 + *bucket_sectors, sectors); 466 + 467 + ret = bucket_ref_update_err(trans, &buf, k, inserting, 468 + BCH_FSCK_ERR_bucket_sector_count_overflow); 503 469 sectors = -*bucket_sectors; 470 + goto out; 504 471 } 505 472 506 473 *bucket_sectors += sectors; 507 474 out: 508 475 printbuf_exit(&buf); 509 476 return ret; 510 - err: 511 - fsck_err: 512 - bch2_dump_trans_updates(trans); 513 - bch2_inconsistent_error(c); 514 - ret = -BCH_ERR_bucket_ref_update; 515 - goto out; 516 477 } 517 478 518 479 void bch2_trans_account_disk_usage_change(struct btree_trans *trans) ··· 666 651 stripe_blockcount_get(&s->v, p.ec.block) + 667 652 sectors); 668 653 669 - struct disk_accounting_pos acc = { 670 - .type = BCH_DISK_ACCOUNTING_replicas, 671 - }; 654 + struct disk_accounting_pos acc; 655 + memset(&acc, 0, sizeof(acc)); 656 + acc.type = BCH_DISK_ACCOUNTING_replicas; 672 657 bch2_bkey_to_replicas(&acc.replicas, bkey_i_to_s_c(&s->k_i)); 673 658 acc.replicas.data_type = data_type; 674 659 ret = bch2_disk_accounting_mod(trans, &acc, &sectors, 1, false); ··· 692 677 if (!m || !m->alive) { 693 678 gc_stripe_unlock(m); 694 679 struct printbuf buf = PRINTBUF; 680 + bch2_log_msg_start(c, &buf); 681 + prt_printf(&buf, "pointer to nonexistent stripe %llu\n while marking ", 682 + (u64) p.ec.idx); 695 683 bch2_bkey_val_to_text(&buf, c, k); 696 - bch_err_ratelimited(c, "pointer to nonexistent stripe %llu\n while marking %s", 697 - (u64) p.ec.idx, buf.buf); 684 + __bch2_inconsistent_error(c, &buf); 685 + bch2_print_string_as_lines(KERN_ERR, buf.buf); 698 686 printbuf_exit(&buf); 699 - bch2_inconsistent_error(c); 700 687 return -BCH_ERR_trigger_stripe_pointer; 701 688 } 702 689 703 690 m->block_sectors[p.ec.block] += sectors; 704 691 705 - struct disk_accounting_pos acc = { 706 - .type = BCH_DISK_ACCOUNTING_replicas, 707 - }; 692 + struct disk_accounting_pos acc; 693 + memset(&acc, 0, sizeof(acc)); 694 + acc.type = BCH_DISK_ACCOUNTING_replicas; 708 695 memcpy(&acc.replicas, &m->r.e, replicas_entry_bytes(&m->r.e)); 709 696 gc_stripe_unlock(m); 710 697 ··· 734 717 : BCH_DATA_user; 735 718 int ret = 0; 736 719 737 - struct disk_accounting_pos acc_replicas_key = { 738 - .type = BCH_DISK_ACCOUNTING_replicas, 739 - .replicas.data_type = data_type, 740 - .replicas.nr_devs = 0, 741 - .replicas.nr_required = 1, 742 - }; 720 + struct disk_accounting_pos acc_replicas_key; 721 + memset(&acc_replicas_key, 0, sizeof(acc_replicas_key)); 722 + acc_replicas_key.type = BCH_DISK_ACCOUNTING_replicas; 723 + acc_replicas_key.replicas.data_type = data_type; 724 + acc_replicas_key.replicas.nr_devs = 0; 725 + acc_replicas_key.replicas.nr_required = 1; 743 726 744 727 unsigned cur_compression_type = 0; 745 728 u64 compression_acct[3] = { 1, 0, 0 };
+2 -4
fs/bcachefs/chardev.c
··· 426 426 arg.replica_entries_bytes = replicas.nr; 427 427 428 428 for (unsigned i = 0; i < BCH_REPLICAS_MAX; i++) { 429 - struct disk_accounting_pos k = { 430 - .type = BCH_DISK_ACCOUNTING_persistent_reserved, 431 - .persistent_reserved.nr_replicas = i, 432 - }; 429 + struct disk_accounting_pos k; 430 + disk_accounting_key_init(k, persistent_reserved, .nr_replicas = i); 433 431 434 432 bch2_accounting_mem_read(c, 435 433 disk_accounting_pos_to_bpos(&k),
+21 -1
fs/bcachefs/data_update.c
··· 22 22 23 23 #include <linux/ioprio.h> 24 24 25 + static const char * const bch2_data_update_type_strs[] = { 26 + #define x(t, n, ...) [n] = #t, 27 + BCH_DATA_UPDATE_TYPES() 28 + #undef x 29 + NULL 30 + }; 31 + 25 32 static void bkey_put_dev_refs(struct bch_fs *c, struct bkey_s_c k) 26 33 { 27 34 struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k); ··· 188 181 container_of(op, struct data_update, op); 189 182 struct keylist *keys = &op->insert_keys; 190 183 struct bkey_buf _new, _insert; 184 + struct printbuf journal_msg = PRINTBUF; 191 185 int ret = 0; 192 186 193 187 bch2_bkey_buf_init(&_new); ··· 380 372 printbuf_exit(&buf); 381 373 } 382 374 383 - ret = bch2_insert_snapshot_whiteouts(trans, m->btree_id, 375 + printbuf_reset(&journal_msg); 376 + prt_str(&journal_msg, bch2_data_update_type_strs[m->type]); 377 + 378 + ret = bch2_trans_log_msg(trans, &journal_msg) ?: 379 + bch2_trans_log_bkey(trans, m->btree_id, 0, m->k.k) ?: 380 + bch2_insert_snapshot_whiteouts(trans, m->btree_id, 384 381 k.k->p, bkey_start_pos(&insert->k)) ?: 385 382 bch2_insert_snapshot_whiteouts(trans, m->btree_id, 386 383 k.k->p, insert->k.p) ?: ··· 430 417 goto next; 431 418 } 432 419 out: 420 + printbuf_exit(&journal_msg); 433 421 bch2_trans_iter_exit(trans, &iter); 434 422 bch2_bkey_buf_exit(&_insert, c); 435 423 bch2_bkey_buf_exit(&_new, c); ··· 591 577 592 578 void bch2_data_update_to_text(struct printbuf *out, struct data_update *m) 593 579 { 580 + prt_str(out, bch2_data_update_type_strs[m->type]); 581 + prt_newline(out); 582 + 594 583 bch2_data_update_opts_to_text(out, m->op.c, &m->op.opts, &m->data_opts); 595 584 prt_newline(out); 596 585 ··· 755 738 756 739 bch2_bkey_buf_init(&m->k); 757 740 bch2_bkey_buf_reassemble(&m->k, c, k); 741 + m->type = data_opts.btree_insert_flags & BCH_WATERMARK_copygc 742 + ? BCH_DATA_UPDATE_copygc 743 + : BCH_DATA_UPDATE_rebalance; 758 744 m->btree_id = btree_id; 759 745 m->data_opts = data_opts; 760 746 m->ctxt = ctxt;
+12
fs/bcachefs/data_update.h
··· 24 24 void bch2_data_update_opts_to_text(struct printbuf *, struct bch_fs *, 25 25 struct bch_io_opts *, struct data_update_opts *); 26 26 27 + #define BCH_DATA_UPDATE_TYPES() \ 28 + x(copygc, 0) \ 29 + x(rebalance, 1) \ 30 + x(promote, 2) 31 + 32 + enum bch_data_update_types { 33 + #define x(n, id) BCH_DATA_UPDATE_##n = id, 34 + BCH_DATA_UPDATE_TYPES() 35 + #undef x 36 + }; 37 + 27 38 struct data_update { 39 + enum bch_data_update_types type; 28 40 /* extent being updated: */ 29 41 bool read_done; 30 42 enum btree_id btree_id;
+26 -14
fs/bcachefs/disk_accounting.c
··· 114 114 unsigned dev, s64 sectors, 115 115 bool gc) 116 116 { 117 - struct disk_accounting_pos acc = { 118 - .type = BCH_DISK_ACCOUNTING_replicas, 119 - }; 120 - 117 + struct disk_accounting_pos acc; 118 + memset(&acc, 0, sizeof(acc)); 119 + acc.type = BCH_DISK_ACCOUNTING_replicas; 121 120 bch2_replicas_entry_cached(&acc.replicas, dev); 122 121 123 122 return bch2_disk_accounting_mod(trans, &acc, &sectors, 1, gc); ··· 133 134 } 134 135 135 136 #define field_end(p, member) (((void *) (&p.member)) + sizeof(p.member)) 137 + 138 + static const unsigned bch2_accounting_type_nr_counters[] = { 139 + #define x(f, id, nr) [BCH_DISK_ACCOUNTING_##f] = nr, 140 + BCH_DISK_ACCOUNTING_TYPES() 141 + #undef x 142 + }; 136 143 137 144 int bch2_accounting_validate(struct bch_fs *c, struct bkey_s_c k, 138 145 struct bkey_validate_context from) ··· 198 193 bkey_fsck_err_on(!is_zero(end, (void *) (&acc_k + 1)), 199 194 c, accounting_key_junk_at_end, 200 195 "junk at end of accounting key"); 196 + 197 + bkey_fsck_err_on(bch2_accounting_counters(k.k) != bch2_accounting_type_nr_counters[acc_k.type], 198 + c, accounting_key_nr_counters_wrong, 199 + "accounting key with %u counters, should be %u", 200 + bch2_accounting_counters(k.k), bch2_accounting_type_nr_counters[acc_k.type]); 201 201 fsck_err: 202 202 return ret; 203 203 } ··· 645 635 646 636 if (fsck_err_on(!bch2_replicas_marked_locked(c, &r.e), 647 637 trans, accounting_replicas_not_marked, 648 - "accounting not marked in superblock replicas\n %s", 638 + "accounting not marked in superblock replicas\n%s", 649 639 (printbuf_reset(&buf), 650 640 bch2_accounting_key_to_text(&buf, &acc), 651 641 buf.buf))) { ··· 675 665 return ret; 676 666 invalid_device: 677 667 if (fsck_err(trans, accounting_to_invalid_device, 678 - "accounting entry points to invalid device %i\n %s", 668 + "accounting entry points to invalid device %i\n%s", 679 669 invalid_dev, 680 670 (printbuf_reset(&buf), 681 671 bch2_accounting_key_to_text(&buf, &acc), ··· 736 726 break; 737 727 738 728 if (!bch2_accounting_is_mem(acc_k)) { 739 - struct disk_accounting_pos next = { .type = acc_k.type + 1 }; 729 + struct disk_accounting_pos next; 730 + memset(&next, 0, sizeof(next)); 731 + next.type = acc_k.type + 1; 740 732 bch2_btree_iter_set_pos(&iter, disk_accounting_pos_to_bpos(&next)); 741 733 continue; 742 734 } ··· 894 882 int bch2_dev_usage_init(struct bch_dev *ca, bool gc) 895 883 { 896 884 struct bch_fs *c = ca->fs; 897 - struct disk_accounting_pos acc = { 898 - .type = BCH_DISK_ACCOUNTING_dev_data_type, 899 - .dev_data_type.dev = ca->dev_idx, 900 - .dev_data_type.data_type = BCH_DATA_free, 901 - }; 902 885 u64 v[3] = { ca->mi.nbuckets - ca->mi.first_bucket, 0, 0 }; 903 886 904 887 int ret = bch2_trans_do(c, ({ 905 - bch2_disk_accounting_mod(trans, &acc, v, ARRAY_SIZE(v), gc) ?: 888 + bch2_disk_accounting_mod2(trans, gc, 889 + v, dev_data_type, 890 + .dev = ca->dev_idx, 891 + .data_type = BCH_DATA_free) ?: 906 892 (!gc ? bch2_trans_commit(trans, NULL, NULL, 0) : 0); 907 893 })); 908 894 bch_err_fn(c, ret); ··· 927 917 break; 928 918 929 919 if (!bch2_accounting_is_mem(acc_k)) { 930 - struct disk_accounting_pos next = { .type = acc_k.type + 1 }; 920 + struct disk_accounting_pos next; 921 + memset(&next, 0, sizeof(next)); 922 + next.type = acc_k.type + 1; 931 923 bch2_btree_iter_set_pos(&iter, disk_accounting_pos_to_bpos(&next)); 932 924 continue; 933 925 }
+5 -3
fs/bcachefs/disk_accounting.h
··· 33 33 static inline void bch2_accounting_accumulate(struct bkey_i_accounting *dst, 34 34 struct bkey_s_c_accounting src) 35 35 { 36 - EBUG_ON(dst->k.u64s != src.k->u64s); 37 - 38 - for (unsigned i = 0; i < bch2_accounting_counters(&dst->k); i++) 36 + for (unsigned i = 0; 37 + i < min(bch2_accounting_counters(&dst->k), 38 + bch2_accounting_counters(src.k)); 39 + i++) 39 40 dst->v.d[i] += src.v->d[i]; 41 + 40 42 if (bversion_cmp(dst->k.bversion, src.k->bversion) < 0) 41 43 dst->k.bversion = src.k->bversion; 42 44 }
+69 -11
fs/bcachefs/disk_accounting_format.h
··· 95 95 } 96 96 } 97 97 98 + /* 99 + * field 1: name 100 + * field 2: id 101 + * field 3: number of counters (max 3) 102 + */ 103 + 98 104 #define BCH_DISK_ACCOUNTING_TYPES() \ 99 - x(nr_inodes, 0) \ 100 - x(persistent_reserved, 1) \ 101 - x(replicas, 2) \ 102 - x(dev_data_type, 3) \ 103 - x(compression, 4) \ 104 - x(snapshot, 5) \ 105 - x(btree, 6) \ 106 - x(rebalance_work, 7) \ 107 - x(inum, 8) 105 + x(nr_inodes, 0, 1) \ 106 + x(persistent_reserved, 1, 1) \ 107 + x(replicas, 2, 1) \ 108 + x(dev_data_type, 3, 3) \ 109 + x(compression, 4, 3) \ 110 + x(snapshot, 5, 1) \ 111 + x(btree, 6, 1) \ 112 + x(rebalance_work, 7, 1) \ 113 + x(inum, 8, 3) 108 114 109 115 enum disk_accounting_type { 110 - #define x(f, nr) BCH_DISK_ACCOUNTING_##f = nr, 116 + #define x(f, nr, ...) BCH_DISK_ACCOUNTING_##f = nr, 111 117 BCH_DISK_ACCOUNTING_TYPES() 112 118 #undef x 113 119 BCH_DISK_ACCOUNTING_TYPE_NR, 114 120 }; 115 121 122 + /* 123 + * No subtypes - number of inodes in the entire filesystem 124 + * 125 + * XXX: perhaps we could add a per-subvolume counter? 126 + */ 116 127 struct bch_acct_nr_inodes { 117 128 }; 118 129 130 + /* 131 + * Tracks KEY_TYPE_reservation sectors, broken out by number of replicas for the 132 + * reservation: 133 + */ 119 134 struct bch_acct_persistent_reserved { 120 135 __u8 nr_replicas; 121 136 }; 122 137 138 + /* 139 + * device, data type counter fields: 140 + * [ 141 + * nr_buckets 142 + * live sectors (in buckets of that data type) 143 + * sectors of internal fragmentation 144 + * ] 145 + * 146 + * XXX: live sectors should've been done differently, you can have multiple data 147 + * types in the same bucket (user, stripe, cached) and this collapses them to 148 + * the bucket data type, and makes the internal fragmentation counter redundant 149 + */ 123 150 struct bch_acct_dev_data_type { 124 151 __u8 dev; 125 152 __u8 data_type; 126 153 }; 127 154 155 + /* 156 + * Compression type fields: 157 + * [ 158 + * number of extents 159 + * uncompressed size 160 + * compressed size 161 + * ] 162 + * 163 + * Compression ratio, average extent size (fragmentation). 164 + */ 128 165 struct bch_acct_compression { 129 166 __u8 type; 130 167 }; 131 168 169 + /* 170 + * On disk usage by snapshot id; counts same values as replicas counter, but 171 + * aggregated differently 172 + */ 132 173 struct bch_acct_snapshot { 133 174 __u32 id; 134 175 } __packed; ··· 178 137 __u32 id; 179 138 } __packed; 180 139 140 + /* 141 + * inum counter fields: 142 + * [ 143 + * number of extents 144 + * sum of extent sizes - bkey size 145 + * this field is similar to inode.bi_sectors, except here extents in 146 + * different snapshots but the same inode number are all collapsed to the 147 + * same counter 148 + * sum of on disk size - same values tracked by replicas counters 149 + * ] 150 + * 151 + * This tracks on disk fragmentation. 152 + */ 181 153 struct bch_acct_inum { 182 154 __u64 inum; 183 155 } __packed; 184 156 157 + /* 158 + * Simple counter of the amount of data (on disk sectors) rebalance needs to 159 + * move, extents counted here are also in the rebalance_work btree. 160 + */ 185 161 struct bch_acct_rebalance_work { 186 162 }; 187 163 ··· 207 149 struct { 208 150 __u8 type; 209 151 union { 210 - struct bch_acct_nr_inodes nr_inodes; 152 + struct bch_acct_nr_inodes nr_inodes; 211 153 struct bch_acct_persistent_reserved persistent_reserved; 212 154 struct bch_replicas_entry_v1 replicas; 213 155 struct bch_acct_dev_data_type dev_data_type;
+12 -10
fs/bcachefs/ec.c
··· 320 320 321 321 if (flags & BTREE_TRIGGER_gc) { 322 322 struct bucket *g = gc_bucket(ca, bucket.offset); 323 - if (bch2_fs_inconsistent_on(!g, c, "reference to invalid bucket on device %u\n %s", 323 + if (bch2_fs_inconsistent_on(!g, c, "reference to invalid bucket on device %u\n%s", 324 324 ptr->dev, 325 325 (bch2_bkey_val_to_text(&buf, c, s.s_c), buf.buf))) { 326 326 ret = -BCH_ERR_mark_stripe; ··· 453 453 if (new_s) { 454 454 s64 sectors = (u64) le16_to_cpu(new_s->sectors) * new_s->nr_redundant; 455 455 456 - struct disk_accounting_pos acc = { 457 - .type = BCH_DISK_ACCOUNTING_replicas, 458 - }; 456 + struct disk_accounting_pos acc; 457 + memset(&acc, 0, sizeof(acc)); 458 + acc.type = BCH_DISK_ACCOUNTING_replicas; 459 459 bch2_bkey_to_replicas(&acc.replicas, new); 460 460 int ret = bch2_disk_accounting_mod(trans, &acc, &sectors, 1, gc); 461 461 if (ret) ··· 468 468 if (old_s) { 469 469 s64 sectors = -((s64) le16_to_cpu(old_s->sectors)) * old_s->nr_redundant; 470 470 471 - struct disk_accounting_pos acc = { 472 - .type = BCH_DISK_ACCOUNTING_replicas, 473 - }; 471 + struct disk_accounting_pos acc; 472 + memset(&acc, 0, sizeof(acc)); 473 + acc.type = BCH_DISK_ACCOUNTING_replicas; 474 474 bch2_bkey_to_replicas(&acc.replicas, old); 475 475 int ret = bch2_disk_accounting_mod(trans, &acc, &sectors, 1, gc); 476 476 if (ret) ··· 2110 2110 if (ret) 2111 2111 return ret; 2112 2112 2113 - struct disk_accounting_pos acc = { 2114 - .type = BCH_DISK_ACCOUNTING_replicas, 2115 - }; 2113 + struct disk_accounting_pos acc; 2116 2114 2117 2115 s64 sectors = 0; 2118 2116 for (unsigned i = 0; i < s->v.nr_blocks; i++) 2119 2117 sectors -= stripe_blockcount_get(&s->v, i); 2120 2118 2119 + memset(&acc, 0, sizeof(acc)); 2120 + acc.type = BCH_DISK_ACCOUNTING_replicas; 2121 2121 bch2_bkey_to_replicas(&acc.replicas, bkey_i_to_s_c(&s->k_i)); 2122 2122 acc.replicas.data_type = BCH_DATA_user; 2123 2123 ret = bch2_disk_accounting_mod(trans, &acc, &sectors, 1, false); ··· 2131 2131 2132 2132 sectors = -sectors; 2133 2133 2134 + memset(&acc, 0, sizeof(acc)); 2135 + acc.type = BCH_DISK_ACCOUNTING_replicas; 2134 2136 bch2_bkey_to_replicas(&acc.replicas, bkey_i_to_s_c(&s->k_i)); 2135 2137 acc.replicas.data_type = BCH_DATA_user; 2136 2138 ret = bch2_disk_accounting_mod(trans, &acc, &sectors, 1, false);
+3
fs/bcachefs/errcode.h
··· 5 5 #define BCH_ERRCODES() \ 6 6 x(ERANGE, ERANGE_option_too_small) \ 7 7 x(ERANGE, ERANGE_option_too_big) \ 8 + x(EINVAL, injected) \ 9 + x(BCH_ERR_injected, injected_fs_start) \ 8 10 x(EINVAL, mount_option) \ 9 11 x(BCH_ERR_mount_option, option_name) \ 10 12 x(BCH_ERR_mount_option, option_value) \ ··· 310 308 x(BCH_ERR_data_write, data_write_misaligned) \ 311 309 x(BCH_ERR_decompress, data_read) \ 312 310 x(BCH_ERR_data_read, no_device_to_read_from) \ 311 + x(BCH_ERR_data_read, no_devices_valid) \ 313 312 x(BCH_ERR_data_read, data_read_io_err) \ 314 313 x(BCH_ERR_data_read, data_read_csum_err) \ 315 314 x(BCH_ERR_data_read, data_read_retry) \
+167 -59
fs/bcachefs/error.c
··· 11 11 12 12 #define FSCK_ERR_RATELIMIT_NR 10 13 13 14 - bool bch2_inconsistent_error(struct bch_fs *c) 14 + void bch2_log_msg_start(struct bch_fs *c, struct printbuf *out) 15 + { 16 + printbuf_indent_add_nextline(out, 2); 17 + 18 + #ifdef BCACHEFS_LOG_PREFIX 19 + prt_printf(out, bch2_log_msg(c, "")); 20 + #endif 21 + } 22 + 23 + bool __bch2_inconsistent_error(struct bch_fs *c, struct printbuf *out) 15 24 { 16 25 set_bit(BCH_FS_error, &c->flags); 17 26 ··· 30 21 case BCH_ON_ERROR_fix_safe: 31 22 case BCH_ON_ERROR_ro: 32 23 if (bch2_fs_emergency_read_only(c)) 33 - bch_err(c, "inconsistency detected - emergency read only at journal seq %llu", 34 - journal_cur_seq(&c->journal)); 24 + prt_printf(out, "inconsistency detected - emergency read only at journal seq %llu\n", 25 + journal_cur_seq(&c->journal)); 35 26 return true; 36 27 case BCH_ON_ERROR_panic: 28 + bch2_print_string_as_lines(KERN_ERR, out->buf); 37 29 panic(bch2_fmt(c, "panic after error")); 38 30 return true; 39 31 default: ··· 42 32 } 43 33 } 44 34 45 - int bch2_topology_error(struct bch_fs *c) 35 + bool bch2_inconsistent_error(struct bch_fs *c) 46 36 { 37 + struct printbuf buf = PRINTBUF; 38 + printbuf_indent_add_nextline(&buf, 2); 39 + 40 + bool ret = __bch2_inconsistent_error(c, &buf); 41 + if (ret) 42 + bch_err(c, "%s", buf.buf); 43 + printbuf_exit(&buf); 44 + return ret; 45 + } 46 + 47 + __printf(3, 0) 48 + static bool bch2_fs_trans_inconsistent(struct bch_fs *c, struct btree_trans *trans, 49 + const char *fmt, va_list args) 50 + { 51 + struct printbuf buf = PRINTBUF; 52 + 53 + bch2_log_msg_start(c, &buf); 54 + 55 + prt_vprintf(&buf, fmt, args); 56 + prt_newline(&buf); 57 + 58 + if (trans) 59 + bch2_trans_updates_to_text(&buf, trans); 60 + bool ret = __bch2_inconsistent_error(c, &buf); 61 + bch2_print_string_as_lines(KERN_ERR, buf.buf); 62 + 63 + printbuf_exit(&buf); 64 + return ret; 65 + } 66 + 67 + bool bch2_fs_inconsistent(struct bch_fs *c, const char *fmt, ...) 68 + { 69 + va_list args; 70 + va_start(args, fmt); 71 + bool ret = bch2_fs_trans_inconsistent(c, NULL, fmt, args); 72 + va_end(args); 73 + return ret; 74 + } 75 + 76 + bool bch2_trans_inconsistent(struct btree_trans *trans, const char *fmt, ...) 77 + { 78 + va_list args; 79 + va_start(args, fmt); 80 + bool ret = bch2_fs_trans_inconsistent(trans->c, trans, fmt, args); 81 + va_end(args); 82 + return ret; 83 + } 84 + 85 + int __bch2_topology_error(struct bch_fs *c, struct printbuf *out) 86 + { 87 + prt_printf(out, "btree topology error: "); 88 + 47 89 set_bit(BCH_FS_topology_error, &c->flags); 48 90 if (!test_bit(BCH_FS_recovery_running, &c->flags)) { 49 - bch2_inconsistent_error(c); 91 + __bch2_inconsistent_error(c, out); 50 92 return -BCH_ERR_btree_need_topology_repair; 51 93 } else { 52 94 return bch2_run_explicit_recovery_pass(c, BCH_RECOVERY_PASS_check_topology) ?: 53 95 -BCH_ERR_btree_node_read_validate_error; 54 96 } 97 + } 98 + 99 + int bch2_fs_topology_error(struct bch_fs *c, const char *fmt, ...) 100 + { 101 + struct printbuf buf = PRINTBUF; 102 + 103 + bch2_log_msg_start(c, &buf); 104 + 105 + va_list args; 106 + va_start(args, fmt); 107 + prt_vprintf(&buf, fmt, args); 108 + va_end(args); 109 + 110 + int ret = __bch2_topology_error(c, &buf); 111 + bch2_print_string_as_lines(KERN_ERR, buf.buf); 112 + 113 + printbuf_exit(&buf); 114 + return ret; 55 115 } 56 116 57 117 void bch2_fatal_error(struct bch_fs *c) ··· 264 184 265 185 #endif 266 186 267 - static struct fsck_err_state *fsck_err_get(struct bch_fs *c, const char *fmt) 187 + static struct fsck_err_state *fsck_err_get(struct bch_fs *c, 188 + enum bch_sb_error_id id) 268 189 { 269 190 struct fsck_err_state *s; 270 191 ··· 273 192 return NULL; 274 193 275 194 list_for_each_entry(s, &c->fsck_error_msgs, list) 276 - if (s->fmt == fmt) { 195 + if (s->id == id) { 277 196 /* 278 197 * move it to the head of the list: repeated fsck errors 279 198 * are common ··· 291 210 } 292 211 293 212 INIT_LIST_HEAD(&s->list); 294 - s->fmt = fmt; 213 + s->id = id; 295 214 list_add(&s->list, &c->fsck_error_msgs); 296 215 return s; 297 216 } ··· 341 260 return ask; 342 261 } 343 262 263 + static struct fsck_err_state *count_fsck_err_locked(struct bch_fs *c, 264 + enum bch_sb_error_id id, const char *msg, 265 + bool *repeat, bool *print, bool *suppress) 266 + { 267 + bch2_sb_error_count(c, id); 268 + 269 + struct fsck_err_state *s = fsck_err_get(c, id); 270 + if (s) { 271 + /* 272 + * We may be called multiple times for the same error on 273 + * transaction restart - this memoizes instead of asking the user 274 + * multiple times for the same error: 275 + */ 276 + if (s->last_msg && !strcmp(msg, s->last_msg)) { 277 + *repeat = true; 278 + *print = false; 279 + return s; 280 + } 281 + 282 + kfree(s->last_msg); 283 + s->last_msg = kstrdup(msg, GFP_KERNEL); 284 + 285 + if (c->opts.ratelimit_errors && 286 + s->nr >= FSCK_ERR_RATELIMIT_NR) { 287 + if (s->nr == FSCK_ERR_RATELIMIT_NR) 288 + *suppress = true; 289 + else 290 + *print = false; 291 + } 292 + 293 + s->nr++; 294 + } 295 + return s; 296 + } 297 + 298 + void __bch2_count_fsck_err(struct bch_fs *c, 299 + enum bch_sb_error_id id, const char *msg, 300 + bool *repeat, bool *print, bool *suppress) 301 + { 302 + bch2_sb_error_count(c, id); 303 + 304 + mutex_lock(&c->fsck_error_msgs_lock); 305 + count_fsck_err_locked(c, id, msg, repeat, print, suppress); 306 + mutex_unlock(&c->fsck_error_msgs_lock); 307 + } 308 + 344 309 int __bch2_fsck_err(struct bch_fs *c, 345 310 struct btree_trans *trans, 346 311 enum bch_fsck_flags flags, 347 312 enum bch_sb_error_id err, 348 313 const char *fmt, ...) 349 314 { 350 - struct fsck_err_state *s = NULL; 351 315 va_list args; 352 - bool print = true, suppressing = false, inconsistent = false, exiting = false; 353 316 struct printbuf buf = PRINTBUF, *out = &buf; 354 317 int ret = -BCH_ERR_fsck_ignore; 355 318 const char *action_orig = "fix?", *action = action_orig; ··· 428 303 ? -BCH_ERR_fsck_fix 429 304 : -BCH_ERR_fsck_ignore; 430 305 431 - bch2_sb_error_count(c, err); 306 + printbuf_indent_add_nextline(out, 2); 307 + 308 + #ifdef BCACHEFS_LOG_PREFIX 309 + if (strncmp(fmt, "bcachefs", 8)) 310 + prt_printf(out, bch2_log_msg(c, "")); 311 + #endif 432 312 433 313 va_start(args, fmt); 434 314 prt_vprintf(out, fmt, args); ··· 453 323 } 454 324 455 325 mutex_lock(&c->fsck_error_msgs_lock); 456 - s = fsck_err_get(c, fmt); 457 - if (s) { 458 - /* 459 - * We may be called multiple times for the same error on 460 - * transaction restart - this memoizes instead of asking the user 461 - * multiple times for the same error: 462 - */ 463 - if (s->last_msg && !strcmp(buf.buf, s->last_msg)) { 464 - ret = s->ret; 465 - goto err_unlock; 466 - } 467 - 468 - kfree(s->last_msg); 469 - s->last_msg = kstrdup(buf.buf, GFP_KERNEL); 470 - if (!s->last_msg) { 471 - ret = -ENOMEM; 472 - goto err_unlock; 473 - } 474 - 475 - if (c->opts.ratelimit_errors && 476 - !(flags & FSCK_NO_RATELIMIT) && 477 - s->nr >= FSCK_ERR_RATELIMIT_NR) { 478 - if (s->nr == FSCK_ERR_RATELIMIT_NR) 479 - suppressing = true; 480 - else 481 - print = false; 482 - } 483 - 484 - s->nr++; 326 + bool repeat = false, print = true, suppress = false; 327 + bool inconsistent = false, exiting = false; 328 + struct fsck_err_state *s = 329 + count_fsck_err_locked(c, err, buf.buf, &repeat, &print, &suppress); 330 + if (repeat) { 331 + ret = s->ret; 332 + goto err_unlock; 485 333 } 486 - 487 - #ifdef BCACHEFS_LOG_PREFIX 488 - if (!strncmp(fmt, "bcachefs:", 9)) 489 - prt_printf(out, bch2_log_msg(c, "")); 490 - #endif 491 334 492 335 if ((flags & FSCK_AUTOFIX) && 493 336 (c->opts.errors == BCH_ON_ERROR_continue || ··· 480 377 !(flags & (FSCK_CAN_FIX|FSCK_CAN_IGNORE))) { 481 378 prt_str(out, ", shutting down"); 482 379 inconsistent = true; 380 + print = true; 483 381 ret = -BCH_ERR_fsck_errors_not_fixed; 484 382 } else if (flags & FSCK_CAN_FIX) { 485 383 prt_str(out, ", "); ··· 539 435 print = true; 540 436 } 541 437 print: 438 + prt_newline(out); 439 + 440 + if (inconsistent) 441 + __bch2_inconsistent_error(c, out); 442 + else if (exiting) 443 + prt_printf(out, "Unable to continue, halting\n"); 444 + else if (suppress) 445 + prt_printf(out, "Ratelimiting new instances of previous error\n"); 446 + 542 447 if (print) { 448 + /* possibly strip an empty line, from printbuf_indent_add */ 449 + while (out->pos && out->buf[out->pos - 1] == ' ') 450 + --out->pos; 451 + printbuf_nul_terminate(out); 452 + 543 453 if (bch2_fs_stdio_redirect(c)) 544 - bch2_print(c, "%s\n", out->buf); 454 + bch2_print(c, "%s", out->buf); 545 455 else 546 456 bch2_print_string_as_lines(KERN_ERR, out->buf); 547 457 } 548 458 549 - if (exiting) 550 - bch_err(c, "Unable to continue, halting"); 551 - else if (suppressing) 552 - bch_err(c, "Ratelimiting new instances of previous error"); 553 - 554 459 if (s) 555 460 s->ret = ret; 556 - 557 - if (inconsistent) 558 - bch2_inconsistent_error(c); 559 461 560 462 /* 561 463 * We don't yet track whether the filesystem currently has errors, for ··· 624 514 prt_printf(&buf, " level=%u: ", from.level); 625 515 626 516 bch2_bkey_val_to_text(&buf, c, k); 627 - prt_str(&buf, "\n "); 517 + prt_newline(&buf); 628 518 629 519 va_list args; 630 520 va_start(args, fmt); 631 521 prt_vprintf(&buf, fmt, args); 632 522 va_end(args); 633 523 634 - prt_str(&buf, ": delete?"); 635 - 636 - int ret = __bch2_fsck_err(c, NULL, fsck_flags, err, "%s", buf.buf); 524 + int ret = __bch2_fsck_err(c, NULL, fsck_flags, err, "%s, delete?", buf.buf); 637 525 printbuf_exit(&buf); 638 526 return ret; 639 527 } ··· 644 536 645 537 list_for_each_entry_safe(s, n, &c->fsck_error_msgs, list) { 646 538 if (s->ratelimited && s->last_msg) 647 - bch_err(c, "Saw %llu errors like:\n %s", s->nr, s->last_msg); 539 + bch_err(c, "Saw %llu errors like:\n %s", s->nr, s->last_msg); 648 540 649 541 list_del(&s->list); 650 542 kfree(s->last_msg);
+20 -28
fs/bcachefs/error.h
··· 18 18 19 19 /* Error messages: */ 20 20 21 + void bch2_log_msg_start(struct bch_fs *, struct printbuf *); 22 + 21 23 /* 22 24 * Inconsistency errors: The on disk data is inconsistent. If these occur during 23 25 * initial recovery, they don't indicate a bug in the running code - we walk all ··· 31 29 * BCH_ON_ERROR_CONTINUE mode 32 30 */ 33 31 32 + bool __bch2_inconsistent_error(struct bch_fs *, struct printbuf *); 34 33 bool bch2_inconsistent_error(struct bch_fs *); 35 - 36 - int bch2_topology_error(struct bch_fs *); 37 - 38 - #define bch2_fs_topology_error(c, ...) \ 39 - ({ \ 40 - bch_err(c, "btree topology error: " __VA_ARGS__); \ 41 - bch2_topology_error(c); \ 42 - }) 43 - 44 - #define bch2_fs_inconsistent(c, ...) \ 45 - ({ \ 46 - bch_err(c, __VA_ARGS__); \ 47 - bch2_inconsistent_error(c); \ 48 - }) 34 + __printf(2, 3) 35 + bool bch2_fs_inconsistent(struct bch_fs *, const char *, ...); 49 36 50 37 #define bch2_fs_inconsistent_on(cond, ...) \ 51 38 ({ \ ··· 44 53 _ret; \ 45 54 }) 46 55 47 - /* 48 - * When a transaction update discovers or is causing a fs inconsistency, it's 49 - * helpful to also dump the pending updates: 50 - */ 51 - #define bch2_trans_inconsistent(trans, ...) \ 52 - ({ \ 53 - bch_err(trans->c, __VA_ARGS__); \ 54 - bch2_dump_trans_updates(trans); \ 55 - bch2_inconsistent_error(trans->c); \ 56 - }) 56 + __printf(2, 3) 57 + bool bch2_trans_inconsistent(struct btree_trans *, const char *, ...); 57 58 58 - #define bch2_trans_inconsistent_on(cond, trans, ...) \ 59 + #define bch2_trans_inconsistent_on(cond, ...) \ 59 60 ({ \ 60 61 bool _ret = unlikely(!!(cond)); \ 61 - \ 62 62 if (_ret) \ 63 - bch2_trans_inconsistent(trans, __VA_ARGS__); \ 63 + bch2_trans_inconsistent(__VA_ARGS__); \ 64 64 _ret; \ 65 65 }) 66 + 67 + int __bch2_topology_error(struct bch_fs *, struct printbuf *); 68 + __printf(2, 3) 69 + int bch2_fs_topology_error(struct bch_fs *, const char *, ...); 66 70 67 71 /* 68 72 * Fsck errors: inconsistency errors we detect at mount time, and should ideally ··· 66 80 67 81 struct fsck_err_state { 68 82 struct list_head list; 69 - const char *fmt; 83 + enum bch_sb_error_id id; 70 84 u64 nr; 71 85 bool ratelimited; 72 86 int ret; ··· 75 89 }; 76 90 77 91 #define fsck_err_count(_c, _err) bch2_sb_err_count(_c, BCH_FSCK_ERR_##_err) 92 + 93 + void __bch2_count_fsck_err(struct bch_fs *, 94 + enum bch_sb_error_id, const char *, 95 + bool *, bool *, bool *); 96 + #define bch2_count_fsck_err(_c, _err, ...) \ 97 + __bch2_count_fsck_err(_c, BCH_FSCK_ERR_##_err, __VA_ARGS__) 78 98 79 99 __printf(5, 6) __cold 80 100 int __bch2_fsck_err(struct bch_fs *, struct btree_trans *,
+5 -2
fs/bcachefs/extents.c
··· 227 227 if (have_io_errors) 228 228 return -BCH_ERR_data_read_io_err; 229 229 230 - WARN_ONCE(1, "unhandled error case in %s\n", __func__); 231 - return -EINVAL; 230 + /* 231 + * If we get here, we have pointers (bkey_ptrs_validate() ensures that), 232 + * but they don't point to valid devices: 233 + */ 234 + return -BCH_ERR_no_devices_valid; 232 235 } 233 236 234 237 /* KEY_TYPE_btree_ptr: */
+1 -1
fs/bcachefs/fs-io-buffered.c
··· 225 225 226 226 bch2_read_extent(trans, rbio, iter.pos, 227 227 data_btree, k, offset_into_extent, flags); 228 + swap(rbio->bio.bi_iter.bi_size, bytes); 228 229 229 230 if (flags & BCH_READ_last_fragment) 230 231 break; 231 232 232 - swap(rbio->bio.bi_iter.bi_size, bytes); 233 233 bio_advance(&rbio->bio, bytes); 234 234 err: 235 235 if (ret &&
+20 -9
fs/bcachefs/fs-io.c
··· 999 999 POS(inode->v.i_ino, offset >> 9), 1000 1000 POS(inode->v.i_ino, U64_MAX), 1001 1001 inum.subvol, BTREE_ITER_slots, k, ({ 1002 - if (k.k->p.inode != inode->v.i_ino) { 1003 - next_hole = bch2_seek_pagecache_hole(&inode->v, 1004 - offset, MAX_LFS_FILESIZE, 0, false); 1005 - break; 1006 - } else if (!bkey_extent_is_data(k.k)) { 1007 - next_hole = bch2_seek_pagecache_hole(&inode->v, 1008 - max(offset, bkey_start_offset(k.k) << 9), 1009 - k.k->p.offset << 9, 0, false); 1002 + if (k.k->p.inode != inode->v.i_ino || 1003 + !bkey_extent_is_data(k.k)) { 1004 + loff_t start_offset = k.k->p.inode == inode->v.i_ino 1005 + ? max(offset, bkey_start_offset(k.k) << 9) 1006 + : offset; 1007 + loff_t end_offset = k.k->p.inode == inode->v.i_ino 1008 + ? MAX_LFS_FILESIZE 1009 + : k.k->p.offset << 9; 1010 1010 1011 - if (next_hole < k.k->p.offset << 9) 1011 + /* 1012 + * Found a hole in the btree, now make sure it's 1013 + * a hole in the pagecache. We might have to 1014 + * keep searching if this hole is entirely dirty 1015 + * in the page cache: 1016 + */ 1017 + bch2_trans_unlock(trans); 1018 + loff_t pagecache_hole = bch2_seek_pagecache_hole(&inode->v, 1019 + start_offset, end_offset, 0, false); 1020 + if (pagecache_hole < end_offset) { 1021 + next_hole = pagecache_hole; 1012 1022 break; 1023 + } 1013 1024 } else { 1014 1025 offset = max(offset, bkey_start_offset(k.k) << 9); 1015 1026 }
+4 -2
fs/bcachefs/fs-ioctl.c
··· 537 537 ret = -EXDEV; 538 538 goto err; 539 539 } 540 - ret = __bch2_unlink(dir, victim, true); 540 + 541 + ret = inode_permission(file_mnt_idmap(filp), d_inode(victim), MAY_WRITE) ?: 542 + __bch2_unlink(dir, victim, true); 541 543 if (!ret) { 542 544 fsnotify_rmdir(dir, victim); 543 - d_delete(victim); 545 + d_invalidate(victim); 544 546 } 545 547 err: 546 548 inode_unlock(dir);
+6 -3
fs/bcachefs/fs.c
··· 673 673 * back to this dirent 674 674 */ 675 675 bch2_fs_inconsistent_on(bch2_err_matches(ret, ENOENT), 676 - c, "dirent to missing inode:\n %s", 676 + c, "dirent to missing inode:\n%s", 677 677 (bch2_bkey_val_to_text(&buf, c, d.s_c), buf.buf)); 678 678 if (ret) 679 679 goto err; ··· 2179 2179 2180 2180 /* Some options can't be parsed until after the fs is started: */ 2181 2181 opts = bch2_opts_empty(); 2182 - ret = bch2_parse_mount_opts(c, &opts, NULL, opts_parse->parse_later.buf); 2182 + ret = bch2_parse_mount_opts(c, &opts, NULL, opts_parse->parse_later.buf, false); 2183 2183 if (ret) 2184 2184 goto err_stop_fs; 2185 2185 ··· 2290 2290 goto err; 2291 2291 2292 2292 err_put_super: 2293 - __bch2_fs_stop(c); 2293 + if (!sb->s_root) 2294 + __bch2_fs_stop(c); 2294 2295 deactivate_locked_super(sb); 2295 2296 goto err; 2296 2297 } ··· 2334 2333 int ret = bch2_parse_one_mount_opt(c, &opts->opts, 2335 2334 &opts->parse_later, param->key, 2336 2335 param->string); 2336 + if (ret) 2337 + pr_err("Error parsing option %s: %s", param->key, bch2_err_str(ret)); 2337 2338 2338 2339 return bch2_err_class(ret); 2339 2340 }
+12 -10
fs/bcachefs/fsck.c
··· 1421 1421 1422 1422 if (fsck_err_on(!i, 1423 1423 trans, key_in_missing_inode, 1424 - "key in missing inode:\n %s", 1424 + "key in missing inode:\n%s", 1425 1425 (printbuf_reset(&buf), 1426 1426 bch2_bkey_val_to_text(&buf, c, k), buf.buf))) 1427 1427 goto delete; 1428 1428 1429 1429 if (fsck_err_on(i && !btree_matches_i_mode(iter->btree_id, i->inode.bi_mode), 1430 1430 trans, key_in_wrong_inode_type, 1431 - "key for wrong inode mode %o:\n %s", 1431 + "key for wrong inode mode %o:\n%s", 1432 1432 i->inode.bi_mode, 1433 1433 (printbuf_reset(&buf), 1434 1434 bch2_bkey_val_to_text(&buf, c, k), buf.buf))) ··· 1571 1571 if (ret) 1572 1572 goto err; 1573 1573 1574 - prt_str(&buf, "\n "); 1574 + prt_newline(&buf); 1575 1575 bch2_bkey_val_to_text(&buf, c, k1); 1576 1576 1577 1577 if (!bpos_eq(pos1, k1.k->p)) { 1578 - prt_str(&buf, "\n wanted\n "); 1578 + prt_str(&buf, "\nwanted\n "); 1579 1579 bch2_bpos_to_text(&buf, pos1); 1580 - prt_str(&buf, "\n "); 1580 + prt_str(&buf, "\n"); 1581 1581 bch2_bkey_to_text(&buf, &pos2); 1582 1582 1583 1583 bch_err(c, "%s: error finding first overlapping extent when repairing, got%s", ··· 1600 1600 break; 1601 1601 } 1602 1602 1603 - prt_str(&buf, "\n "); 1603 + prt_newline(&buf); 1604 1604 bch2_bkey_val_to_text(&buf, c, k2); 1605 1605 1606 1606 if (bpos_gt(k2.k->p, pos2.p) || ··· 1611 1611 goto err; 1612 1612 } 1613 1613 1614 - prt_printf(&buf, "\n overwriting %s extent", 1614 + prt_printf(&buf, "\noverwriting %s extent", 1615 1615 pos1.snapshot >= pos2.p.snapshot ? "first" : "second"); 1616 1616 1617 1617 if (fsck_err(trans, extent_overlapping, ··· 1631 1631 k1, k2) ?: 1632 1632 bch2_trans_commit(trans, &res, NULL, BCH_TRANS_COMMIT_no_enospc); 1633 1633 bch2_disk_reservation_put(c, &res); 1634 + 1635 + bch_info(c, "repair ret %s", bch2_err_str(ret)); 1634 1636 1635 1637 if (ret) 1636 1638 goto err; ··· 1786 1784 if (fsck_err_on(k.k->p.offset > round_up(i->inode.bi_size, block_bytes(c)) >> 9 && 1787 1785 !bkey_extent_is_reservation(k), 1788 1786 trans, extent_past_end_of_inode, 1789 - "extent type past end of inode %llu:%u, i_size %llu\n %s", 1787 + "extent type past end of inode %llu:%u, i_size %llu\n%s", 1790 1788 i->inode.bi_inum, i->snapshot, i->inode.bi_size, 1791 1789 (bch2_bkey_val_to_text(&buf, c, k), buf.buf))) { 1792 1790 struct btree_iter iter2; ··· 3023 3021 if (arg.opts) { 3024 3022 char *optstr = strndup_user((char __user *)(unsigned long) arg.opts, 1 << 16); 3025 3023 ret = PTR_ERR_OR_ZERO(optstr) ?: 3026 - bch2_parse_mount_opts(NULL, &thr->opts, NULL, optstr); 3024 + bch2_parse_mount_opts(NULL, &thr->opts, NULL, optstr, false); 3027 3025 if (!IS_ERR(optstr)) 3028 3026 kfree(optstr); 3029 3027 ··· 3131 3129 char *optstr = strndup_user((char __user *)(unsigned long) arg.opts, 1 << 16); 3132 3130 3133 3131 ret = PTR_ERR_OR_ZERO(optstr) ?: 3134 - bch2_parse_mount_opts(c, &thr->opts, NULL, optstr); 3132 + bch2_parse_mount_opts(c, &thr->opts, NULL, optstr, false); 3135 3133 if (!IS_ERR(optstr)) 3136 3134 kfree(optstr); 3137 3135
+3 -1
fs/bcachefs/io_read.c
··· 259 259 &orig->opts, 260 260 update_opts, 261 261 btree_id, k); 262 + op->write.type = BCH_DATA_UPDATE_promote; 262 263 /* 263 264 * possible errors: -BCH_ERR_nocow_lock_blocked, 264 265 * -BCH_ERR_ENOSPC_disk_reservation: ··· 1323 1322 ret = __bch2_read_extent(trans, rbio, bvec_iter, iter.pos, 1324 1323 data_btree, k, 1325 1324 offset_into_extent, failed, flags, -1); 1325 + swap(bvec_iter.bi_size, bytes); 1326 + 1326 1327 if (ret) 1327 1328 goto err; 1328 1329 1329 1330 if (flags & BCH_READ_last_fragment) 1330 1331 break; 1331 1332 1332 - swap(bvec_iter.bi_size, bytes); 1333 1333 bio_advance_iter(&rbio->bio, &bvec_iter, bytes); 1334 1334 err: 1335 1335 if (ret == -BCH_ERR_data_read_retry_csum_err_maybe_userspace)
+4 -2
fs/bcachefs/io_read.h
··· 137 137 enum btree_id data_btree, struct bkey_s_c k, 138 138 unsigned offset_into_extent, unsigned flags) 139 139 { 140 - __bch2_read_extent(trans, rbio, rbio->bio.bi_iter, read_pos, 141 - data_btree, k, offset_into_extent, NULL, flags, -1); 140 + int ret = __bch2_read_extent(trans, rbio, rbio->bio.bi_iter, read_pos, 141 + data_btree, k, offset_into_extent, NULL, flags, -1); 142 + /* __bch2_read_extent only returns errors if BCH_READ_in_retry is set */ 143 + WARN(ret, "unhandled error from __bch2_read_extent()"); 142 144 } 143 145 144 146 int __bch2_read(struct btree_trans *, struct bch_read_bio *, struct bvec_iter,
+25 -19
fs/bcachefs/io_write.c
··· 434 434 printbuf_exit(&buf); 435 435 } 436 436 437 - static void bch2_write_csum_err_msg(struct bch_write_op *op) 438 - { 439 - bch2_write_op_error(op, op->pos.offset, 440 - "error verifying existing checksum while rewriting existing data (memory corruption?)"); 441 - } 442 - 443 437 void bch2_submit_wbio_replicas(struct bch_write_bio *wbio, struct bch_fs *c, 444 438 enum bch_data_type type, 445 439 const struct bkey_i *k, ··· 833 839 { 834 840 struct bch_fs *c = op->c; 835 841 struct bio *bio = &op->wbio.bio; 836 - struct nonce nonce = extent_nonce(op->version, op->crc); 842 + struct bch_csum csum; 837 843 int ret = 0; 838 844 839 845 BUG_ON(bio_sectors(bio) != op->crc.compressed_size); ··· 860 866 */ 861 867 if (crc_is_compressed(op->crc)) { 862 868 /* Last point we can still verify checksum: */ 863 - struct bch_csum csum = bch2_checksum_bio(c, op->crc.csum_type, nonce, bio); 869 + struct nonce nonce = extent_nonce(op->version, op->crc); 870 + csum = bch2_checksum_bio(c, op->crc.csum_type, nonce, bio); 864 871 if (bch2_crc_cmp(op->crc.csum, csum) && !c->opts.no_data_io) 865 872 goto csum_err; 866 873 ··· 900 905 */ 901 906 if (bch2_csum_type_is_encryption(op->crc.csum_type) && 902 907 (op->compression_opt || op->crc.csum_type != op->csum_type)) { 903 - struct bch_csum csum = bch2_checksum_bio(c, op->crc.csum_type, nonce, bio); 908 + struct nonce nonce = extent_nonce(op->version, op->crc); 909 + csum = bch2_checksum_bio(c, op->crc.csum_type, nonce, bio); 904 910 if (bch2_crc_cmp(op->crc.csum, csum) && !c->opts.no_data_io) 905 911 goto csum_err; 906 912 ··· 915 919 916 920 return 0; 917 921 csum_err: 918 - bch2_write_csum_err_msg(op); 922 + bch2_write_op_error(op, op->pos.offset, 923 + "error verifying existing checksum while moving existing data (memory corruption?)\n" 924 + " expected %0llx:%0llx got %0llx:%0llx type %s", 925 + op->crc.csum.hi, 926 + op->crc.csum.lo, 927 + csum.hi, 928 + csum.lo, 929 + op->crc.csum_type < BCH_CSUM_NR 930 + ? __bch2_csum_types[op->crc.csum_type] 931 + : "(unknown)"); 919 932 return -BCH_ERR_data_write_csum; 920 933 } 921 934 ··· 939 934 bool bounce = false; 940 935 bool page_alloc_failed = false; 941 936 int ret, more = 0; 937 + 938 + if (op->incompressible) 939 + op->compression_opt = 0; 942 940 943 941 BUG_ON(!bio_sectors(src)); 944 942 ··· 1054 1046 * data can't be modified (by userspace) while it's in 1055 1047 * flight. 1056 1048 */ 1057 - if (bch2_rechecksum_bio(c, src, version, op->crc, 1049 + ret = bch2_rechecksum_bio(c, src, version, op->crc, 1058 1050 &crc, &op->crc, 1059 1051 src_len >> 9, 1060 1052 bio_sectors(src) - (src_len >> 9), 1061 - op->csum_type)) 1062 - goto csum_err; 1053 + op->csum_type); 1054 + if (ret) 1055 + goto err; 1063 1056 /* 1064 1057 * rchecksum_bio sets compression_type on crc from op->crc, 1065 1058 * this isn't always correct as sometimes we're changing ··· 1070 1061 crc.nonce = nonce; 1071 1062 } else { 1072 1063 if ((op->flags & BCH_WRITE_data_encoded) && 1073 - bch2_rechecksum_bio(c, src, version, op->crc, 1064 + (ret = bch2_rechecksum_bio(c, src, version, op->crc, 1074 1065 NULL, &op->crc, 1075 1066 src_len >> 9, 1076 1067 bio_sectors(src) - (src_len >> 9), 1077 - op->crc.csum_type)) 1078 - goto csum_err; 1068 + op->crc.csum_type))) 1069 + goto err; 1079 1070 1080 1071 crc.compressed_size = dst_len >> 9; 1081 1072 crc.uncompressed_size = src_len >> 9; ··· 1134 1125 do_write: 1135 1126 *_dst = dst; 1136 1127 return more; 1137 - csum_err: 1138 - bch2_write_csum_err_msg(op); 1139 - ret = -BCH_ERR_data_write_csum; 1140 1128 err: 1141 1129 if (to_wbio(dst)->bounce) 1142 1130 bch2_bio_free_pages_pool(c, dst);
+10 -9
fs/bcachefs/journal.c
··· 62 62 prt_newline(out); 63 63 } 64 64 65 - prt_printf(out, "expires:\t"); 66 - prt_printf(out, "%li jiffies\n", buf->expires - jiffies); 65 + prt_printf(out, "expires:\t%li jiffies\n", buf->expires - jiffies); 67 66 68 67 prt_printf(out, "flags:\t"); 69 68 if (buf->noflush) ··· 141 142 bool stuck = false; 142 143 struct printbuf buf = PRINTBUF; 143 144 145 + buf.atomic++; 146 + 144 147 if (!(error == -BCH_ERR_journal_full || 145 148 error == -BCH_ERR_journal_pin_full) || 146 149 nr_unwritten_journal_entries(j) || ··· 168 167 return stuck; 169 168 } 170 169 j->err_seq = journal_cur_seq(j); 171 - spin_unlock(&j->lock); 172 170 173 - bch_err(c, "Journal stuck! Hava a pre-reservation but journal full (error %s)", 174 - bch2_err_str(error)); 175 - bch2_journal_debug_to_text(&buf, j); 176 - bch_err(c, "%s", buf.buf); 171 + __bch2_journal_debug_to_text(&buf, j); 172 + spin_unlock(&j->lock); 173 + prt_printf(&buf, bch2_fmt(c, "Journal stuck! Hava a pre-reservation but journal full (error %s)"), 174 + bch2_err_str(error)); 175 + bch2_print_string_as_lines(KERN_ERR, buf.buf); 177 176 178 177 printbuf_reset(&buf); 179 178 bch2_journal_pins_to_text(&buf, j); ··· 729 728 730 729 struct printbuf buf = PRINTBUF; 731 730 bch2_journal_debug_to_text(&buf, j); 732 - bch_err(c, "Journal stuck? Waited for 10 seconds...\n%s", 733 - buf.buf); 731 + bch2_print_string_as_lines(KERN_ERR, buf.buf); 732 + prt_printf(&buf, bch2_fmt(c, "Journal stuck? Waited for 10 seconds, err %s"), bch2_err_str(ret)); 734 733 printbuf_exit(&buf); 735 734 736 735 closure_wait_event(&j->async_wait,
+28 -10
fs/bcachefs/journal_io.c
··· 214 214 215 215 fsck_err_on(same_device, 216 216 c, journal_entry_dup_same_device, 217 - "duplicate journal entry on same device\n %s", 217 + "duplicate journal entry on same device\n%s", 218 218 buf.buf); 219 219 220 220 fsck_err_on(not_identical, 221 221 c, journal_entry_replicas_data_mismatch, 222 - "found duplicate but non identical journal entries\n %s", 222 + "found duplicate but non identical journal entries\n%s", 223 223 buf.buf); 224 224 225 225 if (entry_ptr.csum_good && !identical) ··· 308 308 break; \ 309 309 case WRITE: \ 310 310 bch2_sb_error_count(c, BCH_FSCK_ERR_##_err); \ 311 - bch_err(c, "corrupt metadata before write: %s\n", _buf.buf);\ 312 - if (bch2_fs_inconsistent(c)) { \ 311 + if (bch2_fs_inconsistent(c, \ 312 + "corrupt metadata before write: %s\n", _buf.buf)) {\ 313 313 ret = -BCH_ERR_fsck_errors_not_fixed; \ 314 314 goto fsck_err; \ 315 315 } \ ··· 760 760 761 761 static void journal_entry_overwrite_to_text(struct printbuf *out, struct bch_fs *c, 762 762 struct jset_entry *entry) 763 + { 764 + journal_entry_btree_keys_to_text(out, c, entry); 765 + } 766 + 767 + static int journal_entry_log_bkey_validate(struct bch_fs *c, 768 + struct jset *jset, 769 + struct jset_entry *entry, 770 + unsigned version, int big_endian, 771 + struct bkey_validate_context from) 772 + { 773 + from.flags = 0; 774 + return journal_entry_btree_keys_validate(c, jset, entry, 775 + version, big_endian, from); 776 + } 777 + 778 + static void journal_entry_log_bkey_to_text(struct printbuf *out, struct bch_fs *c, 779 + struct jset_entry *entry) 763 780 { 764 781 journal_entry_btree_keys_to_text(out, c, entry); 765 782 } ··· 1388 1371 missing_end = seq - 1; 1389 1372 fsck_err(c, journal_entries_missing, 1390 1373 "journal entries %llu-%llu missing! (replaying %llu-%llu)\n" 1391 - " prev at %s\n" 1392 - " next at %s, continue?", 1374 + "prev at %s\n" 1375 + "next at %s, continue?", 1393 1376 missing_start, missing_end, 1394 1377 *last_seq, *blacklist_seq - 1, 1395 1378 buf1.buf, buf2.buf); ··· 1443 1426 !bch2_replicas_marked(c, &replicas.e) && 1444 1427 (le64_to_cpu(i->j.seq) == *last_seq || 1445 1428 fsck_err(c, journal_entry_replicas_not_marked, 1446 - "superblock not marked as containing replicas for journal entry %llu\n %s", 1429 + "superblock not marked as containing replicas for journal entry %llu\n%s", 1447 1430 le64_to_cpu(i->j.seq), buf.buf))) { 1448 1431 ret = bch2_mark_replicas(c, &replicas.e); 1449 1432 if (ret) ··· 1640 1623 : j->noflush_write_time, j->write_start_time); 1641 1624 1642 1625 if (!w->devs_written.nr) { 1643 - bch_err(c, "unable to write journal to sufficient devices"); 1626 + if (!bch2_journal_error(j)) 1627 + bch_err(c, "unable to write journal to sufficient devices"); 1644 1628 err = -BCH_ERR_journal_write_err; 1645 1629 } else { 1646 1630 bch2_devlist_to_replicas(&replicas.e, BCH_DATA_journal, ··· 2099 2081 struct printbuf buf = PRINTBUF; 2100 2082 buf.atomic++; 2101 2083 2084 + __bch2_journal_debug_to_text(&buf, j); 2085 + spin_unlock(&j->lock); 2102 2086 prt_printf(&buf, bch2_fmt(c, "Unable to allocate journal write at seq %llu for %zu sectors: %s"), 2103 2087 le64_to_cpu(w->data->seq), 2104 2088 vstruct_sectors(w->data, c->block_bits), 2105 2089 bch2_err_str(ret)); 2106 - __bch2_journal_debug_to_text(&buf, j); 2107 - spin_unlock(&j->lock); 2108 2090 bch2_print_string_as_lines(KERN_ERR, buf.buf); 2109 2091 printbuf_exit(&buf); 2110 2092 }
+3 -4
fs/bcachefs/lru.c
··· 101 101 goto err; 102 102 103 103 if (fsck_err(trans, alloc_key_to_missing_lru_entry, 104 - "missing %s lru entry\n" 105 - " %s", 104 + "missing %s lru entry\n%s", 106 105 bch2_lru_types[lru_type(lru_k)], 107 106 (bch2_bkey_val_to_text(&buf, c, referring_k), buf.buf))) { 108 107 ret = bch2_lru_set(trans, lru_id, dev_bucket, time); ··· 189 190 190 191 if (fsck_err(trans, lru_entry_bad, 191 192 "incorrect lru entry: lru %s time %llu\n" 192 - " %s\n" 193 - " for %s", 193 + "%s\n" 194 + "for %s", 194 195 bch2_lru_types[type], 195 196 lru_pos_time(lru_k.k->p), 196 197 (bch2_bkey_val_to_text(&buf1, c, lru_k), buf1.buf),
+33 -4
fs/bcachefs/move.c
··· 528 528 return 0; 529 529 } 530 530 531 + /* 532 + * Move requires non extents iterators, and there's also no need for it to 533 + * signal indirect_extent_missing_error: 534 + */ 535 + static struct bkey_s_c bch2_lookup_indirect_extent_for_move(struct btree_trans *trans, 536 + struct btree_iter *iter, 537 + struct bkey_s_c_reflink_p p) 538 + { 539 + if (unlikely(REFLINK_P_ERROR(p.v))) 540 + return bkey_s_c_null; 541 + 542 + struct bpos reflink_pos = POS(0, REFLINK_P_IDX(p.v)); 543 + 544 + bch2_trans_iter_init(trans, iter, 545 + BTREE_ID_reflink, reflink_pos, 546 + BTREE_ITER_not_extents); 547 + 548 + struct bkey_s_c k = bch2_btree_iter_peek(iter); 549 + if (!k.k || bkey_err(k)) { 550 + bch2_trans_iter_exit(trans, iter); 551 + return k; 552 + } 553 + 554 + if (bkey_lt(reflink_pos, bkey_start_pos(k.k))) { 555 + bch2_trans_iter_exit(trans, iter); 556 + return bkey_s_c_null; 557 + } 558 + 559 + return k; 560 + } 561 + 531 562 static int bch2_move_data_btree(struct moving_context *ctxt, 532 563 struct bpos start, 533 564 struct bpos end, ··· 623 592 k.k->type == KEY_TYPE_reflink_p && 624 593 REFLINK_P_MAY_UPDATE_OPTIONS(bkey_s_c_to_reflink_p(k).v)) { 625 594 struct bkey_s_c_reflink_p p = bkey_s_c_to_reflink_p(k); 626 - s64 offset_into_extent = 0; 627 595 628 596 bch2_trans_iter_exit(trans, &reflink_iter); 629 - k = bch2_lookup_indirect_extent(trans, &reflink_iter, &offset_into_extent, p, true, 0); 597 + k = bch2_lookup_indirect_extent_for_move(trans, &reflink_iter, p); 630 598 ret = bkey_err(k); 631 599 if (bch2_err_matches(ret, BCH_ERR_transaction_restart)) 632 600 continue; 633 601 if (ret) 634 602 break; 635 603 636 - if (bkey_deleted(k.k)) 604 + if (!k.k) 637 605 goto next_nondata; 638 606 639 607 /* ··· 641 611 * pointer - need to fixup iter->k 642 612 */ 643 613 extent_iter = &reflink_iter; 644 - offset_into_extent = 0; 645 614 } 646 615 647 616 if (!bkey_extent_is_direct_data(k.k))
+2 -2
fs/bcachefs/namei.c
··· 700 700 701 701 if (bch2_inode_should_have_single_bp(target) && 702 702 !fsck_err(trans, inode_wrong_backpointer, 703 - "dirent points to inode that does not point back:\n %s", 703 + "dirent points to inode that does not point back:\n%s", 704 704 (bch2_bkey_val_to_text(&buf, c, d.s_c), 705 - prt_printf(&buf, "\n "), 705 + prt_newline(&buf), 706 706 bch2_inode_unpacked_to_text(&buf, target), 707 707 buf.buf))) 708 708 goto err;
+24 -29
fs/bcachefs/opts.c
··· 44 44 NULL 45 45 }; 46 46 47 - static const char * const __bch2_csum_types[] = { 47 + const char * const __bch2_csum_types[] = { 48 48 BCH_CSUM_TYPES() 49 49 NULL 50 50 }; ··· 482 482 483 483 int bch2_opt_check_may_set(struct bch_fs *c, struct bch_dev *ca, int id, u64 v) 484 484 { 485 - lockdep_assert_held(&c->state_lock); 486 - 487 485 int ret = 0; 488 486 489 487 switch (id) { 490 488 case Opt_state: 491 489 if (ca) 492 - return __bch2_dev_set_state(c, ca, v, BCH_FORCE_IF_DEGRADED); 490 + return bch2_dev_set_state(c, ca, v, BCH_FORCE_IF_DEGRADED); 493 491 break; 494 492 495 493 case Opt_compression: ··· 549 551 goto bad_opt; 550 552 551 553 ret = bch2_opt_parse(c, &bch2_opt_table[id], val, &v, &err); 552 - if (ret == -BCH_ERR_option_needs_open_fs && parse_later) { 553 - prt_printf(parse_later, "%s=%s,", name, val); 554 - if (parse_later->allocation_failure) { 555 - ret = -ENOMEM; 556 - goto out; 554 + if (ret == -BCH_ERR_option_needs_open_fs) { 555 + ret = 0; 556 + 557 + if (parse_later) { 558 + prt_printf(parse_later, "%s=%s,", name, val); 559 + if (parse_later->allocation_failure) 560 + ret = -ENOMEM; 557 561 } 558 562 559 - ret = 0; 560 563 goto out; 561 564 } 562 565 ··· 568 569 bch2_opt_set_by_id(opts, id, v); 569 570 570 571 ret = 0; 571 - goto out; 572 - 573 - bad_opt: 574 - pr_err("Bad mount option %s", name); 575 - ret = -BCH_ERR_option_name; 576 - goto out; 577 - 578 - bad_val: 579 - pr_err("Invalid mount option %s", err.buf); 580 - ret = -BCH_ERR_option_value; 581 - 582 572 out: 583 573 printbuf_exit(&err); 584 574 return ret; 575 + bad_opt: 576 + ret = -BCH_ERR_option_name; 577 + goto out; 578 + bad_val: 579 + ret = -BCH_ERR_option_value; 580 + goto out; 585 581 } 586 582 587 583 int bch2_parse_mount_opts(struct bch_fs *c, struct bch_opts *opts, 588 - struct printbuf *parse_later, char *options) 584 + struct printbuf *parse_later, char *options, 585 + bool ignore_unknown) 589 586 { 590 587 char *copied_opts, *copied_opts_start; 591 588 char *opt, *name, *val; 592 - int ret; 589 + int ret = 0; 593 590 594 591 if (!options) 595 592 return 0; ··· 610 615 val = opt; 611 616 612 617 ret = bch2_parse_one_mount_opt(c, opts, parse_later, name, val); 613 - if (ret < 0) 614 - goto out; 618 + if (ret == -BCH_ERR_option_name && ignore_unknown) 619 + ret = 0; 620 + if (ret) { 621 + pr_err("Error parsing option %s: %s", name, bch2_err_str(ret)); 622 + break; 623 + } 615 624 } 616 625 617 - ret = 0; 618 - goto out; 619 - 620 - out: 621 626 kfree(copied_opts_start); 622 627 return ret; 623 628 }
+2 -1
fs/bcachefs/opts.h
··· 16 16 extern const char * const bch2_sb_features[]; 17 17 extern const char * const bch2_sb_compat[]; 18 18 extern const char * const __bch2_btree_ids[]; 19 + extern const char * const __bch2_csum_types[]; 19 20 extern const char * const __bch2_csum_opts[]; 20 21 extern const char * const __bch2_compression_types[]; 21 22 extern const char * const bch2_compression_opts[]; ··· 636 635 int bch2_parse_one_mount_opt(struct bch_fs *, struct bch_opts *, 637 636 struct printbuf *, const char *, const char *); 638 637 int bch2_parse_mount_opts(struct bch_fs *, struct bch_opts *, struct printbuf *, 639 - char *); 638 + char *, bool); 640 639 641 640 /* inode opts: */ 642 641
+19
fs/bcachefs/printbuf.c
··· 277 277 } 278 278 279 279 /** 280 + * bch2_printbuf_indent_add_nextline() - add to the current indent level for 281 + * subsequent lines 282 + * 283 + * @buf: printbuf to control 284 + * @spaces: number of spaces to add to the current indent level 285 + * 286 + * Subsequent lines - not the current line - will be indented by @spaces more 287 + * spaces. 288 + */ 289 + void bch2_printbuf_indent_add_nextline(struct printbuf *buf, unsigned spaces) 290 + { 291 + if (WARN_ON_ONCE(buf->indent + spaces < buf->indent)) 292 + spaces = 0; 293 + 294 + buf->indent += spaces; 295 + buf->has_indent_or_tabstops = true; 296 + } 297 + 298 + /** 280 299 * bch2_printbuf_indent_sub() - subtract from the current indent level 281 300 * 282 301 * @buf: printbuf to control
+1
fs/bcachefs/printbuf.h
··· 112 112 int bch2_printbuf_tabstop_push(struct printbuf *, unsigned); 113 113 114 114 void bch2_printbuf_indent_add(struct printbuf *, unsigned); 115 + void bch2_printbuf_indent_add_nextline(struct printbuf *, unsigned); 115 116 void bch2_printbuf_indent_sub(struct printbuf *, unsigned); 116 117 117 118 void bch2_prt_newline(struct printbuf *);
+2 -4
fs/bcachefs/progress.c
··· 16 16 if (!(btree_id_mask & BIT_ULL(i))) 17 17 continue; 18 18 19 - struct disk_accounting_pos acc = { 20 - .type = BCH_DISK_ACCOUNTING_btree, 21 - .btree.id = i, 22 - }; 19 + struct disk_accounting_pos acc; 20 + disk_accounting_key_init(acc, btree, .id = i); 23 21 24 22 u64 v; 25 23 bch2_accounting_mem_read(c, disk_accounting_pos_to_bpos(&acc), &v, 1);
+3 -2
fs/bcachefs/rebalance.c
··· 600 600 struct bch_fs_rebalance *r = &c->rebalance; 601 601 602 602 /* print pending work */ 603 - struct disk_accounting_pos acc = { .type = BCH_DISK_ACCOUNTING_rebalance_work, }; 603 + struct disk_accounting_pos acc; 604 + disk_accounting_key_init(acc, rebalance_work); 604 605 u64 v; 605 606 bch2_accounting_mem_read(c, disk_accounting_pos_to_bpos(&acc), &v, 1); 606 607 607 608 prt_printf(out, "pending work:\t"); 608 - prt_human_readable_u64(out, v); 609 + prt_human_readable_u64(out, v << 9); 609 610 prt_printf(out, "\n\n"); 610 611 611 612 prt_str(out, bch2_rebalance_state_strs[r->state]);
+3 -9
fs/bcachefs/recovery_passes.c
··· 234 234 235 235 int bch2_run_online_recovery_passes(struct bch_fs *c) 236 236 { 237 - int ret = 0; 238 - 239 - down_read(&c->state_lock); 240 - 241 237 for (unsigned i = 0; i < ARRAY_SIZE(recovery_pass_fns); i++) { 242 238 struct recovery_pass_fn *p = recovery_pass_fns + i; 243 239 244 240 if (!(p->when & PASS_ONLINE)) 245 241 continue; 246 242 247 - ret = bch2_run_recovery_pass(c, i); 243 + int ret = bch2_run_recovery_pass(c, i); 248 244 if (bch2_err_matches(ret, BCH_ERR_restart_recovery)) { 249 245 i = c->curr_recovery_pass; 250 246 continue; 251 247 } 252 248 if (ret) 253 - break; 249 + return ret; 254 250 } 255 251 256 - up_read(&c->state_lock); 257 - 258 - return ret; 252 + return 0; 259 253 } 260 254 261 255 int bch2_run_recovery_passes(struct bch_fs *c)
+6 -6
fs/bcachefs/reflink.c
··· 193 193 if (ret) 194 194 goto err; 195 195 196 - prt_printf(&buf, "-%llu\n ", (missing_pos.offset + (missing_end - missing_start)) << 9); 196 + prt_printf(&buf, "-%llu\n", (missing_pos.offset + (missing_end - missing_start)) << 9); 197 197 bch2_bkey_val_to_text(&buf, c, p.s_c); 198 198 199 - prt_printf(&buf, "\n missing reflink btree range %llu-%llu", 199 + prt_printf(&buf, "\nmissing reflink btree range %llu-%llu", 200 200 missing_start, missing_end); 201 201 202 202 if (fsck_err(trans, reflink_p_to_missing_reflink_v, "%s", buf.buf)) { ··· 323 323 __le64 *refcount = bkey_refcount(bkey_i_to_s(new)); 324 324 if (!*refcount && (flags & BTREE_TRIGGER_overwrite)) { 325 325 bch2_bkey_val_to_text(&buf, c, p.s_c); 326 - prt_printf(&buf, "\n "); 326 + prt_newline(&buf); 327 327 bch2_bkey_val_to_text(&buf, c, k); 328 328 log_fsck_err(trans, reflink_refcount_underflow, 329 - "indirect extent refcount underflow while marking\n %s", 329 + "indirect extent refcount underflow while marking\n%s", 330 330 buf.buf); 331 331 goto next; 332 332 } ··· 795 795 if (fsck_err_on(r->refcount != le64_to_cpu(*refcount), 796 796 trans, reflink_v_refcount_wrong, 797 797 "reflink key has wrong refcount:\n" 798 - " %s\n" 799 - " should be %u", 798 + "%s\n" 799 + "should be %u", 800 800 (bch2_bkey_val_to_text(&buf, c, k), buf.buf), 801 801 r->refcount)) { 802 802 struct bkey_i *new = bch2_bkey_make_mut_noupdate(trans, k);
+3 -3
fs/bcachefs/sb-errors_format.h
··· 5 5 enum bch_fsck_flags { 6 6 FSCK_CAN_FIX = 1 << 0, 7 7 FSCK_CAN_IGNORE = 1 << 1, 8 - FSCK_NO_RATELIMIT = 1 << 2, 9 - FSCK_AUTOFIX = 1 << 3, 8 + FSCK_AUTOFIX = 1 << 2, 10 9 }; 11 10 12 11 #define BCH_SB_ERRS() \ ··· 310 311 x(accounting_key_replicas_nr_required_bad, 279, FSCK_AUTOFIX) \ 311 312 x(accounting_key_replicas_devs_unsorted, 280, FSCK_AUTOFIX) \ 312 313 x(accounting_key_version_0, 282, FSCK_AUTOFIX) \ 314 + x(accounting_key_nr_counters_wrong, 307, FSCK_AUTOFIX) \ 313 315 x(logged_op_but_clean, 283, FSCK_AUTOFIX) \ 314 316 x(compression_opt_not_marked_in_sb, 295, FSCK_AUTOFIX) \ 315 317 x(compression_type_not_marked_in_sb, 296, FSCK_AUTOFIX) \ 316 318 x(directory_size_mismatch, 303, FSCK_AUTOFIX) \ 317 319 x(dirent_cf_name_too_big, 304, 0) \ 318 320 x(dirent_stray_data_after_cf_name, 305, 0) \ 319 - x(MAX, 307, 0) 321 + x(MAX, 308, 0) 320 322 321 323 enum bch_sb_error_id { 322 324 #define x(t, n, ...) BCH_FSCK_ERR_##t = n,
+8 -8
fs/bcachefs/snapshot.c
··· 485 485 root_id != bch2_snapshot_root(c, root_id) || 486 486 st.k->p.offset != le32_to_cpu(s.tree), 487 487 trans, snapshot_tree_to_missing_snapshot, 488 - "snapshot tree points to missing/incorrect snapshot:\n %s", 488 + "snapshot tree points to missing/incorrect snapshot:\n%s", 489 489 (bch2_bkey_val_to_text(&buf, c, st.s_c), 490 490 prt_newline(&buf), 491 491 ret ··· 505 505 506 506 if (fsck_err_on(ret, 507 507 trans, snapshot_tree_to_missing_subvol, 508 - "snapshot tree points to missing subvolume:\n %s", 508 + "snapshot tree points to missing subvolume:\n%s", 509 509 (printbuf_reset(&buf), 510 510 bch2_bkey_val_to_text(&buf, c, st.s_c), buf.buf)) || 511 511 fsck_err_on(!bch2_snapshot_is_ancestor(c, 512 512 le32_to_cpu(subvol.snapshot), 513 513 root_id), 514 514 trans, snapshot_tree_to_wrong_subvol, 515 - "snapshot tree points to subvolume that does not point to snapshot in this tree:\n %s", 515 + "snapshot tree points to subvolume that does not point to snapshot in this tree:\n%s", 516 516 (printbuf_reset(&buf), 517 517 bch2_bkey_val_to_text(&buf, c, st.s_c), buf.buf)) || 518 518 fsck_err_on(BCH_SUBVOLUME_SNAP(&subvol), 519 519 trans, snapshot_tree_to_snapshot_subvol, 520 - "snapshot tree points to snapshot subvolume:\n %s", 520 + "snapshot tree points to snapshot subvolume:\n%s", 521 521 (printbuf_reset(&buf), 522 522 bch2_bkey_val_to_text(&buf, c, st.s_c), buf.buf))) { 523 523 struct bkey_i_snapshot_tree *u; ··· 756 756 } else { 757 757 if (fsck_err_on(s.subvol, 758 758 trans, snapshot_should_not_have_subvol, 759 - "snapshot should not point to subvol:\n %s", 759 + "snapshot should not point to subvol:\n%s", 760 760 (bch2_bkey_val_to_text(&buf, c, k), buf.buf))) { 761 761 u = bch2_bkey_make_mut_typed(trans, iter, &k, 0, snapshot); 762 762 ret = PTR_ERR_OR_ZERO(u); ··· 774 774 775 775 if (fsck_err_on(!ret, 776 776 trans, snapshot_to_bad_snapshot_tree, 777 - "snapshot points to missing/incorrect tree:\n %s", 777 + "snapshot points to missing/incorrect tree:\n%s", 778 778 (bch2_bkey_val_to_text(&buf, c, k), buf.buf))) { 779 779 ret = snapshot_tree_ptr_repair(trans, iter, k, &s); 780 780 if (ret) ··· 786 786 787 787 if (fsck_err_on(le32_to_cpu(s.depth) != real_depth, 788 788 trans, snapshot_bad_depth, 789 - "snapshot with incorrect depth field, should be %u:\n %s", 789 + "snapshot with incorrect depth field, should be %u:\n%s", 790 790 real_depth, (bch2_bkey_val_to_text(&buf, c, k), buf.buf))) { 791 791 u = bch2_bkey_make_mut_typed(trans, iter, &k, 0, snapshot); 792 792 ret = PTR_ERR_OR_ZERO(u); ··· 803 803 804 804 if (fsck_err_on(!ret, 805 805 trans, snapshot_bad_skiplist, 806 - "snapshot with bad skiplist field:\n %s", 806 + "snapshot with bad skiplist field:\n%s", 807 807 (bch2_bkey_val_to_text(&buf, c, k), buf.buf))) { 808 808 u = bch2_bkey_make_mut_typed(trans, iter, &k, 0, snapshot); 809 809 ret = PTR_ERR_OR_ZERO(u);
+1 -1
fs/bcachefs/str_hash.c
··· 232 232 goto out; 233 233 234 234 if (fsck_err(trans, hash_table_key_wrong_offset, 235 - "hash table key at wrong offset: btree %s inode %llu offset %llu, hashed to %llu\n %s", 235 + "hash table key at wrong offset: btree %s inode %llu offset %llu, hashed to %llu\n%s", 236 236 bch2_btree_id_str(desc->btree_id), hash_k.k->p.inode, hash_k.k->p.offset, hash, 237 237 (printbuf_reset(&buf), 238 238 bch2_bkey_val_to_text(&buf, c, hash_k), buf.buf))) {
+1
fs/bcachefs/subvolume.c
··· 561 561 } 562 562 563 563 SET_BCH_SUBVOLUME_UNLINKED(&n->v, true); 564 + n->v.fs_path_parent = 0; 564 565 bch2_trans_iter_exit(trans, &iter); 565 566 return ret; 566 567 }
+19 -19
fs/bcachefs/super.c
··· 533 533 534 534 int bch2_fs_read_write_early(struct bch_fs *c) 535 535 { 536 - lockdep_assert_held(&c->state_lock); 536 + down_write(&c->state_lock); 537 + int ret = __bch2_fs_read_write(c, true); 538 + up_write(&c->state_lock); 537 539 538 - return __bch2_fs_read_write(c, true); 540 + return ret; 539 541 } 540 542 541 543 /* Filesystem startup/shutdown: */ ··· 1021 1019 int bch2_fs_start(struct bch_fs *c) 1022 1020 { 1023 1021 time64_t now = ktime_get_real_seconds(); 1024 - int ret; 1022 + int ret = 0; 1025 1023 1026 1024 print_mount_opts(c); 1027 1025 1028 1026 down_write(&c->state_lock); 1027 + mutex_lock(&c->sb_lock); 1029 1028 1030 1029 BUG_ON(test_bit(BCH_FS_started, &c->flags)); 1031 1030 1032 - mutex_lock(&c->sb_lock); 1031 + if (!bch2_sb_field_get_minsize(&c->disk_sb, ext, 1032 + sizeof(struct bch_sb_field_ext) / sizeof(u64))) { 1033 + mutex_unlock(&c->sb_lock); 1034 + up_write(&c->state_lock); 1035 + ret = -BCH_ERR_ENOSPC_sb; 1036 + goto err; 1037 + } 1033 1038 1034 1039 ret = bch2_sb_members_v2_init(c); 1035 1040 if (ret) { 1036 1041 mutex_unlock(&c->sb_lock); 1042 + up_write(&c->state_lock); 1037 1043 goto err; 1038 1044 } 1039 1045 1040 1046 for_each_online_member(c, ca) 1041 1047 bch2_members_v2_get_mut(c->disk_sb.sb, ca->dev_idx)->last_mount = cpu_to_le64(now); 1042 1048 1043 - struct bch_sb_field_ext *ext = 1044 - bch2_sb_field_get_minsize(&c->disk_sb, ext, sizeof(*ext) / sizeof(u64)); 1045 1049 mutex_unlock(&c->sb_lock); 1046 - 1047 - if (!ext) { 1048 - bch_err(c, "insufficient space in superblock for sb_field_ext"); 1049 - ret = -BCH_ERR_ENOSPC_sb; 1050 - goto err; 1051 - } 1052 1050 1053 1051 for_each_rw_member(c, ca) 1054 1052 bch2_dev_allocator_add(c, ca); 1055 1053 bch2_recalc_capacity(c); 1054 + up_write(&c->state_lock); 1056 1055 1057 1056 c->recovery_task = current; 1058 1057 ret = BCH_SB_INITIALIZED(c->disk_sb.sb) ··· 1069 1066 goto err; 1070 1067 1071 1068 if (bch2_fs_init_fault("fs_start")) { 1072 - bch_err(c, "fs_start fault injected"); 1073 - ret = -EINVAL; 1069 + ret = -BCH_ERR_injected_fs_start; 1074 1070 goto err; 1075 1071 } 1076 1072 1077 1073 set_bit(BCH_FS_started, &c->flags); 1078 1074 wake_up(&c->ro_ref_wait); 1079 1075 1076 + down_write(&c->state_lock); 1080 1077 if (c->opts.read_only) { 1081 1078 bch2_fs_read_only(c); 1082 1079 } else { 1083 1080 ret = !test_bit(BCH_FS_rw, &c->flags) 1084 1081 ? bch2_fs_read_write(c) 1085 1082 : bch2_fs_read_write_late(c); 1086 - if (ret) 1087 - goto err; 1088 1083 } 1084 + up_write(&c->state_lock); 1089 1085 1090 - ret = 0; 1091 1086 err: 1092 1087 if (ret) 1093 1088 bch_err_msg(c, ret, "starting filesystem"); 1094 1089 else 1095 1090 bch_verbose(c, "done starting filesystem"); 1096 - up_write(&c->state_lock); 1097 1091 return ret; 1098 1092 } 1099 1093 ··· 2259 2259 2260 2260 __maybe_unused 2261 2261 static unsigned bch2_metadata_version = bcachefs_metadata_version_current; 2262 - module_param_named(version, bch2_metadata_version, uint, 0400); 2262 + module_param_named(version, bch2_metadata_version, uint, 0444); 2263 2263 2264 2264 module_exit(bcachefs_exit); 2265 2265 module_init(bcachefs_init);
+2 -7
fs/bcachefs/sysfs.c
··· 257 257 prt_printf(out, "type\tcompressed\runcompressed\raverage extent size\r\n"); 258 258 259 259 for (unsigned i = 1; i < BCH_COMPRESSION_TYPE_NR; i++) { 260 - struct disk_accounting_pos a = { 261 - .type = BCH_DISK_ACCOUNTING_compression, 262 - .compression.type = i, 263 - }; 260 + struct disk_accounting_pos a; 261 + disk_accounting_key_init(a, compression, .type = i); 264 262 struct bpos p = disk_accounting_pos_to_bpos(&a); 265 263 u64 v[3]; 266 264 bch2_accounting_mem_read(c, p, v, ARRAY_SIZE(v)); ··· 629 631 if (unlikely(!bch2_write_ref_tryget(c, BCH_WRITE_REF_sysfs))) 630 632 return -EROFS; 631 633 632 - down_write(&c->state_lock); 633 - 634 634 char *tmp = kstrdup(buf, GFP_KERNEL); 635 635 if (!tmp) { 636 636 ret = -ENOMEM; ··· 671 675 672 676 ret = size; 673 677 err: 674 - up_write(&c->state_lock); 675 678 bch2_write_ref_put(c, BCH_WRITE_REF_sysfs); 676 679 return ret; 677 680 }
+16 -4
fs/bcachefs/time_stats.c
··· 10 10 #include "eytzinger.h" 11 11 #include "time_stats.h" 12 12 13 + /* disable automatic switching to percpu mode */ 14 + #define TIME_STATS_NONPCPU ((unsigned long) 1) 15 + 13 16 static const struct time_unit time_units[] = { 14 17 { "ns", 1 }, 15 18 { "us", NSEC_PER_USEC }, ··· 126 123 { 127 124 unsigned long flags; 128 125 129 - if (!stats->buffer) { 126 + if ((unsigned long) stats->buffer <= TIME_STATS_NONPCPU) { 130 127 spin_lock_irqsave(&stats->lock, flags); 131 128 time_stats_update_one(stats, start, end); 132 129 133 - if (mean_and_variance_weighted_get_mean(stats->freq_stats_weighted, TIME_STATS_MV_WEIGHT) < 32 && 130 + if (!stats->buffer && 131 + mean_and_variance_weighted_get_mean(stats->freq_stats_weighted, TIME_STATS_MV_WEIGHT) < 32 && 134 132 stats->duration_stats.n > 1024) 135 133 stats->buffer = 136 134 alloc_percpu_gfp(struct time_stat_buffer, ··· 161 157 unsigned offset = offsetof(struct bch2_time_stats, min_duration); 162 158 memset((void *) stats + offset, 0, sizeof(*stats) - offset); 163 159 164 - if (stats->buffer) { 160 + if ((unsigned long) stats->buffer > TIME_STATS_NONPCPU) { 165 161 int cpu; 166 162 for_each_possible_cpu(cpu) 167 163 per_cpu_ptr(stats->buffer, cpu)->nr = 0; ··· 171 167 172 168 void bch2_time_stats_exit(struct bch2_time_stats *stats) 173 169 { 174 - free_percpu(stats->buffer); 170 + if ((unsigned long) stats->buffer > TIME_STATS_NONPCPU) 171 + free_percpu(stats->buffer); 172 + stats->buffer = NULL; 175 173 } 176 174 177 175 void bch2_time_stats_init(struct bch2_time_stats *stats) ··· 182 176 stats->min_duration = U64_MAX; 183 177 stats->min_freq = U64_MAX; 184 178 spin_lock_init(&stats->lock); 179 + } 180 + 181 + void bch2_time_stats_init_no_pcpu(struct bch2_time_stats *stats) 182 + { 183 + bch2_time_stats_init(stats); 184 + stats->buffer = (struct time_stat_buffer __percpu *) TIME_STATS_NONPCPU; 185 185 }
+1
fs/bcachefs/time_stats.h
··· 145 145 void bch2_time_stats_reset(struct bch2_time_stats *); 146 146 void bch2_time_stats_exit(struct bch2_time_stats *); 147 147 void bch2_time_stats_init(struct bch2_time_stats *); 148 + void bch2_time_stats_init_no_pcpu(struct bch2_time_stats *); 148 149 149 150 static inline void bch2_time_stats_quantiles_exit(struct bch2_time_stats_quantiles *statq) 150 151 {
+1 -1
fs/bcachefs/util.c
··· 270 270 locked = console_trylock(); 271 271 } 272 272 273 - while (1) { 273 + while (*lines) { 274 274 p = strchrnul(lines, '\n'); 275 275 printk("%s%.*s\n", prefix, (int) (p - lines), lines); 276 276 if (!*p)
+1
fs/bcachefs/util.h
··· 94 94 #define printbuf_tabstop_push(_buf, _n) bch2_printbuf_tabstop_push(_buf, _n) 95 95 96 96 #define printbuf_indent_add(_out, _n) bch2_printbuf_indent_add(_out, _n) 97 + #define printbuf_indent_add_nextline(_out, _n) bch2_printbuf_indent_add_nextline(_out, _n) 97 98 #define printbuf_indent_sub(_out, _n) bch2_printbuf_indent_sub(_out, _n) 98 99 99 100 #define prt_newline(_out) bch2_prt_newline(_out)