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-06-12' of git://evilpiepirate.org/bcachefs

Pull bcachefs fixes from Kent Overstreet:
"As usual, highlighting the ones users have been noticing:

- Fix a small issue with has_case_insensitive not being propagated on
snapshot creation; this led to fsck errors, which we're harmless
because we're not using this flag yet (it's for overlayfs +
casefolding).

- Log the error being corrected in the journal when we're doing fsck
repair: this was one of the "lessons learned" from the i_nlink 0 ->
subvolume deletion bug, where reconstructing what had happened by
analyzing the journal was a bit more difficult than it needed to
be.

- Don't schedule btree node scan to run in the superblock: this fixes
a regression from the 6.16 recovery passes rework, and let to it
running unnecessarily.

The real issue here is that we don't have online, "self healing"
style topology repair yet: topology repair currently has to run
before we go RW, which means that we may schedule it unnecessarily
after a transient error. This will be fixed in the future.

- We now track, in btree node flags, the reason it was scheduled to
be rewritten. We discovered a deadlock in recovery when many btree
nodes need to be rewritten because they're degraded: fully fixing
this will take some work but it's now easier to see what's going
on.

For the bug report where this came up, a device had been kicked RO
due to transient errors: manually setting it back to RW was
sufficient to allow recovery to succeed.

- Mark a few more fsck errors as autofix: as a reminder to users,
please do keep reporting cases where something needs to be repaired
and is not repaired automatically (i.e. cases where -o fix_errors
or fsck -y is required).

- rcu_pending.c now works with PREEMPT_RT

- 'bcachefs device add', then umount, then remount wasn't working -
we now emit a uevent so that the new device's new superblock is
correctly picked up

- Assorted repair fixes: btree node scan will no longer incorrectly
update sb->version_min,

- Assorted syzbot fixes"

* tag 'bcachefs-2025-06-12' of git://evilpiepirate.org/bcachefs: (23 commits)
bcachefs: Don't trace should_be_locked unless changing
bcachefs: Ensure that snapshot creation propagates has_case_insensitive
bcachefs: Print devices we're mounting on multi device filesystems
bcachefs: Don't trust sb->nr_devices in members_to_text()
bcachefs: Fix version checks in validate_bset()
bcachefs: ioctl: avoid stack overflow warning
bcachefs: Don't pass trans to fsck_err() in gc_accounting_done
bcachefs: Fix leak in bch2_fs_recovery() error path
bcachefs: Fix rcu_pending for PREEMPT_RT
bcachefs: Fix downgrade_table_extra()
bcachefs: Don't put rhashtable on stack
bcachefs: Make sure opts.read_only gets propagated back to VFS
bcachefs: Fix possible console lock involved deadlock
bcachefs: mark more errors autofix
bcachefs: Don't persistently run scan_for_btree_nodes
bcachefs: Read error message now prints if self healing
bcachefs: Only run 'increase_depth' for keys from btree node csan
bcachefs: Mark need_discard_freespace_key_bad autofix
bcachefs: Update /dev/disk/by-uuid on device add
bcachefs: Add more flags to btree nodes for rewrite reason
...

+319 -116
-1
fs/bcachefs/bcachefs.h
··· 296 296 #define bch2_fmt(_c, fmt) bch2_log_msg(_c, fmt "\n") 297 297 298 298 void bch2_print_str(struct bch_fs *, const char *, const char *); 299 - void bch2_print_str_nonblocking(struct bch_fs *, const char *, const char *); 300 299 301 300 __printf(2, 3) 302 301 void bch2_print_opts(struct bch_opts *, const char *, ...);
+60 -35
fs/bcachefs/btree_gc.c
··· 397 397 continue; 398 398 } 399 399 400 - ret = btree_check_node_boundaries(trans, b, prev, cur, pulled_from_scan); 400 + ret = lockrestart_do(trans, 401 + btree_check_node_boundaries(trans, b, prev, cur, pulled_from_scan)); 402 + if (ret < 0) 403 + goto err; 404 + 401 405 if (ret == DID_FILL_FROM_SCAN) { 402 406 new_pass = true; 403 407 ret = 0; ··· 442 438 443 439 if (!ret && !IS_ERR_OR_NULL(prev)) { 444 440 BUG_ON(cur); 445 - ret = btree_repair_node_end(trans, b, prev, pulled_from_scan); 441 + ret = lockrestart_do(trans, 442 + btree_repair_node_end(trans, b, prev, pulled_from_scan)); 446 443 if (ret == DID_FILL_FROM_SCAN) { 447 444 new_pass = true; 448 445 ret = 0; ··· 524 519 bch2_bkey_buf_exit(&prev_k, c); 525 520 bch2_bkey_buf_exit(&cur_k, c); 526 521 printbuf_exit(&buf); 522 + bch_err_fn(c, ret); 523 + return ret; 524 + } 525 + 526 + static int bch2_check_root(struct btree_trans *trans, enum btree_id i, 527 + bool *reconstructed_root) 528 + { 529 + struct bch_fs *c = trans->c; 530 + struct btree_root *r = bch2_btree_id_root(c, i); 531 + struct printbuf buf = PRINTBUF; 532 + int ret = 0; 533 + 534 + bch2_btree_id_to_text(&buf, i); 535 + 536 + if (r->error) { 537 + bch_info(c, "btree root %s unreadable, must recover from scan", buf.buf); 538 + 539 + r->alive = false; 540 + r->error = 0; 541 + 542 + if (!bch2_btree_has_scanned_nodes(c, i)) { 543 + __fsck_err(trans, 544 + FSCK_CAN_FIX|(!btree_id_important(i) ? FSCK_AUTOFIX : 0), 545 + btree_root_unreadable_and_scan_found_nothing, 546 + "no nodes found for btree %s, continue?", buf.buf); 547 + bch2_btree_root_alloc_fake_trans(trans, i, 0); 548 + } else { 549 + bch2_btree_root_alloc_fake_trans(trans, i, 1); 550 + bch2_shoot_down_journal_keys(c, i, 1, BTREE_MAX_DEPTH, POS_MIN, SPOS_MAX); 551 + ret = bch2_get_scanned_nodes(c, i, 0, POS_MIN, SPOS_MAX); 552 + if (ret) 553 + goto err; 554 + } 555 + 556 + *reconstructed_root = true; 557 + } 558 + err: 559 + fsck_err: 560 + printbuf_exit(&buf); 561 + bch_err_fn(c, ret); 527 562 return ret; 528 563 } 529 564 ··· 571 526 { 572 527 struct btree_trans *trans = bch2_trans_get(c); 573 528 struct bpos pulled_from_scan = POS_MIN; 574 - struct printbuf buf = PRINTBUF; 575 529 int ret = 0; 576 530 577 531 bch2_trans_srcu_unlock(trans); 578 532 579 533 for (unsigned i = 0; i < btree_id_nr_alive(c) && !ret; i++) { 580 - struct btree_root *r = bch2_btree_id_root(c, i); 581 534 bool reconstructed_root = false; 535 + recover: 536 + ret = lockrestart_do(trans, bch2_check_root(trans, i, &reconstructed_root)); 537 + if (ret) 538 + break; 582 539 583 - printbuf_reset(&buf); 584 - bch2_btree_id_to_text(&buf, i); 585 - 586 - if (r->error) { 587 - reconstruct_root: 588 - bch_info(c, "btree root %s unreadable, must recover from scan", buf.buf); 589 - 590 - r->alive = false; 591 - r->error = 0; 592 - 593 - if (!bch2_btree_has_scanned_nodes(c, i)) { 594 - __fsck_err(trans, 595 - FSCK_CAN_FIX|(!btree_id_important(i) ? FSCK_AUTOFIX : 0), 596 - btree_root_unreadable_and_scan_found_nothing, 597 - "no nodes found for btree %s, continue?", buf.buf); 598 - bch2_btree_root_alloc_fake_trans(trans, i, 0); 599 - } else { 600 - bch2_btree_root_alloc_fake_trans(trans, i, 1); 601 - bch2_shoot_down_journal_keys(c, i, 1, BTREE_MAX_DEPTH, POS_MIN, SPOS_MAX); 602 - ret = bch2_get_scanned_nodes(c, i, 0, POS_MIN, SPOS_MAX); 603 - if (ret) 604 - break; 605 - } 606 - 607 - reconstructed_root = true; 608 - } 609 - 540 + struct btree_root *r = bch2_btree_id_root(c, i); 610 541 struct btree *b = r->b; 611 542 612 543 btree_node_lock_nopath_nofail(trans, &b->c, SIX_LOCK_read); ··· 596 575 597 576 r->b = NULL; 598 577 599 - if (!reconstructed_root) 600 - goto reconstruct_root; 578 + if (!reconstructed_root) { 579 + r->error = -EIO; 580 + goto recover; 581 + } 601 582 583 + struct printbuf buf = PRINTBUF; 584 + bch2_btree_id_to_text(&buf, i); 602 585 bch_err(c, "empty btree root %s", buf.buf); 586 + printbuf_exit(&buf); 603 587 bch2_btree_root_alloc_fake_trans(trans, i, 0); 604 588 r->alive = false; 605 589 ret = 0; 606 590 } 607 591 } 608 - fsck_err: 609 - printbuf_exit(&buf); 592 + 610 593 bch2_trans_put(trans); 611 594 return ret; 612 595 }
+19 -7
fs/bcachefs/btree_io.c
··· 741 741 BCH_VERSION_MAJOR(version), 742 742 BCH_VERSION_MINOR(version)); 743 743 744 - if (btree_err_on(version < c->sb.version_min, 744 + if (c->recovery.curr_pass != BCH_RECOVERY_PASS_scan_for_btree_nodes && 745 + btree_err_on(version < c->sb.version_min, 745 746 -BCH_ERR_btree_node_read_err_fixable, 746 747 c, NULL, b, i, NULL, 747 748 btree_node_bset_older_than_sb_min, 748 749 "bset version %u older than superblock version_min %u", 749 750 version, c->sb.version_min)) { 750 - mutex_lock(&c->sb_lock); 751 - c->disk_sb.sb->version_min = cpu_to_le16(version); 752 - bch2_write_super(c); 753 - mutex_unlock(&c->sb_lock); 751 + if (bch2_version_compatible(version)) { 752 + mutex_lock(&c->sb_lock); 753 + c->disk_sb.sb->version_min = cpu_to_le16(version); 754 + bch2_write_super(c); 755 + mutex_unlock(&c->sb_lock); 756 + } else { 757 + /* We have no idea what's going on: */ 758 + i->version = cpu_to_le16(c->sb.version); 759 + } 754 760 } 755 761 756 762 if (btree_err_on(BCH_VERSION_MAJOR(version) > ··· 1051 1045 le16_add_cpu(&i->u64s, -next_good_key); 1052 1046 memmove_u64s_down(k, (u64 *) k + next_good_key, (u64 *) vstruct_end(i) - (u64 *) k); 1053 1047 set_btree_node_need_rewrite(b); 1048 + set_btree_node_need_rewrite_error(b); 1054 1049 } 1055 1050 fsck_err: 1056 1051 printbuf_exit(&buf); ··· 1312 1305 (u64 *) vstruct_end(i) - (u64 *) k); 1313 1306 set_btree_bset_end(b, b->set); 1314 1307 set_btree_node_need_rewrite(b); 1308 + set_btree_node_need_rewrite_error(b); 1315 1309 continue; 1316 1310 } 1317 1311 if (ret) ··· 1337 1329 bkey_for_each_ptr(bch2_bkey_ptrs(bkey_i_to_s(&b->key)), ptr) { 1338 1330 struct bch_dev *ca2 = bch2_dev_rcu(c, ptr->dev); 1339 1331 1340 - if (!ca2 || ca2->mi.state != BCH_MEMBER_STATE_rw) 1332 + if (!ca2 || ca2->mi.state != BCH_MEMBER_STATE_rw) { 1341 1333 set_btree_node_need_rewrite(b); 1334 + set_btree_node_need_rewrite_degraded(b); 1335 + } 1342 1336 } 1343 1337 1344 - if (!ptr_written) 1338 + if (!ptr_written) { 1345 1339 set_btree_node_need_rewrite(b); 1340 + set_btree_node_need_rewrite_ptr_written_zero(b); 1341 + } 1346 1342 fsck_err: 1347 1343 mempool_free(iter, &c->fill_iter); 1348 1344 printbuf_exit(&buf);
+1 -1
fs/bcachefs/btree_locking.c
··· 213 213 prt_newline(&buf); 214 214 } 215 215 216 - bch2_print_str_nonblocking(g->g->trans->c, KERN_ERR, buf.buf); 216 + bch2_print_str(g->g->trans->c, KERN_ERR, buf.buf); 217 217 printbuf_exit(&buf); 218 218 BUG(); 219 219 }
+4 -2
fs/bcachefs/btree_locking.h
··· 417 417 EBUG_ON(!btree_node_locked(path, path->level)); 418 418 EBUG_ON(path->uptodate); 419 419 420 - path->should_be_locked = true; 421 - trace_btree_path_should_be_locked(trans, path); 420 + if (!path->should_be_locked) { 421 + path->should_be_locked = true; 422 + trace_btree_path_should_be_locked(trans, path); 423 + } 422 424 } 423 425 424 426 static inline void __btree_path_set_level_up(struct btree_trans *trans,
+29
fs/bcachefs/btree_types.h
··· 617 617 x(dying) \ 618 618 x(fake) \ 619 619 x(need_rewrite) \ 620 + x(need_rewrite_error) \ 621 + x(need_rewrite_degraded) \ 622 + x(need_rewrite_ptr_written_zero) \ 620 623 x(never_write) \ 621 624 x(pinned) 622 625 ··· 643 640 644 641 BTREE_FLAGS() 645 642 #undef x 643 + 644 + #define BTREE_NODE_REWRITE_REASON() \ 645 + x(none) \ 646 + x(unknown) \ 647 + x(error) \ 648 + x(degraded) \ 649 + x(ptr_written_zero) 650 + 651 + enum btree_node_rewrite_reason { 652 + #define x(n) BTREE_NODE_REWRITE_##n, 653 + BTREE_NODE_REWRITE_REASON() 654 + #undef x 655 + }; 656 + 657 + static inline enum btree_node_rewrite_reason btree_node_rewrite_reason(struct btree *b) 658 + { 659 + if (btree_node_need_rewrite_ptr_written_zero(b)) 660 + return BTREE_NODE_REWRITE_ptr_written_zero; 661 + if (btree_node_need_rewrite_degraded(b)) 662 + return BTREE_NODE_REWRITE_degraded; 663 + if (btree_node_need_rewrite_error(b)) 664 + return BTREE_NODE_REWRITE_error; 665 + if (btree_node_need_rewrite(b)) 666 + return BTREE_NODE_REWRITE_unknown; 667 + return BTREE_NODE_REWRITE_none; 668 + } 646 669 647 670 static inline struct btree_write *btree_current_write(struct btree *b) 648 671 {
+31 -2
fs/bcachefs/btree_update_interior.c
··· 1138 1138 start_time); 1139 1139 } 1140 1140 1141 + static const char * const btree_node_reawrite_reason_strs[] = { 1142 + #define x(n) #n, 1143 + BTREE_NODE_REWRITE_REASON() 1144 + #undef x 1145 + NULL, 1146 + }; 1147 + 1141 1148 static struct btree_update * 1142 1149 bch2_btree_update_start(struct btree_trans *trans, struct btree_path *path, 1143 1150 unsigned level_start, bool split, ··· 1238 1231 mutex_lock(&c->btree_interior_update_lock); 1239 1232 list_add_tail(&as->list, &c->btree_interior_update_list); 1240 1233 mutex_unlock(&c->btree_interior_update_lock); 1234 + 1235 + struct btree *b = btree_path_node(path, path->level); 1236 + as->node_start = b->data->min_key; 1237 + as->node_end = b->data->max_key; 1238 + as->node_needed_rewrite = btree_node_rewrite_reason(b); 1239 + as->node_written = b->written; 1240 + as->node_sectors = btree_buf_bytes(b) >> 9; 1241 + as->node_remaining = __bch2_btree_u64s_remaining(b, 1242 + btree_bkey_last(b, bset_tree_last(b))); 1241 1243 1242 1244 /* 1243 1245 * We don't want to allocate if we're in an error state, that can cause ··· 2124 2108 if (ret) 2125 2109 goto err; 2126 2110 2111 + as->node_start = prev->data->min_key; 2112 + as->node_end = next->data->max_key; 2113 + 2127 2114 trace_and_count(c, btree_node_merge, trans, b); 2128 2115 2129 2116 n = bch2_btree_node_alloc(as, trans, b->c.level); ··· 2700 2681 2701 2682 prt_str(out, " "); 2702 2683 bch2_btree_id_to_text(out, as->btree_id); 2703 - prt_printf(out, " l=%u-%u mode=%s nodes_written=%u cl.remaining=%u journal_seq=%llu\n", 2684 + prt_printf(out, " l=%u-%u ", 2704 2685 as->update_level_start, 2705 - as->update_level_end, 2686 + as->update_level_end); 2687 + bch2_bpos_to_text(out, as->node_start); 2688 + prt_char(out, ' '); 2689 + bch2_bpos_to_text(out, as->node_end); 2690 + prt_printf(out, "\nwritten %u/%u u64s_remaining %u need_rewrite %s", 2691 + as->node_written, 2692 + as->node_sectors, 2693 + as->node_remaining, 2694 + btree_node_reawrite_reason_strs[as->node_needed_rewrite]); 2695 + 2696 + prt_printf(out, "\nmode=%s nodes_written=%u cl.remaining=%u journal_seq=%llu\n", 2706 2697 bch2_btree_update_modes[as->mode], 2707 2698 as->nodes_written, 2708 2699 closure_nr_remaining(&as->cl),
+7
fs/bcachefs/btree_update_interior.h
··· 57 57 unsigned took_gc_lock:1; 58 58 59 59 enum btree_id btree_id; 60 + struct bpos node_start; 61 + struct bpos node_end; 62 + enum btree_node_rewrite_reason node_needed_rewrite; 63 + u16 node_written; 64 + u16 node_sectors; 65 + u16 node_remaining; 66 + 60 67 unsigned update_level_start; 61 68 unsigned update_level_end; 62 69
+2 -2
fs/bcachefs/chardev.c
··· 399 399 return ret; 400 400 } 401 401 402 - static long bch2_ioctl_fs_usage(struct bch_fs *c, 402 + static noinline_for_stack long bch2_ioctl_fs_usage(struct bch_fs *c, 403 403 struct bch_ioctl_fs_usage __user *user_arg) 404 404 { 405 405 struct bch_ioctl_fs_usage arg = {}; ··· 469 469 } 470 470 471 471 /* obsolete, didn't allow for new data types: */ 472 - static long bch2_ioctl_dev_usage(struct bch_fs *c, 472 + static noinline_for_stack long bch2_ioctl_dev_usage(struct bch_fs *c, 473 473 struct bch_ioctl_dev_usage __user *user_arg) 474 474 { 475 475 struct bch_ioctl_dev_usage arg;
+3 -1
fs/bcachefs/disk_accounting.c
··· 618 618 for (unsigned j = 0; j < nr; j++) 619 619 src_v[j] -= dst_v[j]; 620 620 621 - if (fsck_err(trans, accounting_mismatch, "%s", buf.buf)) { 621 + bch2_trans_unlock_long(trans); 622 + 623 + if (fsck_err(c, accounting_mismatch, "%s", buf.buf)) { 622 624 percpu_up_write(&c->mark_lock); 623 625 ret = commit_do(trans, NULL, NULL, 0, 624 626 bch2_disk_accounting_mod(trans, &acc_k, src_v, nr, false));
+4 -1
fs/bcachefs/error.c
··· 69 69 if (trans) 70 70 bch2_trans_updates_to_text(&buf, trans); 71 71 bool ret = __bch2_inconsistent_error(c, &buf); 72 - bch2_print_str_nonblocking(c, KERN_ERR, buf.buf); 72 + bch2_print_str(c, KERN_ERR, buf.buf); 73 73 74 74 printbuf_exit(&buf); 75 75 return ret; ··· 620 620 621 621 if (s) 622 622 s->ret = ret; 623 + 624 + if (trans) 625 + ret = bch2_trans_log_str(trans, bch2_sb_error_strs[err]) ?: ret; 623 626 err_unlock: 624 627 mutex_unlock(&c->fsck_error_msgs_lock); 625 628 err:
+8
fs/bcachefs/fs.c
··· 2490 2490 if (ret) 2491 2491 goto err_stop_fs; 2492 2492 2493 + /* 2494 + * We might be doing a RO mount because other options required it, or we 2495 + * have no alloc info and it's a small image with no room to regenerate 2496 + * it 2497 + */ 2498 + if (c->opts.read_only) 2499 + fc->sb_flags |= SB_RDONLY; 2500 + 2493 2501 sb = sget(fc->fs_type, NULL, bch2_set_super, fc->sb_flags|SB_NOSEC, c); 2494 2502 ret = PTR_ERR_OR_ZERO(sb); 2495 2503 if (ret)
+9 -2
fs/bcachefs/io_read.c
··· 343 343 344 344 *bounce = true; 345 345 *read_full = promote_full; 346 + 347 + if (have_io_error(failed)) 348 + orig->self_healing = true; 349 + 346 350 return promote; 347 351 nopromote: 348 352 trace_io_read_nopromote(c, ret); ··· 639 635 prt_str(&buf, "(internal move) "); 640 636 641 637 prt_str(&buf, "data read error, "); 642 - if (!ret) 638 + if (!ret) { 643 639 prt_str(&buf, "successful retry"); 644 - else 640 + if (rbio->self_healing) 641 + prt_str(&buf, ", self healing"); 642 + } else 645 643 prt_str(&buf, bch2_err_str(ret)); 646 644 prt_newline(&buf); 645 + 647 646 648 647 if (!bkey_deleted(&sk.k->k)) { 649 648 bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(sk.k));
+1
fs/bcachefs/io_read.h
··· 44 44 have_ioref:1, 45 45 narrow_crcs:1, 46 46 saw_error:1, 47 + self_healing:1, 47 48 context:2; 48 49 }; 49 50 u16 _state;
+13 -9
fs/bcachefs/movinggc.c
··· 28 28 #include <linux/wait.h> 29 29 30 30 struct buckets_in_flight { 31 - struct rhashtable table; 31 + struct rhashtable *table; 32 32 struct move_bucket *first; 33 33 struct move_bucket *last; 34 34 size_t nr; ··· 98 98 static void move_bucket_free(struct buckets_in_flight *list, 99 99 struct move_bucket *b) 100 100 { 101 - int ret = rhashtable_remove_fast(&list->table, &b->hash, 101 + int ret = rhashtable_remove_fast(list->table, &b->hash, 102 102 bch_move_bucket_params); 103 103 BUG_ON(ret); 104 104 kfree(b); ··· 133 133 static bool bucket_in_flight(struct buckets_in_flight *list, 134 134 struct move_bucket_key k) 135 135 { 136 - return rhashtable_lookup_fast(&list->table, &k, bch_move_bucket_params); 136 + return rhashtable_lookup_fast(list->table, &k, bch_move_bucket_params); 137 137 } 138 138 139 139 static int bch2_copygc_get_buckets(struct moving_context *ctxt, ··· 185 185 goto err; 186 186 } 187 187 188 - ret2 = rhashtable_lookup_insert_fast(&buckets_in_flight->table, &b_i->hash, 188 + ret2 = rhashtable_lookup_insert_fast(buckets_in_flight->table, &b_i->hash, 189 189 bch_move_bucket_params); 190 190 BUG_ON(ret2); 191 191 ··· 350 350 struct buckets_in_flight buckets = {}; 351 351 u64 last, wait; 352 352 353 - int ret = rhashtable_init(&buckets.table, &bch_move_bucket_params); 353 + buckets.table = kzalloc(sizeof(*buckets.table), GFP_KERNEL); 354 + int ret = !buckets.table 355 + ? -ENOMEM 356 + : rhashtable_init(buckets.table, &bch_move_bucket_params); 354 357 bch_err_msg(c, ret, "allocating copygc buckets in flight"); 355 358 if (ret) 356 - return ret; 359 + goto err; 357 360 358 361 set_freezable(); 359 362 ··· 424 421 } 425 422 426 423 move_buckets_wait(&ctxt, &buckets, true); 427 - rhashtable_destroy(&buckets.table); 424 + rhashtable_destroy(buckets.table); 428 425 bch2_moving_ctxt_exit(&ctxt); 429 426 bch2_move_stats_exit(&move_stats, c); 430 - 431 - return 0; 427 + err: 428 + kfree(buckets.table); 429 + return ret; 432 430 } 433 431 434 432 void bch2_copygc_stop(struct bch_fs *c)
+10
fs/bcachefs/namei.c
··· 175 175 new_inode->bi_dir_offset = dir_offset; 176 176 } 177 177 178 + if (S_ISDIR(mode)) { 179 + ret = bch2_maybe_propagate_has_case_insensitive(trans, 180 + (subvol_inum) { 181 + new_inode->bi_subvol ?: dir.subvol, 182 + new_inode->bi_inum }, 183 + new_inode); 184 + if (ret) 185 + goto err; 186 + } 187 + 178 188 if (S_ISDIR(mode) && 179 189 !new_inode->bi_subvol) 180 190 new_inode->bi_depth = dir_u->bi_depth + 1;
+11 -11
fs/bcachefs/rcu_pending.c
··· 182 182 while (nr--) 183 183 kfree(*p); 184 184 } 185 - 186 - #define local_irq_save(flags) \ 187 - do { \ 188 - flags = 0; \ 189 - } while (0) 190 185 #endif 191 186 192 187 static noinline void __process_finished_items(struct rcu_pending *pending, ··· 424 429 425 430 BUG_ON((ptr != NULL) != (pending->process == RCU_PENDING_KVFREE_FN)); 426 431 427 - local_irq_save(flags); 428 - p = this_cpu_ptr(pending->p); 429 - spin_lock(&p->lock); 432 + /* We could technically be scheduled before taking the lock and end up 433 + * using a different cpu's rcu_pending_pcpu: that's ok, it needs a lock 434 + * anyways 435 + * 436 + * And we have to do it this way to avoid breaking PREEMPT_RT, which 437 + * redefines how spinlocks work: 438 + */ 439 + p = raw_cpu_ptr(pending->p); 440 + spin_lock_irqsave(&p->lock, flags); 430 441 rcu_gp_poll_state_t seq = __get_state_synchronize_rcu(pending->srcu); 431 442 restart: 432 443 if (may_sleep && ··· 521 520 goto free_node; 522 521 } 523 522 524 - local_irq_save(flags); 525 - p = this_cpu_ptr(pending->p); 526 - spin_lock(&p->lock); 523 + p = raw_cpu_ptr(pending->p); 524 + spin_lock_irqsave(&p->lock, flags); 527 525 goto restart; 528 526 } 529 527
+21 -6
fs/bcachefs/recovery.c
··· 99 99 goto out; 100 100 case BTREE_ID_snapshots: 101 101 ret = __bch2_run_explicit_recovery_pass(c, msg, BCH_RECOVERY_PASS_reconstruct_snapshots, 0) ?: ret; 102 + ret = __bch2_run_explicit_recovery_pass(c, msg, BCH_RECOVERY_PASS_check_topology, 0) ?: ret; 102 103 ret = __bch2_run_explicit_recovery_pass(c, msg, BCH_RECOVERY_PASS_scan_for_btree_nodes, 0) ?: ret; 103 104 goto out; 104 105 default: 106 + ret = __bch2_run_explicit_recovery_pass(c, msg, BCH_RECOVERY_PASS_check_topology, 0) ?: ret; 105 107 ret = __bch2_run_explicit_recovery_pass(c, msg, BCH_RECOVERY_PASS_scan_for_btree_nodes, 0) ?: ret; 106 108 goto out; 107 109 } ··· 273 271 goto out; 274 272 275 273 struct btree_path *path = btree_iter_path(trans, &iter); 276 - if (unlikely(!btree_path_node(path, k->level))) { 274 + if (unlikely(!btree_path_node(path, k->level) && 275 + !k->allocated)) { 276 + struct bch_fs *c = trans->c; 277 + 278 + if (!(c->recovery.passes_complete & (BIT_ULL(BCH_RECOVERY_PASS_scan_for_btree_nodes)| 279 + BIT_ULL(BCH_RECOVERY_PASS_check_topology)))) { 280 + bch_err(c, "have key in journal replay for btree depth that does not exist, confused"); 281 + ret = -EINVAL; 282 + } 283 + #if 0 277 284 bch2_trans_iter_exit(trans, &iter); 278 285 bch2_trans_node_iter_init(trans, &iter, k->btree_id, k->k->k.p, 279 286 BTREE_MAX_DEPTH, 0, iter_flags); 280 287 ret = bch2_btree_iter_traverse(trans, &iter) ?: 281 288 bch2_btree_increase_depth(trans, iter.path, 0) ?: 282 289 -BCH_ERR_transaction_restart_nested; 290 + #endif 291 + k->overwritten = true; 283 292 goto out; 284 293 } 285 294 ··· 752 739 ? min(c->opts.recovery_pass_last, BCH_RECOVERY_PASS_snapshots_read) 753 740 : BCH_RECOVERY_PASS_snapshots_read; 754 741 c->opts.nochanges = true; 755 - c->opts.read_only = true; 756 742 } 743 + 744 + if (c->opts.nochanges) 745 + c->opts.read_only = true; 757 746 758 747 mutex_lock(&c->sb_lock); 759 748 struct bch_sb_field_ext *ext = bch2_sb_field_get(c->disk_sb.sb, ext); ··· 1108 1093 out: 1109 1094 bch2_flush_fsck_errs(c); 1110 1095 1111 - if (!IS_ERR(clean)) 1112 - kfree(clean); 1113 - 1114 1096 if (!ret && 1115 1097 test_bit(BCH_FS_need_delete_dead_snapshots, &c->flags) && 1116 1098 !c->opts.nochanges) { ··· 1116 1104 } 1117 1105 1118 1106 bch_err_fn(c, ret); 1107 + final_out: 1108 + if (!IS_ERR(clean)) 1109 + kfree(clean); 1119 1110 return ret; 1120 1111 err: 1121 1112 fsck_err: ··· 1132 1117 bch2_print_str(c, KERN_ERR, buf.buf); 1133 1118 printbuf_exit(&buf); 1134 1119 } 1135 - return ret; 1120 + goto final_out; 1136 1121 } 1137 1122 1138 1123 int bch2_fs_initialize(struct bch_fs *c)
+11 -3
fs/bcachefs/recovery_passes.c
··· 294 294 enum bch_run_recovery_pass_flags *flags) 295 295 { 296 296 struct bch_fs_recovery *r = &c->recovery; 297 - bool in_recovery = test_bit(BCH_FS_in_recovery, &c->flags); 298 - bool persistent = !in_recovery || !(*flags & RUN_RECOVERY_PASS_nopersistent); 297 + 298 + /* 299 + * Never run scan_for_btree_nodes persistently: check_topology will run 300 + * it if required 301 + */ 302 + if (pass == BCH_RECOVERY_PASS_scan_for_btree_nodes) 303 + *flags |= RUN_RECOVERY_PASS_nopersistent; 299 304 300 305 if ((*flags & RUN_RECOVERY_PASS_ratelimit) && 301 306 !bch2_recovery_pass_want_ratelimit(c, pass)) ··· 315 310 * Otherwise, we run run_explicit_recovery_pass when we find damage, so 316 311 * it should run again even if it's already run: 317 312 */ 313 + bool in_recovery = test_bit(BCH_FS_in_recovery, &c->flags); 314 + bool persistent = !in_recovery || !(*flags & RUN_RECOVERY_PASS_nopersistent); 318 315 319 316 if (persistent 320 317 ? !(c->sb.recovery_passes_required & BIT_ULL(pass)) ··· 340 333 { 341 334 struct bch_fs_recovery *r = &c->recovery; 342 335 int ret = 0; 336 + 343 337 344 338 lockdep_assert_held(&c->sb_lock); 345 339 ··· 454 446 455 447 int bch2_run_print_explicit_recovery_pass(struct bch_fs *c, enum bch_recovery_pass pass) 456 448 { 457 - enum bch_run_recovery_pass_flags flags = RUN_RECOVERY_PASS_nopersistent; 449 + enum bch_run_recovery_pass_flags flags = 0; 458 450 459 451 if (!recovery_pass_needs_set(c, pass, &flags)) 460 452 return 0;
+4 -1
fs/bcachefs/sb-downgrade.c
··· 253 253 254 254 static int downgrade_table_extra(struct bch_fs *c, darray_char *table) 255 255 { 256 + unsigned dst_offset = table->nr; 256 257 struct bch_sb_field_downgrade_entry *dst = (void *) &darray_top(*table); 257 258 unsigned bytes = sizeof(*dst) + sizeof(dst->errors[0]) * le16_to_cpu(dst->nr_errors); 258 259 int ret = 0; ··· 269 268 if (ret) 270 269 return ret; 271 270 271 + dst = (void *) &table->data[dst_offset]; 272 + dst->nr_errors = cpu_to_le16(nr_errors + 1); 273 + 272 274 /* open coded __set_bit_le64, as dst is packed and 273 275 * dst->recovery_passes is misaligned */ 274 276 unsigned b = BCH_RECOVERY_PASS_STABLE_check_allocations; ··· 282 278 break; 283 279 } 284 280 285 - dst->nr_errors = cpu_to_le16(nr_errors); 286 281 return ret; 287 282 } 288 283
+5 -5
fs/bcachefs/sb-errors_format.h
··· 134 134 x(bucket_gens_to_invalid_buckets, 121, FSCK_AUTOFIX) \ 135 135 x(bucket_gens_nonzero_for_invalid_buckets, 122, FSCK_AUTOFIX) \ 136 136 x(need_discard_freespace_key_to_invalid_dev_bucket, 123, 0) \ 137 - x(need_discard_freespace_key_bad, 124, 0) \ 137 + x(need_discard_freespace_key_bad, 124, FSCK_AUTOFIX) \ 138 138 x(discarding_bucket_not_in_need_discard_btree, 291, 0) \ 139 139 x(backpointer_bucket_offset_wrong, 125, 0) \ 140 140 x(backpointer_level_bad, 294, 0) \ ··· 165 165 x(ptr_to_missing_replicas_entry, 149, FSCK_AUTOFIX) \ 166 166 x(ptr_to_missing_stripe, 150, 0) \ 167 167 x(ptr_to_incorrect_stripe, 151, 0) \ 168 - x(ptr_gen_newer_than_bucket_gen, 152, 0) \ 168 + x(ptr_gen_newer_than_bucket_gen, 152, FSCK_AUTOFIX) \ 169 169 x(ptr_too_stale, 153, 0) \ 170 170 x(stale_dirty_ptr, 154, FSCK_AUTOFIX) \ 171 171 x(ptr_bucket_data_type_mismatch, 155, 0) \ ··· 236 236 x(inode_multiple_links_but_nlink_0, 207, FSCK_AUTOFIX) \ 237 237 x(inode_wrong_backpointer, 208, FSCK_AUTOFIX) \ 238 238 x(inode_wrong_nlink, 209, FSCK_AUTOFIX) \ 239 - x(inode_has_child_snapshots_wrong, 287, 0) \ 239 + x(inode_has_child_snapshots_wrong, 287, FSCK_AUTOFIX) \ 240 240 x(inode_unreachable, 210, FSCK_AUTOFIX) \ 241 241 x(inode_journal_seq_in_future, 299, FSCK_AUTOFIX) \ 242 242 x(inode_i_sectors_underflow, 312, FSCK_AUTOFIX) \ ··· 279 279 x(root_dir_missing, 239, 0) \ 280 280 x(root_inode_not_dir, 240, 0) \ 281 281 x(dir_loop, 241, 0) \ 282 - x(hash_table_key_duplicate, 242, 0) \ 283 - x(hash_table_key_wrong_offset, 243, 0) \ 282 + x(hash_table_key_duplicate, 242, FSCK_AUTOFIX) \ 283 + x(hash_table_key_wrong_offset, 243, FSCK_AUTOFIX) \ 284 284 x(unlinked_inode_not_on_deleted_list, 244, FSCK_AUTOFIX) \ 285 285 x(reflink_p_front_pad_bad, 245, 0) \ 286 286 x(journal_entry_dup_same_device, 246, 0) \
+30 -4
fs/bcachefs/sb-members.c
··· 325 325 { 326 326 struct bch_sb_field_members_v1 *mi = field_to_type(f, members_v1); 327 327 struct bch_sb_field_disk_groups *gi = bch2_sb_field_get(sb, disk_groups); 328 - unsigned i; 329 328 330 - for (i = 0; i < sb->nr_devices; i++) 329 + if (vstruct_end(&mi->field) <= (void *) &mi->_members[0]) { 330 + prt_printf(out, "field ends before start of entries"); 331 + return; 332 + } 333 + 334 + unsigned nr = (vstruct_end(&mi->field) - (void *) &mi->_members[0]) / sizeof(mi->_members[0]); 335 + if (nr != sb->nr_devices) 336 + prt_printf(out, "nr_devices mismatch: have %i entries, should be %u", nr, sb->nr_devices); 337 + 338 + for (unsigned i = 0; i < min(sb->nr_devices, nr); i++) 331 339 member_to_text(out, members_v1_get(mi, i), gi, sb, i); 332 340 } 333 341 ··· 349 341 { 350 342 struct bch_sb_field_members_v2 *mi = field_to_type(f, members_v2); 351 343 struct bch_sb_field_disk_groups *gi = bch2_sb_field_get(sb, disk_groups); 352 - unsigned i; 353 344 354 - for (i = 0; i < sb->nr_devices; i++) 345 + if (vstruct_end(&mi->field) <= (void *) &mi->_members[0]) { 346 + prt_printf(out, "field ends before start of entries"); 347 + return; 348 + } 349 + 350 + if (!le16_to_cpu(mi->member_bytes)) { 351 + prt_printf(out, "member_bytes 0"); 352 + return; 353 + } 354 + 355 + unsigned nr = (vstruct_end(&mi->field) - (void *) &mi->_members[0]) / le16_to_cpu(mi->member_bytes); 356 + if (nr != sb->nr_devices) 357 + prt_printf(out, "nr_devices mismatch: have %i entries, should be %u", nr, sb->nr_devices); 358 + 359 + /* 360 + * We call to_text() on superblock sections that haven't passed 361 + * validate, so we can't trust sb->nr_devices. 362 + */ 363 + 364 + for (unsigned i = 0; i < min(sb->nr_devices, nr); i++) 355 365 member_to_text(out, members_v2_get(mi, i), gi, sb, i); 356 366 } 357 367
+33 -14
fs/bcachefs/super.c
··· 104 104 #undef x 105 105 106 106 static void __bch2_print_str(struct bch_fs *c, const char *prefix, 107 - const char *str, bool nonblocking) 107 + const char *str) 108 108 { 109 109 #ifdef __KERNEL__ 110 110 struct stdio_redirect *stdio = bch2_fs_stdio_redirect(c); ··· 114 114 return; 115 115 } 116 116 #endif 117 - bch2_print_string_as_lines(KERN_ERR, str, nonblocking); 117 + bch2_print_string_as_lines(KERN_ERR, str); 118 118 } 119 119 120 120 void bch2_print_str(struct bch_fs *c, const char *prefix, const char *str) 121 121 { 122 - __bch2_print_str(c, prefix, str, false); 123 - } 124 - 125 - void bch2_print_str_nonblocking(struct bch_fs *c, const char *prefix, const char *str) 126 - { 127 - __bch2_print_str(c, prefix, str, true); 122 + __bch2_print_str(c, prefix, str); 128 123 } 129 124 130 125 __printf(2, 0) ··· 1067 1072 static void print_mount_opts(struct bch_fs *c) 1068 1073 { 1069 1074 enum bch_opt_id i; 1070 - struct printbuf p = PRINTBUF; 1071 - bool first = true; 1075 + CLASS(printbuf, p)(); 1076 + bch2_log_msg_start(c, &p); 1072 1077 1073 1078 prt_str(&p, "starting version "); 1074 1079 bch2_version_to_text(&p, c->sb.version); 1075 1080 1081 + bool first = true; 1076 1082 for (i = 0; i < bch2_opts_nr; i++) { 1077 1083 const struct bch_option *opt = &bch2_opt_table[i]; 1078 1084 u64 v = bch2_opt_get_by_id(&c->opts, i); ··· 1090 1094 } 1091 1095 1092 1096 if (c->sb.version_incompat_allowed != c->sb.version) { 1093 - prt_printf(&p, "\n allowing incompatible features above "); 1097 + prt_printf(&p, "\nallowing incompatible features above "); 1094 1098 bch2_version_to_text(&p, c->sb.version_incompat_allowed); 1095 1099 } 1096 1100 1097 1101 if (c->opts.verbose) { 1098 - prt_printf(&p, "\n features: "); 1102 + prt_printf(&p, "\nfeatures: "); 1099 1103 prt_bitflags(&p, bch2_sb_features, c->sb.features); 1100 1104 } 1101 1105 1102 - bch_info(c, "%s", p.buf); 1103 - printbuf_exit(&p); 1106 + if (c->sb.multi_device) { 1107 + prt_printf(&p, "\nwith devices"); 1108 + for_each_online_member(c, ca, BCH_DEV_READ_REF_bch2_online_devs) { 1109 + prt_char(&p, ' '); 1110 + prt_str(&p, ca->name); 1111 + } 1112 + } 1113 + 1114 + bch2_print_str(c, KERN_INFO, p.buf); 1104 1115 } 1105 1116 1106 1117 static bool bch2_fs_may_start(struct bch_fs *c) ··· 1997 1994 if (ret) 1998 1995 goto err_late; 1999 1996 } 1997 + 1998 + /* 1999 + * We just changed the superblock UUID, invalidate cache and send a 2000 + * uevent to update /dev/disk/by-uuid 2001 + */ 2002 + invalidate_bdev(ca->disk_sb.bdev); 2003 + 2004 + char uuid_str[37]; 2005 + snprintf(uuid_str, sizeof(uuid_str), "UUID=%pUb", &c->sb.uuid); 2006 + 2007 + char *envp[] = { 2008 + "CHANGE=uuid", 2009 + uuid_str, 2010 + NULL, 2011 + }; 2012 + kobject_uevent_env(&ca->disk_sb.bdev->bd_device.kobj, KOBJ_CHANGE, envp); 2000 2013 2001 2014 up_write(&c->state_lock); 2002 2015 out:
+2 -8
fs/bcachefs/util.c
··· 262 262 return true; 263 263 } 264 264 265 - void bch2_print_string_as_lines(const char *prefix, const char *lines, 266 - bool nonblocking) 265 + void bch2_print_string_as_lines(const char *prefix, const char *lines) 267 266 { 268 267 bool locked = false; 269 268 const char *p; ··· 272 273 return; 273 274 } 274 275 275 - if (!nonblocking) { 276 - console_lock(); 277 - locked = true; 278 - } else { 279 - locked = console_trylock(); 280 - } 276 + locked = console_trylock(); 281 277 282 278 while (*lines) { 283 279 p = strchrnul(lines, '\n');
+1 -1
fs/bcachefs/util.h
··· 214 214 void bch2_prt_u64_base2_nbits(struct printbuf *, u64, unsigned); 215 215 void bch2_prt_u64_base2(struct printbuf *, u64); 216 216 217 - void bch2_print_string_as_lines(const char *, const char *, bool); 217 + void bch2_print_string_as_lines(const char *, const char *); 218 218 219 219 typedef DARRAY(unsigned long) bch_stacktrace; 220 220 int bch2_save_backtrace(bch_stacktrace *stack, struct task_struct *, unsigned, gfp_t);