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

Merge tag 'bcachefs-2024-03-19' of https://evilpiepirate.org/git/bcachefs

Pull bcachefs fixes from Kent Overstreet:
"Assorted bugfixes.

Most are fixes for simple assertion pops; the most significant fix is
for a deadlock in recovery when we have to rewrite large numbers of
btree nodes to fix errors. This was incorrectly running out of the
same workqueue as the core interior btree update path - we now give it
its own single threaded workqueue.

This was visible to users as "bch2_btree_update_start(): error:
BCH_ERR_journal_reclaim_would_deadlock" - and then recovery hanging"

* tag 'bcachefs-2024-03-19' of https://evilpiepirate.org/git/bcachefs:
bcachefs: Fix lost wakeup on journal shutdown
bcachefs; Fix deadlock in bch2_btree_update_start()
bcachefs: ratelimit errors from async_btree_node_rewrite
bcachefs: Run check_topology() first
bcachefs: Improve bch2_fatal_error()
bcachefs: Fix lost transaction restart error
bcachefs: Don't corrupt journal keys gap buffer when dropping alloc info
bcachefs: fix for building in userspace
bcachefs: bch2_snapshot_is_ancestor() now safe to call in early recovery
bcachefs: Fix nested transaction restart handling in bch2_bucket_gens_init()
bcachefs: Improve sysfs internal/btree_updates
bcachefs: Split out btree_node_rewrite_worker
bcachefs: Fix locking in bch2_alloc_write_key()
bcachefs: Avoid extent entry type assertions in .invalid()
bcachefs: Fix spurious -BCH_ERR_transaction_restart_nested
bcachefs: Fix check_key_has_snapshot() call
bcachefs: Change "accounting overran journal reservation" to a warning

+157 -111
+8 -7
fs/bcachefs/alloc_background.c
··· 532 532 u8 gen = bch2_alloc_to_v4(k, &a)->gen; 533 533 unsigned offset; 534 534 struct bpos pos = alloc_gens_pos(iter.pos, &offset); 535 + int ret2 = 0; 535 536 536 537 if (have_bucket_gens_key && bkey_cmp(iter.pos, pos)) { 537 - ret = commit_do(trans, NULL, NULL, 538 - BCH_TRANS_COMMIT_no_enospc, 539 - bch2_btree_insert_trans(trans, BTREE_ID_bucket_gens, &g.k_i, 0)); 540 - if (ret) 541 - break; 538 + ret2 = bch2_btree_insert_trans(trans, BTREE_ID_bucket_gens, &g.k_i, 0) ?: 539 + bch2_trans_commit(trans, NULL, NULL, BCH_TRANS_COMMIT_no_enospc); 540 + if (ret2) 541 + goto iter_err; 542 542 have_bucket_gens_key = false; 543 543 } 544 544 ··· 549 549 } 550 550 551 551 g.v.gens[offset] = gen; 552 - 0; 552 + iter_err: 553 + ret2; 553 554 })); 554 555 555 556 if (have_bucket_gens_key && !ret) ··· 853 852 bucket_journal_seq); 854 853 if (ret) { 855 854 bch2_fs_fatal_error(c, 856 - "error setting bucket_needs_journal_commit: %i", ret); 855 + "setting bucket_needs_journal_commit: %s", bch2_err_str(ret)); 857 856 return ret; 858 857 } 859 858 }
+6 -4
fs/bcachefs/alloc_foreground.c
··· 1356 1356 1357 1357 /* Don't retry from all devices if we're out of open buckets: */ 1358 1358 if (bch2_err_matches(ret, BCH_ERR_open_buckets_empty)) { 1359 - int ret = open_bucket_add_buckets(trans, &ptrs, wp, devs_have, 1359 + int ret2 = open_bucket_add_buckets(trans, &ptrs, wp, devs_have, 1360 1360 target, erasure_code, 1361 1361 nr_replicas, &nr_effective, 1362 1362 &have_cache, watermark, 1363 1363 flags, cl); 1364 - if (!ret || 1365 - bch2_err_matches(ret, BCH_ERR_transaction_restart) || 1366 - bch2_err_matches(ret, BCH_ERR_open_buckets_empty)) 1364 + if (!ret2 || 1365 + bch2_err_matches(ret2, BCH_ERR_transaction_restart) || 1366 + bch2_err_matches(ret2, BCH_ERR_open_buckets_empty)) { 1367 + ret = ret2; 1367 1368 goto alloc_done; 1369 + } 1368 1370 } 1369 1371 1370 1372 /*
+2
fs/bcachefs/bcachefs.h
··· 849 849 struct workqueue_struct *btree_interior_update_worker; 850 850 struct work_struct btree_interior_update_work; 851 851 852 + struct workqueue_struct *btree_node_rewrite_worker; 853 + 852 854 struct list_head pending_node_rewrites; 853 855 struct mutex pending_node_rewrites_lock; 854 856
+1 -1
fs/bcachefs/btree_gc.c
··· 1392 1392 *old, 1393 1393 b->data_type); 1394 1394 gc = *b; 1395 - percpu_up_read(&c->mark_lock); 1396 1395 1397 1396 if (gc.data_type != old_gc.data_type || 1398 1397 gc.dirty_sectors != old_gc.dirty_sectors) 1399 1398 bch2_dev_usage_update_m(c, ca, &old_gc, &gc); 1399 + percpu_up_read(&c->mark_lock); 1400 1400 1401 1401 if (metadata_only && 1402 1402 gc.data_type != BCH_DATA_sb &&
+6 -6
fs/bcachefs/btree_io.c
··· 1066 1066 1067 1067 ret = bset_encrypt(c, i, b->written << 9); 1068 1068 if (bch2_fs_fatal_err_on(ret, c, 1069 - "error decrypting btree node: %i", ret)) 1069 + "decrypting btree node: %s", bch2_err_str(ret))) 1070 1070 goto fsck_err; 1071 1071 1072 1072 btree_err_on(btree_node_type_is_extents(btree_node_type(b)) && ··· 1107 1107 1108 1108 ret = bset_encrypt(c, i, b->written << 9); 1109 1109 if (bch2_fs_fatal_err_on(ret, c, 1110 - "error decrypting btree node: %i\n", ret)) 1110 + "decrypting btree node: %s", bch2_err_str(ret))) 1111 1111 goto fsck_err; 1112 1112 1113 1113 sectors = vstruct_sectors(bne, c->block_bits); ··· 1338 1338 if (saw_error && !btree_node_read_error(b)) { 1339 1339 printbuf_reset(&buf); 1340 1340 bch2_bpos_to_text(&buf, b->key.k.p); 1341 - bch_info(c, "%s: rewriting btree node at btree=%s level=%u %s due to error", 1341 + bch_err_ratelimited(c, "%s: rewriting btree node at btree=%s level=%u %s due to error", 1342 1342 __func__, bch2_btree_id_str(b->c.btree_id), b->c.level, buf.buf); 1343 1343 1344 1344 bch2_btree_node_rewrite_async(c, b); ··· 1874 1874 return; 1875 1875 err: 1876 1876 set_btree_node_noevict(b); 1877 - if (!bch2_err_matches(ret, EROFS)) 1878 - bch2_fs_fatal_error(c, "fatal error writing btree node: %s", bch2_err_str(ret)); 1877 + bch2_fs_fatal_err_on(!bch2_err_matches(ret, EROFS), c, 1878 + "writing btree node: %s", bch2_err_str(ret)); 1879 1879 goto out; 1880 1880 } 1881 1881 ··· 2131 2131 2132 2132 ret = bset_encrypt(c, i, b->written << 9); 2133 2133 if (bch2_fs_fatal_err_on(ret, c, 2134 - "error encrypting btree node: %i\n", ret)) 2134 + "encrypting btree node: %s", bch2_err_str(ret))) 2135 2135 goto err; 2136 2136 2137 2137 nonce = btree_nonce(i, b->written << 9);
+1 -1
fs/bcachefs/btree_key_cache.c
··· 676 676 !bch2_err_matches(ret, BCH_ERR_transaction_restart) && 677 677 !bch2_err_matches(ret, BCH_ERR_journal_reclaim_would_deadlock) && 678 678 !bch2_journal_error(j), c, 679 - "error flushing key cache: %s", bch2_err_str(ret)); 679 + "flushing key cache: %s", bch2_err_str(ret)); 680 680 if (ret) 681 681 goto out; 682 682
+29 -15
fs/bcachefs/btree_update_interior.c
··· 646 646 bch2_trans_unlock(trans); 647 647 648 648 bch2_fs_fatal_err_on(ret && !bch2_journal_error(&c->journal), c, 649 - "%s(): error %s", __func__, bch2_err_str(ret)); 649 + "%s", bch2_err_str(ret)); 650 650 err: 651 651 if (as->b) { 652 652 ··· 1067 1067 flags &= ~BCH_WATERMARK_MASK; 1068 1068 flags |= watermark; 1069 1069 1070 - if (!(flags & BCH_TRANS_COMMIT_journal_reclaim) && 1071 - watermark < c->journal.watermark) { 1070 + if (watermark < c->journal.watermark) { 1072 1071 struct journal_res res = { 0 }; 1072 + unsigned journal_flags = watermark|JOURNAL_RES_GET_CHECK; 1073 + 1074 + if ((flags & BCH_TRANS_COMMIT_journal_reclaim) && 1075 + watermark != BCH_WATERMARK_reclaim) 1076 + journal_flags |= JOURNAL_RES_GET_NONBLOCK; 1073 1077 1074 1078 ret = drop_locks_do(trans, 1075 - bch2_journal_res_get(&c->journal, &res, 1, 1076 - watermark|JOURNAL_RES_GET_CHECK)); 1079 + bch2_journal_res_get(&c->journal, &res, 1, journal_flags)); 1080 + if (bch2_err_matches(ret, BCH_ERR_operation_blocked)) 1081 + ret = -BCH_ERR_journal_reclaim_would_deadlock; 1077 1082 if (ret) 1078 1083 return ERR_PTR(ret); 1079 1084 } ··· 1122 1117 closure_init(&as->cl, NULL); 1123 1118 as->c = c; 1124 1119 as->start_time = start_time; 1120 + as->ip_started = _RET_IP_; 1125 1121 as->mode = BTREE_INTERIOR_NO_UPDATE; 1126 1122 as->took_gc_lock = true; 1127 1123 as->btree_id = path->btree_id; ··· 1198 1192 err: 1199 1193 bch2_btree_update_free(as, trans); 1200 1194 if (!bch2_err_matches(ret, ENOSPC) && 1201 - !bch2_err_matches(ret, EROFS)) 1195 + !bch2_err_matches(ret, EROFS) && 1196 + ret != -BCH_ERR_journal_reclaim_would_deadlock) 1202 1197 bch_err_fn_ratelimited(c, ret); 1203 1198 return ERR_PTR(ret); 1204 1199 } ··· 2121 2114 2122 2115 ret = bch2_trans_do(c, NULL, NULL, 0, 2123 2116 async_btree_node_rewrite_trans(trans, a)); 2124 - bch_err_fn(c, ret); 2117 + bch_err_fn_ratelimited(c, ret); 2125 2118 bch2_write_ref_put(c, BCH_WRITE_REF_node_rewrite); 2126 2119 kfree(a); 2127 2120 } ··· 2168 2161 bch2_write_ref_get(c, BCH_WRITE_REF_node_rewrite); 2169 2162 } 2170 2163 2171 - queue_work(c->btree_interior_update_worker, &a->work); 2164 + queue_work(c->btree_node_rewrite_worker, &a->work); 2172 2165 } 2173 2166 2174 2167 void bch2_do_pending_node_rewrites(struct bch_fs *c) ··· 2180 2173 list_del(&a->list); 2181 2174 2182 2175 bch2_write_ref_get(c, BCH_WRITE_REF_node_rewrite); 2183 - queue_work(c->btree_interior_update_worker, &a->work); 2176 + queue_work(c->btree_node_rewrite_worker, &a->work); 2184 2177 } 2185 2178 mutex_unlock(&c->pending_node_rewrites_lock); 2186 2179 } ··· 2448 2441 2449 2442 mutex_lock(&c->btree_interior_update_lock); 2450 2443 list_for_each_entry(as, &c->btree_interior_update_list, list) 2451 - prt_printf(out, "%p m %u w %u r %u j %llu\n", 2452 - as, 2453 - as->mode, 2454 - as->nodes_written, 2455 - closure_nr_remaining(&as->cl), 2456 - as->journal.seq); 2444 + prt_printf(out, "%ps: mode=%u nodes_written=%u cl.remaining=%u journal_seq=%llu\n", 2445 + (void *) as->ip_started, 2446 + as->mode, 2447 + as->nodes_written, 2448 + closure_nr_remaining(&as->cl), 2449 + as->journal.seq); 2457 2450 mutex_unlock(&c->btree_interior_update_lock); 2458 2451 } 2459 2452 ··· 2517 2510 2518 2511 void bch2_fs_btree_interior_update_exit(struct bch_fs *c) 2519 2512 { 2513 + if (c->btree_node_rewrite_worker) 2514 + destroy_workqueue(c->btree_node_rewrite_worker); 2520 2515 if (c->btree_interior_update_worker) 2521 2516 destroy_workqueue(c->btree_interior_update_worker); 2522 2517 mempool_exit(&c->btree_interior_update_pool); ··· 2541 2532 c->btree_interior_update_worker = 2542 2533 alloc_workqueue("btree_update", WQ_UNBOUND|WQ_MEM_RECLAIM, 8); 2543 2534 if (!c->btree_interior_update_worker) 2535 + return -BCH_ERR_ENOMEM_btree_interior_update_worker_init; 2536 + 2537 + c->btree_node_rewrite_worker = 2538 + alloc_ordered_workqueue("btree_node_rewrite", WQ_UNBOUND); 2539 + if (!c->btree_node_rewrite_worker) 2544 2540 return -BCH_ERR_ENOMEM_btree_interior_update_worker_init; 2545 2541 2546 2542 if (mempool_init_kmalloc_pool(&c->btree_interior_update_pool, 1,
+1
fs/bcachefs/btree_update_interior.h
··· 32 32 struct closure cl; 33 33 struct bch_fs *c; 34 34 u64 start_time; 35 + unsigned long ip_started; 35 36 36 37 struct list_head list; 37 38 struct list_head unwritten_list;
+1 -1
fs/bcachefs/btree_write_buffer.c
··· 378 378 } 379 379 } 380 380 err: 381 - bch2_fs_fatal_err_on(ret, c, "%s: insert error %s", __func__, bch2_err_str(ret)); 381 + bch2_fs_fatal_err_on(ret, c, "%s", bch2_err_str(ret)); 382 382 trace_write_buffer_flush(trans, wb->flushing.keys.nr, skipped, fast, 0); 383 383 bch2_journal_pin_drop(j, &wb->flushing.pin); 384 384 wb->flushing.keys.nr = 0;
+3 -3
fs/bcachefs/buckets.c
··· 990 990 ret = !gc 991 991 ? bch2_update_cached_sectors_list(trans, p.ptr.dev, disk_sectors) 992 992 : update_cached_sectors(c, k, p.ptr.dev, disk_sectors, 0, true); 993 - bch2_fs_fatal_err_on(ret && gc, c, "%s(): no replicas entry while updating cached sectors", 994 - __func__); 993 + bch2_fs_fatal_err_on(ret && gc, c, "%s: no replicas entry while updating cached sectors", 994 + bch2_err_str(ret)); 995 995 if (ret) 996 996 return ret; 997 997 } ··· 1020 1020 struct printbuf buf = PRINTBUF; 1021 1021 1022 1022 bch2_bkey_val_to_text(&buf, c, k); 1023 - bch2_fs_fatal_error(c, "%s(): no replicas entry for %s", __func__, buf.buf); 1023 + bch2_fs_fatal_error(c, ": no replicas entry for %s", buf.buf); 1024 1024 printbuf_exit(&buf); 1025 1025 } 1026 1026 if (ret)
+1 -1
fs/bcachefs/debug.c
··· 170 170 struct printbuf buf = PRINTBUF; 171 171 172 172 bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&b->key)); 173 - bch2_fs_fatal_error(c, "btree node verify failed for : %s\n", buf.buf); 173 + bch2_fs_fatal_error(c, ": btree node verify failed for: %s\n", buf.buf); 174 174 printbuf_exit(&buf); 175 175 } 176 176 out:
+3 -3
fs/bcachefs/ec.c
··· 448 448 struct printbuf buf = PRINTBUF; 449 449 450 450 bch2_bkey_val_to_text(&buf, c, new); 451 - bch2_fs_fatal_error(c, "no replicas entry for %s", buf.buf); 451 + bch2_fs_fatal_error(c, ": no replicas entry for %s", buf.buf); 452 452 printbuf_exit(&buf); 453 453 return ret; 454 454 } ··· 1868 1868 return -BCH_ERR_stripe_alloc_blocked; 1869 1869 1870 1870 ret = get_stripe_key_trans(trans, idx, &h->s->existing_stripe); 1871 + bch2_fs_fatal_err_on(ret && !bch2_err_matches(ret, BCH_ERR_transaction_restart), c, 1872 + "reading stripe key: %s", bch2_err_str(ret)); 1871 1873 if (ret) { 1872 1874 bch2_stripe_close(c, h->s); 1873 - if (!bch2_err_matches(ret, BCH_ERR_transaction_restart)) 1874 - bch2_fs_fatal_error(c, "error reading stripe key: %s", bch2_err_str(ret)); 1875 1875 return ret; 1876 1876 } 1877 1877
+2 -2
fs/bcachefs/error.h
··· 191 191 192 192 void bch2_fatal_error(struct bch_fs *); 193 193 194 - #define bch2_fs_fatal_error(c, ...) \ 194 + #define bch2_fs_fatal_error(c, _msg, ...) \ 195 195 do { \ 196 - bch_err(c, __VA_ARGS__); \ 196 + bch_err(c, "%s(): fatal error " _msg, __func__, ##__VA_ARGS__); \ 197 197 bch2_fatal_error(c); \ 198 198 } while (0) 199 199
+3 -3
fs/bcachefs/extents.h
··· 108 108 109 109 static inline bool extent_entry_is_ptr(const union bch_extent_entry *e) 110 110 { 111 - return extent_entry_type(e) == BCH_EXTENT_ENTRY_ptr; 111 + return __extent_entry_type(e) == BCH_EXTENT_ENTRY_ptr; 112 112 } 113 113 114 114 static inline bool extent_entry_is_stripe_ptr(const union bch_extent_entry *e) 115 115 { 116 - return extent_entry_type(e) == BCH_EXTENT_ENTRY_stripe_ptr; 116 + return __extent_entry_type(e) == BCH_EXTENT_ENTRY_stripe_ptr; 117 117 } 118 118 119 119 static inline bool extent_entry_is_crc(const union bch_extent_entry *e) 120 120 { 121 - switch (extent_entry_type(e)) { 121 + switch (__extent_entry_type(e)) { 122 122 case BCH_EXTENT_ENTRY_crc32: 123 123 case BCH_EXTENT_ENTRY_crc64: 124 124 case BCH_EXTENT_ENTRY_crc128:
+2 -1
fs/bcachefs/fs.c
··· 108 108 goto retry; 109 109 110 110 bch2_fs_fatal_err_on(bch2_err_matches(ret, ENOENT), c, 111 - "inode %u:%llu not found when updating", 111 + "%s: inode %u:%llu not found when updating", 112 + bch2_err_str(ret), 112 113 inode_inum(inode).subvol, 113 114 inode_inum(inode).inum); 114 115
+24 -9
fs/bcachefs/fsck.c
··· 1114 1114 return ret; 1115 1115 } 1116 1116 1117 - static int check_i_sectors(struct btree_trans *trans, struct inode_walker *w) 1117 + static int check_i_sectors_notnested(struct btree_trans *trans, struct inode_walker *w) 1118 1118 { 1119 1119 struct bch_fs *c = trans->c; 1120 - u32 restart_count = trans->restart_count; 1121 1120 int ret = 0; 1122 1121 s64 count2; 1123 1122 ··· 1148 1149 } 1149 1150 fsck_err: 1150 1151 bch_err_fn(c, ret); 1151 - return ret ?: trans_was_restarted(trans, restart_count); 1152 + return ret; 1153 + } 1154 + 1155 + static int check_i_sectors(struct btree_trans *trans, struct inode_walker *w) 1156 + { 1157 + u32 restart_count = trans->restart_count; 1158 + return check_i_sectors_notnested(trans, w) ?: 1159 + trans_was_restarted(trans, restart_count); 1152 1160 } 1153 1161 1154 1162 struct extent_end { ··· 1539 1533 check_extent(trans, &iter, k, &w, &s, &extent_ends) ?: 1540 1534 check_extent_overbig(trans, &iter, k); 1541 1535 })) ?: 1542 - check_i_sectors(trans, &w)); 1536 + check_i_sectors_notnested(trans, &w)); 1543 1537 1544 1538 bch2_disk_reservation_put(c, &res); 1545 1539 extent_ends_exit(&extent_ends); ··· 1569 1563 return ret; 1570 1564 } 1571 1565 1572 - static int check_subdir_count(struct btree_trans *trans, struct inode_walker *w) 1566 + static int check_subdir_count_notnested(struct btree_trans *trans, struct inode_walker *w) 1573 1567 { 1574 1568 struct bch_fs *c = trans->c; 1575 - u32 restart_count = trans->restart_count; 1576 1569 int ret = 0; 1577 1570 s64 count2; 1578 1571 ··· 1603 1598 } 1604 1599 fsck_err: 1605 1600 bch_err_fn(c, ret); 1606 - return ret ?: trans_was_restarted(trans, restart_count); 1601 + return ret; 1602 + } 1603 + 1604 + static int check_subdir_count(struct btree_trans *trans, struct inode_walker *w) 1605 + { 1606 + u32 restart_count = trans->restart_count; 1607 + return check_subdir_count_notnested(trans, w) ?: 1608 + trans_was_restarted(trans, restart_count); 1607 1609 } 1608 1610 1609 1611 static int check_dirent_inode_dirent(struct btree_trans *trans, ··· 2015 2003 k, 2016 2004 NULL, NULL, 2017 2005 BCH_TRANS_COMMIT_no_enospc, 2018 - check_dirent(trans, &iter, k, &hash_info, &dir, &target, &s))); 2006 + check_dirent(trans, &iter, k, &hash_info, &dir, &target, &s)) ?: 2007 + check_subdir_count_notnested(trans, &dir)); 2019 2008 2020 2009 snapshots_seen_exit(&s); 2021 2010 inode_walker_exit(&dir); ··· 2035 2022 int ret; 2036 2023 2037 2024 ret = check_key_has_snapshot(trans, iter, k); 2038 - if (ret) 2025 + if (ret < 0) 2039 2026 return ret; 2027 + if (ret) 2028 + return 0; 2040 2029 2041 2030 i = walk_inode(trans, inode, k); 2042 2031 ret = PTR_ERR_OR_ZERO(i);
+6 -6
fs/bcachefs/journal.c
··· 511 511 if (journal_res_get_fast(j, res, flags)) 512 512 return 0; 513 513 514 + if (bch2_journal_error(j)) 515 + return -BCH_ERR_erofs_journal_err; 516 + 517 + if (j->blocked) 518 + return -BCH_ERR_journal_res_get_blocked; 519 + 514 520 if ((flags & BCH_WATERMARK_MASK) < j->watermark) { 515 521 ret = JOURNAL_ERR_journal_full; 516 522 can_discard = j->can_discard; 517 523 goto out; 518 524 } 519 - 520 - if (j->blocked) 521 - return -BCH_ERR_journal_res_get_blocked; 522 - 523 - if (bch2_journal_error(j)) 524 - return -BCH_ERR_erofs_journal_err; 525 525 526 526 if (nr_unwritten_journal_entries(j) == ARRAY_SIZE(j->buf) && !journal_entry_is_open(j)) { 527 527 ret = JOURNAL_ERR_max_in_flight;
+7 -8
fs/bcachefs/journal_io.c
··· 1082 1082 ret = bch2_encrypt(c, JSET_CSUM_TYPE(j), journal_nonce(j), 1083 1083 j->encrypted_start, 1084 1084 vstruct_end(j) - (void *) j->encrypted_start); 1085 - bch2_fs_fatal_err_on(ret, c, 1086 - "error decrypting journal entry: %s", 1087 - bch2_err_str(ret)); 1085 + bch2_fs_fatal_err_on(ret, c, "decrypting journal entry: %s", bch2_err_str(ret)); 1088 1086 1089 1087 mutex_lock(&jlist->lock); 1090 1088 ret = journal_entry_add(c, ca, (struct journal_ptr) { ··· 1818 1820 jset_entry_for_each_key(i, k) { 1819 1821 ret = bch2_journal_key_to_wb(c, &wb, i->btree_id, k); 1820 1822 if (ret) { 1821 - bch2_fs_fatal_error(c, "-ENOMEM flushing journal keys to btree write buffer"); 1823 + bch2_fs_fatal_error(c, "flushing journal keys to btree write buffer: %s", 1824 + bch2_err_str(ret)); 1822 1825 bch2_journal_keys_to_write_buffer_end(c, &wb); 1823 1826 return ret; 1824 1827 } ··· 1847 1848 1848 1849 bch2_journal_super_entries_add_common(c, &end, seq); 1849 1850 u64s = (u64 *) end - (u64 *) start; 1850 - BUG_ON(u64s > j->entry_u64s_reserved); 1851 + 1852 + WARN_ON(u64s > j->entry_u64s_reserved); 1851 1853 1852 1854 le32_add_cpu(&jset->u64s, u64s); 1853 1855 ··· 1856 1856 bytes = vstruct_bytes(jset); 1857 1857 1858 1858 if (sectors > w->sectors) { 1859 - bch2_fs_fatal_error(c, "aieeee! journal write overran available space, %zu > %u (extra %u reserved %u/%u)", 1859 + bch2_fs_fatal_error(c, ": journal write overran available space, %zu > %u (extra %u reserved %u/%u)", 1860 1860 vstruct_bytes(jset), w->sectors << 9, 1861 1861 u64s, w->u64s_reserved, j->entry_u64s_reserved); 1862 1862 return -EINVAL; ··· 1884 1884 ret = bch2_encrypt(c, JSET_CSUM_TYPE(jset), journal_nonce(jset), 1885 1885 jset->encrypted_start, 1886 1886 vstruct_end(jset) - (void *) jset->encrypted_start); 1887 - if (bch2_fs_fatal_err_on(ret, c, 1888 - "error decrypting journal entry: %i", ret)) 1887 + if (bch2_fs_fatal_err_on(ret, c, "decrypting journal entry: %s", bch2_err_str(ret))) 1889 1888 return ret; 1890 1889 1891 1890 jset->csum = csum_vstruct(c, JSET_CSUM_TYPE(jset),
+2 -2
fs/bcachefs/logged_ops.c
··· 101 101 struct printbuf buf = PRINTBUF; 102 102 103 103 bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(k)); 104 - bch2_fs_fatal_error(c, "%s: error deleting logged operation %s: %s", 105 - __func__, buf.buf, bch2_err_str(ret)); 104 + bch2_fs_fatal_error(c, "deleting logged operation %s: %s", 105 + buf.buf, bch2_err_str(ret)); 106 106 printbuf_exit(&buf); 107 107 } 108 108 }
+1 -2
fs/bcachefs/movinggc.c
··· 155 155 if (bch2_err_matches(ret, EROFS)) 156 156 return ret; 157 157 158 - if (bch2_fs_fatal_err_on(ret, c, "%s: error %s from bch2_btree_write_buffer_tryflush()", 159 - __func__, bch2_err_str(ret))) 158 + if (bch2_fs_fatal_err_on(ret, c, "%s: from bch2_btree_write_buffer_tryflush()", bch2_err_str(ret))) 160 159 return ret; 161 160 162 161 ret = for_each_btree_key_upto(trans, iter, BTREE_ID_lru,
+5 -1
fs/bcachefs/recovery.c
··· 90 90 struct journal_keys *keys = &c->journal_keys; 91 91 size_t src, dst; 92 92 93 + move_gap(keys, keys->nr); 94 + 93 95 for (src = 0, dst = 0; src < keys->nr; src++) 94 96 if (!btree_id_is_alloc(keys->data[src].btree_id)) 95 97 keys->data[dst++] = keys->data[src]; 96 - keys->nr = dst; 98 + keys->nr = keys->gap = dst; 97 99 } 98 100 99 101 /* ··· 204 202 } 205 203 206 204 BUG_ON(!atomic_read(&keys->ref)); 205 + 206 + move_gap(keys, keys->nr); 207 207 208 208 /* 209 209 * First, attempt to replay keys in sorted order. This is more
+1 -1
fs/bcachefs/recovery_types.h
··· 13 13 * must never change: 14 14 */ 15 15 #define BCH_RECOVERY_PASSES() \ 16 + x(check_topology, 4, 0) \ 16 17 x(alloc_read, 0, PASS_ALWAYS) \ 17 18 x(stripes_read, 1, PASS_ALWAYS) \ 18 19 x(initialize_subvolumes, 2, 0) \ 19 20 x(snapshots_read, 3, PASS_ALWAYS) \ 20 - x(check_topology, 4, 0) \ 21 21 x(check_allocations, 5, PASS_FSCK) \ 22 22 x(trans_mark_dev_sbs, 6, PASS_ALWAYS|PASS_SILENT) \ 23 23 x(fs_journal_alloc, 7, PASS_ALWAYS|PASS_SILENT) \
+18 -14
fs/bcachefs/snapshot.c
··· 91 91 92 92 /* Snapshot nodes: */ 93 93 94 - static bool bch2_snapshot_is_ancestor_early(struct bch_fs *c, u32 id, u32 ancestor) 94 + static bool __bch2_snapshot_is_ancestor_early(struct snapshot_table *t, u32 id, u32 ancestor) 95 95 { 96 - struct snapshot_table *t; 97 - 98 - rcu_read_lock(); 99 - t = rcu_dereference(c->snapshots); 100 - 101 96 while (id && id < ancestor) 102 97 id = __snapshot_t(t, id)->parent; 98 + return id == ancestor; 99 + } 100 + 101 + static bool bch2_snapshot_is_ancestor_early(struct bch_fs *c, u32 id, u32 ancestor) 102 + { 103 + rcu_read_lock(); 104 + bool ret = __bch2_snapshot_is_ancestor_early(rcu_dereference(c->snapshots), id, ancestor); 103 105 rcu_read_unlock(); 104 106 105 - return id == ancestor; 107 + return ret; 106 108 } 107 109 108 110 static inline u32 get_ancestor_below(struct snapshot_table *t, u32 id, u32 ancestor) ··· 122 120 123 121 bool __bch2_snapshot_is_ancestor(struct bch_fs *c, u32 id, u32 ancestor) 124 122 { 125 - struct snapshot_table *t; 126 123 bool ret; 127 124 128 - EBUG_ON(c->recovery_pass_done <= BCH_RECOVERY_PASS_check_snapshots); 129 - 130 125 rcu_read_lock(); 131 - t = rcu_dereference(c->snapshots); 126 + struct snapshot_table *t = rcu_dereference(c->snapshots); 127 + 128 + if (unlikely(c->recovery_pass_done <= BCH_RECOVERY_PASS_check_snapshots)) { 129 + ret = __bch2_snapshot_is_ancestor_early(t, id, ancestor); 130 + goto out; 131 + } 132 132 133 133 while (id && id < ancestor - IS_ANCESTOR_BITMAP) 134 134 id = get_ancestor_below(t, id, ancestor); ··· 138 134 if (id && id < ancestor) { 139 135 ret = test_bit(ancestor - id - 1, __snapshot_t(t, id)->is_ancestor); 140 136 141 - EBUG_ON(ret != bch2_snapshot_is_ancestor_early(c, id, ancestor)); 137 + EBUG_ON(ret != __bch2_snapshot_is_ancestor_early(t, id, ancestor)); 142 138 } else { 143 139 ret = id == ancestor; 144 140 } 145 - 141 + out: 146 142 rcu_read_unlock(); 147 143 148 144 return ret; ··· 551 547 "snapshot tree points to missing subvolume:\n %s", 552 548 (printbuf_reset(&buf), 553 549 bch2_bkey_val_to_text(&buf, c, st.s_c), buf.buf)) || 554 - fsck_err_on(!bch2_snapshot_is_ancestor_early(c, 550 + fsck_err_on(!bch2_snapshot_is_ancestor(c, 555 551 le32_to_cpu(subvol.snapshot), 556 552 root_id), 557 553 c, snapshot_tree_to_wrong_subvol,
+4 -4
fs/bcachefs/super-io.c
··· 985 985 prt_str(&buf, " > "); 986 986 bch2_version_to_text(&buf, bcachefs_metadata_version_current); 987 987 prt_str(&buf, ")"); 988 - bch2_fs_fatal_error(c, "%s", buf.buf); 988 + bch2_fs_fatal_error(c, ": %s", buf.buf); 989 989 printbuf_exit(&buf); 990 990 return -BCH_ERR_sb_not_downgraded; 991 991 } ··· 1005 1005 1006 1006 if (le64_to_cpu(ca->sb_read_scratch->seq) < ca->disk_sb.seq) { 1007 1007 bch2_fs_fatal_error(c, 1008 - "Superblock write was silently dropped! (seq %llu expected %llu)", 1008 + ": Superblock write was silently dropped! (seq %llu expected %llu)", 1009 1009 le64_to_cpu(ca->sb_read_scratch->seq), 1010 1010 ca->disk_sb.seq); 1011 1011 percpu_ref_put(&ca->io_ref); ··· 1015 1015 1016 1016 if (le64_to_cpu(ca->sb_read_scratch->seq) > ca->disk_sb.seq) { 1017 1017 bch2_fs_fatal_error(c, 1018 - "Superblock modified by another process (seq %llu expected %llu)", 1018 + ": Superblock modified by another process (seq %llu expected %llu)", 1019 1019 le64_to_cpu(ca->sb_read_scratch->seq), 1020 1020 ca->disk_sb.seq); 1021 1021 percpu_ref_put(&ca->io_ref); ··· 1066 1066 !can_mount_with_written || 1067 1067 (can_mount_without_written && 1068 1068 !can_mount_with_written), c, 1069 - "Unable to write superblock to sufficient devices (from %ps)", 1069 + ": Unable to write superblock to sufficient devices (from %ps)", 1070 1070 (void *) _RET_IP_)) 1071 1071 ret = -1; 1072 1072 out:
+17 -16
fs/bcachefs/super.c
··· 87 87 NULL 88 88 }; 89 89 90 + __printf(2, 0) 91 + static void bch2_print_maybe_redirect(struct stdio_redirect *stdio, const char *fmt, va_list args) 92 + { 93 + #ifdef __KERNEL__ 94 + if (unlikely(stdio)) { 95 + if (fmt[0] == KERN_SOH[0]) 96 + fmt += 2; 97 + 98 + bch2_stdio_redirect_vprintf(stdio, true, fmt, args); 99 + return; 100 + } 101 + #endif 102 + vprintk(fmt, args); 103 + } 104 + 90 105 void bch2_print_opts(struct bch_opts *opts, const char *fmt, ...) 91 106 { 92 107 struct stdio_redirect *stdio = (void *)(unsigned long)opts->stdio; 93 108 94 109 va_list args; 95 110 va_start(args, fmt); 96 - if (likely(!stdio)) { 97 - vprintk(fmt, args); 98 - } else { 99 - if (fmt[0] == KERN_SOH[0]) 100 - fmt += 2; 101 - 102 - bch2_stdio_redirect_vprintf(stdio, true, fmt, args); 103 - } 111 + bch2_print_maybe_redirect(stdio, fmt, args); 104 112 va_end(args); 105 113 } 106 114 ··· 118 110 119 111 va_list args; 120 112 va_start(args, fmt); 121 - if (likely(!stdio)) { 122 - vprintk(fmt, args); 123 - } else { 124 - if (fmt[0] == KERN_SOH[0]) 125 - fmt += 2; 126 - 127 - bch2_stdio_redirect_vprintf(stdio, true, fmt, args); 128 - } 113 + bch2_print_maybe_redirect(stdio, fmt, args); 129 114 va_end(args); 130 115 } 131 116
+3
fs/bcachefs/util.h
··· 683 683 /* Move the gap in a gap buffer: */ 684 684 #define move_gap(_d, _new_gap) \ 685 685 do { \ 686 + BUG_ON(_new_gap > (_d)->nr); \ 687 + BUG_ON((_d)->gap > (_d)->nr); \ 688 + \ 686 689 __move_gap((_d)->data, sizeof((_d)->data[0]), \ 687 690 (_d)->nr, (_d)->size, (_d)->gap, _new_gap); \ 688 691 (_d)->gap = _new_gap; \