1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Assorted bcachefs debug code 4 * 5 * Copyright 2010, 2011 Kent Overstreet <kent.overstreet@gmail.com> 6 * Copyright 2012 Google, Inc. 7 */ 8 9 #include "bcachefs.h" 10 #include "bkey_methods.h" 11 #include "btree_cache.h" 12 #include "btree_io.h" 13 #include "btree_iter.h" 14 #include "btree_locking.h" 15 #include "btree_update.h" 16 #include "buckets.h" 17 #include "debug.h" 18 #include "error.h" 19 #include "extents.h" 20 #include "fsck.h" 21 #include "inode.h" 22 #include "super.h" 23 24 #include <linux/console.h> 25 #include <linux/debugfs.h> 26 #include <linux/module.h> 27 #include <linux/random.h> 28 #include <linux/seq_file.h> 29 30 static struct dentry *bch_debug; 31 32 static bool bch2_btree_verify_replica(struct bch_fs *c, struct btree *b, 33 struct extent_ptr_decoded pick) 34 { 35 struct btree *v = c->verify_data; 36 struct btree_node *n_ondisk = c->verify_ondisk; 37 struct btree_node *n_sorted = c->verify_data->data; 38 struct bset *sorted, *inmemory = &b->data->keys; 39 struct bch_dev *ca = bch_dev_bkey_exists(c, pick.ptr.dev); 40 struct bio *bio; 41 bool failed = false, saw_error = false; 42 43 if (!bch2_dev_get_ioref(ca, READ)) 44 return false; 45 46 bio = bio_alloc_bioset(ca->disk_sb.bdev, 47 buf_pages(n_sorted, btree_bytes(c)), 48 REQ_OP_READ|REQ_META, 49 GFP_NOFS, 50 &c->btree_bio); 51 bio->bi_iter.bi_sector = pick.ptr.offset; 52 bch2_bio_map(bio, n_sorted, btree_bytes(c)); 53 54 submit_bio_wait(bio); 55 56 bio_put(bio); 57 percpu_ref_put(&ca->io_ref); 58 59 memcpy(n_ondisk, n_sorted, btree_bytes(c)); 60 61 v->written = 0; 62 if (bch2_btree_node_read_done(c, ca, v, false, &saw_error) || saw_error) 63 return false; 64 65 n_sorted = c->verify_data->data; 66 sorted = &n_sorted->keys; 67 68 if (inmemory->u64s != sorted->u64s || 69 memcmp(inmemory->start, 70 sorted->start, 71 vstruct_end(inmemory) - (void *) inmemory->start)) { 72 unsigned offset = 0, sectors; 73 struct bset *i; 74 unsigned j; 75 76 console_lock(); 77 78 printk(KERN_ERR "*** in memory:\n"); 79 bch2_dump_bset(c, b, inmemory, 0); 80 81 printk(KERN_ERR "*** read back in:\n"); 82 bch2_dump_bset(c, v, sorted, 0); 83 84 while (offset < v->written) { 85 if (!offset) { 86 i = &n_ondisk->keys; 87 sectors = vstruct_blocks(n_ondisk, c->block_bits) << 88 c->block_bits; 89 } else { 90 struct btree_node_entry *bne = 91 (void *) n_ondisk + (offset << 9); 92 i = &bne->keys; 93 94 sectors = vstruct_blocks(bne, c->block_bits) << 95 c->block_bits; 96 } 97 98 printk(KERN_ERR "*** on disk block %u:\n", offset); 99 bch2_dump_bset(c, b, i, offset); 100 101 offset += sectors; 102 } 103 104 for (j = 0; j < le16_to_cpu(inmemory->u64s); j++) 105 if (inmemory->_data[j] != sorted->_data[j]) 106 break; 107 108 console_unlock(); 109 bch_err(c, "verify failed at key %u", j); 110 111 failed = true; 112 } 113 114 if (v->written != b->written) { 115 bch_err(c, "written wrong: expected %u, got %u", 116 b->written, v->written); 117 failed = true; 118 } 119 120 return failed; 121 } 122 123 void __bch2_btree_verify(struct bch_fs *c, struct btree *b) 124 { 125 struct bkey_ptrs_c ptrs; 126 struct extent_ptr_decoded p; 127 const union bch_extent_entry *entry; 128 struct btree *v; 129 struct bset *inmemory = &b->data->keys; 130 struct bkey_packed *k; 131 bool failed = false; 132 133 if (c->opts.nochanges) 134 return; 135 136 bch2_btree_node_io_lock(b); 137 mutex_lock(&c->verify_lock); 138 139 if (!c->verify_ondisk) { 140 c->verify_ondisk = kvpmalloc(btree_bytes(c), GFP_KERNEL); 141 if (!c->verify_ondisk) 142 goto out; 143 } 144 145 if (!c->verify_data) { 146 c->verify_data = __bch2_btree_node_mem_alloc(c); 147 if (!c->verify_data) 148 goto out; 149 150 list_del_init(&c->verify_data->list); 151 } 152 153 BUG_ON(b->nsets != 1); 154 155 for (k = inmemory->start; k != vstruct_last(inmemory); k = bkey_p_next(k)) 156 if (k->type == KEY_TYPE_btree_ptr_v2) 157 ((struct bch_btree_ptr_v2 *) bkeyp_val(&b->format, k))->mem_ptr = 0; 158 159 v = c->verify_data; 160 bkey_copy(&v->key, &b->key); 161 v->c.level = b->c.level; 162 v->c.btree_id = b->c.btree_id; 163 bch2_btree_keys_init(v); 164 165 ptrs = bch2_bkey_ptrs_c(bkey_i_to_s_c(&b->key)); 166 bkey_for_each_ptr_decode(&b->key.k, ptrs, p, entry) 167 failed |= bch2_btree_verify_replica(c, b, p); 168 169 if (failed) { 170 struct printbuf buf = PRINTBUF; 171 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); 174 printbuf_exit(&buf); 175 } 176 out: 177 mutex_unlock(&c->verify_lock); 178 bch2_btree_node_io_unlock(b); 179 } 180 181 void bch2_btree_node_ondisk_to_text(struct printbuf *out, struct bch_fs *c, 182 const struct btree *b) 183 { 184 struct btree_node *n_ondisk = NULL; 185 struct extent_ptr_decoded pick; 186 struct bch_dev *ca; 187 struct bio *bio = NULL; 188 unsigned offset = 0; 189 int ret; 190 191 if (bch2_bkey_pick_read_device(c, bkey_i_to_s_c(&b->key), NULL, &pick) <= 0) { 192 prt_printf(out, "error getting device to read from: invalid device\n"); 193 return; 194 } 195 196 ca = bch_dev_bkey_exists(c, pick.ptr.dev); 197 if (!bch2_dev_get_ioref(ca, READ)) { 198 prt_printf(out, "error getting device to read from: not online\n"); 199 return; 200 } 201 202 n_ondisk = kvpmalloc(btree_bytes(c), GFP_KERNEL); 203 if (!n_ondisk) { 204 prt_printf(out, "memory allocation failure\n"); 205 goto out; 206 } 207 208 bio = bio_alloc_bioset(ca->disk_sb.bdev, 209 buf_pages(n_ondisk, btree_bytes(c)), 210 REQ_OP_READ|REQ_META, 211 GFP_NOFS, 212 &c->btree_bio); 213 bio->bi_iter.bi_sector = pick.ptr.offset; 214 bch2_bio_map(bio, n_ondisk, btree_bytes(c)); 215 216 ret = submit_bio_wait(bio); 217 if (ret) { 218 prt_printf(out, "IO error reading btree node: %s\n", bch2_err_str(ret)); 219 goto out; 220 } 221 222 while (offset < btree_sectors(c)) { 223 struct bset *i; 224 struct nonce nonce; 225 struct bch_csum csum; 226 struct bkey_packed *k; 227 unsigned sectors; 228 229 if (!offset) { 230 i = &n_ondisk->keys; 231 232 if (!bch2_checksum_type_valid(c, BSET_CSUM_TYPE(i))) { 233 prt_printf(out, "unknown checksum type at offset %u: %llu\n", 234 offset, BSET_CSUM_TYPE(i)); 235 goto out; 236 } 237 238 nonce = btree_nonce(i, offset << 9); 239 csum = csum_vstruct(c, BSET_CSUM_TYPE(i), nonce, n_ondisk); 240 241 if (bch2_crc_cmp(csum, n_ondisk->csum)) { 242 prt_printf(out, "invalid checksum\n"); 243 goto out; 244 } 245 246 bset_encrypt(c, i, offset << 9); 247 248 sectors = vstruct_sectors(n_ondisk, c->block_bits); 249 } else { 250 struct btree_node_entry *bne = (void *) n_ondisk + (offset << 9); 251 252 i = &bne->keys; 253 254 if (i->seq != n_ondisk->keys.seq) 255 break; 256 257 if (!bch2_checksum_type_valid(c, BSET_CSUM_TYPE(i))) { 258 prt_printf(out, "unknown checksum type at offset %u: %llu\n", 259 offset, BSET_CSUM_TYPE(i)); 260 goto out; 261 } 262 263 nonce = btree_nonce(i, offset << 9); 264 csum = csum_vstruct(c, BSET_CSUM_TYPE(i), nonce, bne); 265 266 if (bch2_crc_cmp(csum, bne->csum)) { 267 prt_printf(out, "invalid checksum"); 268 goto out; 269 } 270 271 bset_encrypt(c, i, offset << 9); 272 273 sectors = vstruct_sectors(bne, c->block_bits); 274 } 275 276 prt_printf(out, " offset %u version %u, journal seq %llu\n", 277 offset, 278 le16_to_cpu(i->version), 279 le64_to_cpu(i->journal_seq)); 280 offset += sectors; 281 282 printbuf_indent_add(out, 4); 283 284 for (k = i->start; k != vstruct_last(i); k = bkey_p_next(k)) { 285 struct bkey u; 286 287 bch2_bkey_val_to_text(out, c, bkey_disassemble(b, k, &u)); 288 prt_newline(out); 289 } 290 291 printbuf_indent_sub(out, 4); 292 } 293 out: 294 if (bio) 295 bio_put(bio); 296 kvpfree(n_ondisk, btree_bytes(c)); 297 percpu_ref_put(&ca->io_ref); 298 } 299 300 #ifdef CONFIG_DEBUG_FS 301 302 /* XXX: bch_fs refcounting */ 303 304 struct dump_iter { 305 struct bch_fs *c; 306 enum btree_id id; 307 struct bpos from; 308 struct bpos prev_node; 309 u64 iter; 310 311 struct printbuf buf; 312 313 char __user *ubuf; /* destination user buffer */ 314 size_t size; /* size of requested read */ 315 ssize_t ret; /* bytes read so far */ 316 }; 317 318 static ssize_t flush_buf(struct dump_iter *i) 319 { 320 if (i->buf.pos) { 321 size_t bytes = min_t(size_t, i->buf.pos, i->size); 322 int copied = bytes - copy_to_user(i->ubuf, i->buf.buf, bytes); 323 324 i->ret += copied; 325 i->ubuf += copied; 326 i->size -= copied; 327 i->buf.pos -= copied; 328 memmove(i->buf.buf, i->buf.buf + copied, i->buf.pos); 329 330 if (copied != bytes) 331 return -EFAULT; 332 } 333 334 return i->size ? 0 : i->ret; 335 } 336 337 static int bch2_dump_open(struct inode *inode, struct file *file) 338 { 339 struct btree_debug *bd = inode->i_private; 340 struct dump_iter *i; 341 342 i = kzalloc(sizeof(struct dump_iter), GFP_KERNEL); 343 if (!i) 344 return -ENOMEM; 345 346 file->private_data = i; 347 i->from = POS_MIN; 348 i->iter = 0; 349 i->c = container_of(bd, struct bch_fs, btree_debug[bd->id]); 350 i->id = bd->id; 351 i->buf = PRINTBUF; 352 353 return 0; 354 } 355 356 static int bch2_dump_release(struct inode *inode, struct file *file) 357 { 358 struct dump_iter *i = file->private_data; 359 360 printbuf_exit(&i->buf); 361 kfree(i); 362 return 0; 363 } 364 365 static ssize_t bch2_read_btree(struct file *file, char __user *buf, 366 size_t size, loff_t *ppos) 367 { 368 struct dump_iter *i = file->private_data; 369 struct btree_trans *trans; 370 struct btree_iter iter; 371 struct bkey_s_c k; 372 ssize_t ret; 373 374 i->ubuf = buf; 375 i->size = size; 376 i->ret = 0; 377 378 ret = flush_buf(i); 379 if (ret) 380 return ret; 381 382 trans = bch2_trans_get(i->c); 383 ret = for_each_btree_key2(trans, iter, i->id, i->from, 384 BTREE_ITER_PREFETCH| 385 BTREE_ITER_ALL_SNAPSHOTS, k, ({ 386 bch2_bkey_val_to_text(&i->buf, i->c, k); 387 prt_newline(&i->buf); 388 drop_locks_do(trans, flush_buf(i)); 389 })); 390 i->from = iter.pos; 391 392 bch2_trans_put(trans); 393 394 if (!ret) 395 ret = flush_buf(i); 396 397 return ret ?: i->ret; 398 } 399 400 static const struct file_operations btree_debug_ops = { 401 .owner = THIS_MODULE, 402 .open = bch2_dump_open, 403 .release = bch2_dump_release, 404 .read = bch2_read_btree, 405 }; 406 407 static ssize_t bch2_read_btree_formats(struct file *file, char __user *buf, 408 size_t size, loff_t *ppos) 409 { 410 struct dump_iter *i = file->private_data; 411 struct btree_trans *trans; 412 struct btree_iter iter; 413 struct btree *b; 414 ssize_t ret; 415 416 i->ubuf = buf; 417 i->size = size; 418 i->ret = 0; 419 420 ret = flush_buf(i); 421 if (ret) 422 return ret; 423 424 if (bpos_eq(SPOS_MAX, i->from)) 425 return i->ret; 426 427 trans = bch2_trans_get(i->c); 428 retry: 429 bch2_trans_begin(trans); 430 431 for_each_btree_node(trans, iter, i->id, i->from, 0, b, ret) { 432 bch2_btree_node_to_text(&i->buf, i->c, b); 433 i->from = !bpos_eq(SPOS_MAX, b->key.k.p) 434 ? bpos_successor(b->key.k.p) 435 : b->key.k.p; 436 437 ret = drop_locks_do(trans, flush_buf(i)); 438 if (ret) 439 break; 440 } 441 bch2_trans_iter_exit(trans, &iter); 442 443 if (bch2_err_matches(ret, BCH_ERR_transaction_restart)) 444 goto retry; 445 446 bch2_trans_put(trans); 447 448 if (!ret) 449 ret = flush_buf(i); 450 451 return ret ?: i->ret; 452 } 453 454 static const struct file_operations btree_format_debug_ops = { 455 .owner = THIS_MODULE, 456 .open = bch2_dump_open, 457 .release = bch2_dump_release, 458 .read = bch2_read_btree_formats, 459 }; 460 461 static ssize_t bch2_read_bfloat_failed(struct file *file, char __user *buf, 462 size_t size, loff_t *ppos) 463 { 464 struct dump_iter *i = file->private_data; 465 struct btree_trans *trans; 466 struct btree_iter iter; 467 struct bkey_s_c k; 468 ssize_t ret; 469 470 i->ubuf = buf; 471 i->size = size; 472 i->ret = 0; 473 474 ret = flush_buf(i); 475 if (ret) 476 return ret; 477 478 trans = bch2_trans_get(i->c); 479 480 ret = for_each_btree_key2(trans, iter, i->id, i->from, 481 BTREE_ITER_PREFETCH| 482 BTREE_ITER_ALL_SNAPSHOTS, k, ({ 483 struct btree_path_level *l = &iter.path->l[0]; 484 struct bkey_packed *_k = 485 bch2_btree_node_iter_peek(&l->iter, l->b); 486 487 if (bpos_gt(l->b->key.k.p, i->prev_node)) { 488 bch2_btree_node_to_text(&i->buf, i->c, l->b); 489 i->prev_node = l->b->key.k.p; 490 } 491 492 bch2_bfloat_to_text(&i->buf, l->b, _k); 493 drop_locks_do(trans, flush_buf(i)); 494 })); 495 i->from = iter.pos; 496 497 bch2_trans_put(trans); 498 499 if (!ret) 500 ret = flush_buf(i); 501 502 return ret ?: i->ret; 503 } 504 505 static const struct file_operations bfloat_failed_debug_ops = { 506 .owner = THIS_MODULE, 507 .open = bch2_dump_open, 508 .release = bch2_dump_release, 509 .read = bch2_read_bfloat_failed, 510 }; 511 512 static void bch2_cached_btree_node_to_text(struct printbuf *out, struct bch_fs *c, 513 struct btree *b) 514 { 515 if (!out->nr_tabstops) 516 printbuf_tabstop_push(out, 32); 517 518 prt_printf(out, "%px btree=%s l=%u ", 519 b, 520 bch2_btree_id_str(b->c.btree_id), 521 b->c.level); 522 prt_newline(out); 523 524 printbuf_indent_add(out, 2); 525 526 bch2_bkey_val_to_text(out, c, bkey_i_to_s_c(&b->key)); 527 prt_newline(out); 528 529 prt_printf(out, "flags: "); 530 prt_tab(out); 531 prt_bitflags(out, bch2_btree_node_flags, b->flags); 532 prt_newline(out); 533 534 prt_printf(out, "pcpu read locks: "); 535 prt_tab(out); 536 prt_printf(out, "%u", b->c.lock.readers != NULL); 537 prt_newline(out); 538 539 prt_printf(out, "written:"); 540 prt_tab(out); 541 prt_printf(out, "%u", b->written); 542 prt_newline(out); 543 544 prt_printf(out, "writes blocked:"); 545 prt_tab(out); 546 prt_printf(out, "%u", !list_empty_careful(&b->write_blocked)); 547 prt_newline(out); 548 549 prt_printf(out, "will make reachable:"); 550 prt_tab(out); 551 prt_printf(out, "%lx", b->will_make_reachable); 552 prt_newline(out); 553 554 prt_printf(out, "journal pin %px:", &b->writes[0].journal); 555 prt_tab(out); 556 prt_printf(out, "%llu", b->writes[0].journal.seq); 557 prt_newline(out); 558 559 prt_printf(out, "journal pin %px:", &b->writes[1].journal); 560 prt_tab(out); 561 prt_printf(out, "%llu", b->writes[1].journal.seq); 562 prt_newline(out); 563 564 printbuf_indent_sub(out, 2); 565 } 566 567 static ssize_t bch2_cached_btree_nodes_read(struct file *file, char __user *buf, 568 size_t size, loff_t *ppos) 569 { 570 struct dump_iter *i = file->private_data; 571 struct bch_fs *c = i->c; 572 bool done = false; 573 ssize_t ret = 0; 574 575 i->ubuf = buf; 576 i->size = size; 577 i->ret = 0; 578 579 do { 580 struct bucket_table *tbl; 581 struct rhash_head *pos; 582 struct btree *b; 583 584 ret = flush_buf(i); 585 if (ret) 586 return ret; 587 588 rcu_read_lock(); 589 i->buf.atomic++; 590 tbl = rht_dereference_rcu(c->btree_cache.table.tbl, 591 &c->btree_cache.table); 592 if (i->iter < tbl->size) { 593 rht_for_each_entry_rcu(b, pos, tbl, i->iter, hash) 594 bch2_cached_btree_node_to_text(&i->buf, c, b); 595 i->iter++; 596 } else { 597 done = true; 598 } 599 --i->buf.atomic; 600 rcu_read_unlock(); 601 } while (!done); 602 603 if (i->buf.allocation_failure) 604 ret = -ENOMEM; 605 606 if (!ret) 607 ret = flush_buf(i); 608 609 return ret ?: i->ret; 610 } 611 612 static const struct file_operations cached_btree_nodes_ops = { 613 .owner = THIS_MODULE, 614 .open = bch2_dump_open, 615 .release = bch2_dump_release, 616 .read = bch2_cached_btree_nodes_read, 617 }; 618 619 #ifdef CONFIG_BCACHEFS_DEBUG_TRANSACTIONS 620 static ssize_t bch2_btree_transactions_read(struct file *file, char __user *buf, 621 size_t size, loff_t *ppos) 622 { 623 struct dump_iter *i = file->private_data; 624 struct bch_fs *c = i->c; 625 struct btree_trans *trans; 626 ssize_t ret = 0; 627 u32 seq; 628 629 i->ubuf = buf; 630 i->size = size; 631 i->ret = 0; 632 restart: 633 seqmutex_lock(&c->btree_trans_lock); 634 list_for_each_entry(trans, &c->btree_trans_list, list) { 635 if (trans->locking_wait.task->pid <= i->iter) 636 continue; 637 638 closure_get(&trans->ref); 639 seq = seqmutex_seq(&c->btree_trans_lock); 640 seqmutex_unlock(&c->btree_trans_lock); 641 642 ret = flush_buf(i); 643 if (ret) { 644 closure_put(&trans->ref); 645 goto unlocked; 646 } 647 648 bch2_btree_trans_to_text(&i->buf, trans); 649 650 prt_printf(&i->buf, "backtrace:"); 651 prt_newline(&i->buf); 652 printbuf_indent_add(&i->buf, 2); 653 bch2_prt_task_backtrace(&i->buf, trans->locking_wait.task); 654 printbuf_indent_sub(&i->buf, 2); 655 prt_newline(&i->buf); 656 657 i->iter = trans->locking_wait.task->pid; 658 659 closure_put(&trans->ref); 660 661 if (!seqmutex_relock(&c->btree_trans_lock, seq)) 662 goto restart; 663 } 664 seqmutex_unlock(&c->btree_trans_lock); 665 unlocked: 666 if (i->buf.allocation_failure) 667 ret = -ENOMEM; 668 669 if (!ret) 670 ret = flush_buf(i); 671 672 return ret ?: i->ret; 673 } 674 675 static const struct file_operations btree_transactions_ops = { 676 .owner = THIS_MODULE, 677 .open = bch2_dump_open, 678 .release = bch2_dump_release, 679 .read = bch2_btree_transactions_read, 680 }; 681 #endif /* CONFIG_BCACHEFS_DEBUG_TRANSACTIONS */ 682 683 static ssize_t bch2_journal_pins_read(struct file *file, char __user *buf, 684 size_t size, loff_t *ppos) 685 { 686 struct dump_iter *i = file->private_data; 687 struct bch_fs *c = i->c; 688 bool done = false; 689 int err; 690 691 i->ubuf = buf; 692 i->size = size; 693 i->ret = 0; 694 695 do { 696 err = flush_buf(i); 697 if (err) 698 return err; 699 700 if (!i->size) 701 break; 702 703 done = bch2_journal_seq_pins_to_text(&i->buf, &c->journal, &i->iter); 704 i->iter++; 705 } while (!done); 706 707 if (i->buf.allocation_failure) 708 return -ENOMEM; 709 710 return i->ret; 711 } 712 713 static const struct file_operations journal_pins_ops = { 714 .owner = THIS_MODULE, 715 .open = bch2_dump_open, 716 .release = bch2_dump_release, 717 .read = bch2_journal_pins_read, 718 }; 719 720 static int lock_held_stats_open(struct inode *inode, struct file *file) 721 { 722 struct bch_fs *c = inode->i_private; 723 struct dump_iter *i; 724 725 i = kzalloc(sizeof(struct dump_iter), GFP_KERNEL); 726 727 if (!i) 728 return -ENOMEM; 729 730 i->iter = 0; 731 i->c = c; 732 i->buf = PRINTBUF; 733 file->private_data = i; 734 735 return 0; 736 } 737 738 static int lock_held_stats_release(struct inode *inode, struct file *file) 739 { 740 struct dump_iter *i = file->private_data; 741 742 printbuf_exit(&i->buf); 743 kfree(i); 744 745 return 0; 746 } 747 748 static ssize_t lock_held_stats_read(struct file *file, char __user *buf, 749 size_t size, loff_t *ppos) 750 { 751 struct dump_iter *i = file->private_data; 752 struct bch_fs *c = i->c; 753 int err; 754 755 i->ubuf = buf; 756 i->size = size; 757 i->ret = 0; 758 759 while (1) { 760 struct btree_transaction_stats *s = &c->btree_transaction_stats[i->iter]; 761 762 err = flush_buf(i); 763 if (err) 764 return err; 765 766 if (!i->size) 767 break; 768 769 if (i->iter == ARRAY_SIZE(bch2_btree_transaction_fns) || 770 !bch2_btree_transaction_fns[i->iter]) 771 break; 772 773 prt_printf(&i->buf, "%s: ", bch2_btree_transaction_fns[i->iter]); 774 prt_newline(&i->buf); 775 printbuf_indent_add(&i->buf, 2); 776 777 mutex_lock(&s->lock); 778 779 prt_printf(&i->buf, "Max mem used: %u", s->max_mem); 780 prt_newline(&i->buf); 781 782 if (IS_ENABLED(CONFIG_BCACHEFS_LOCK_TIME_STATS)) { 783 prt_printf(&i->buf, "Lock hold times:"); 784 prt_newline(&i->buf); 785 786 printbuf_indent_add(&i->buf, 2); 787 bch2_time_stats_to_text(&i->buf, &s->lock_hold_times); 788 printbuf_indent_sub(&i->buf, 2); 789 } 790 791 if (s->max_paths_text) { 792 prt_printf(&i->buf, "Maximum allocated btree paths (%u):", s->nr_max_paths); 793 prt_newline(&i->buf); 794 795 printbuf_indent_add(&i->buf, 2); 796 prt_str_indented(&i->buf, s->max_paths_text); 797 printbuf_indent_sub(&i->buf, 2); 798 } 799 800 mutex_unlock(&s->lock); 801 802 printbuf_indent_sub(&i->buf, 2); 803 prt_newline(&i->buf); 804 i->iter++; 805 } 806 807 if (i->buf.allocation_failure) 808 return -ENOMEM; 809 810 return i->ret; 811 } 812 813 static const struct file_operations lock_held_stats_op = { 814 .owner = THIS_MODULE, 815 .open = lock_held_stats_open, 816 .release = lock_held_stats_release, 817 .read = lock_held_stats_read, 818 }; 819 820 static ssize_t bch2_btree_deadlock_read(struct file *file, char __user *buf, 821 size_t size, loff_t *ppos) 822 { 823 struct dump_iter *i = file->private_data; 824 struct bch_fs *c = i->c; 825 struct btree_trans *trans; 826 ssize_t ret = 0; 827 u32 seq; 828 829 i->ubuf = buf; 830 i->size = size; 831 i->ret = 0; 832 833 if (i->iter) 834 goto out; 835 restart: 836 seqmutex_lock(&c->btree_trans_lock); 837 list_for_each_entry(trans, &c->btree_trans_list, list) { 838 if (trans->locking_wait.task->pid <= i->iter) 839 continue; 840 841 closure_get(&trans->ref); 842 seq = seqmutex_seq(&c->btree_trans_lock); 843 seqmutex_unlock(&c->btree_trans_lock); 844 845 ret = flush_buf(i); 846 if (ret) { 847 closure_put(&trans->ref); 848 goto out; 849 } 850 851 bch2_check_for_deadlock(trans, &i->buf); 852 853 i->iter = trans->locking_wait.task->pid; 854 855 closure_put(&trans->ref); 856 857 if (!seqmutex_relock(&c->btree_trans_lock, seq)) 858 goto restart; 859 } 860 seqmutex_unlock(&c->btree_trans_lock); 861 out: 862 if (i->buf.allocation_failure) 863 ret = -ENOMEM; 864 865 if (!ret) 866 ret = flush_buf(i); 867 868 return ret ?: i->ret; 869 } 870 871 static const struct file_operations btree_deadlock_ops = { 872 .owner = THIS_MODULE, 873 .open = bch2_dump_open, 874 .release = bch2_dump_release, 875 .read = bch2_btree_deadlock_read, 876 }; 877 878 void bch2_fs_debug_exit(struct bch_fs *c) 879 { 880 if (!IS_ERR_OR_NULL(c->fs_debug_dir)) 881 debugfs_remove_recursive(c->fs_debug_dir); 882 } 883 884 void bch2_fs_debug_init(struct bch_fs *c) 885 { 886 struct btree_debug *bd; 887 char name[100]; 888 889 if (IS_ERR_OR_NULL(bch_debug)) 890 return; 891 892 snprintf(name, sizeof(name), "%pU", c->sb.user_uuid.b); 893 c->fs_debug_dir = debugfs_create_dir(name, bch_debug); 894 if (IS_ERR_OR_NULL(c->fs_debug_dir)) 895 return; 896 897 debugfs_create_file("cached_btree_nodes", 0400, c->fs_debug_dir, 898 c->btree_debug, &cached_btree_nodes_ops); 899 900 #ifdef CONFIG_BCACHEFS_DEBUG_TRANSACTIONS 901 debugfs_create_file("btree_transactions", 0400, c->fs_debug_dir, 902 c->btree_debug, &btree_transactions_ops); 903 #endif 904 905 debugfs_create_file("journal_pins", 0400, c->fs_debug_dir, 906 c->btree_debug, &journal_pins_ops); 907 908 debugfs_create_file("btree_transaction_stats", 0400, c->fs_debug_dir, 909 c, &lock_held_stats_op); 910 911 debugfs_create_file("btree_deadlock", 0400, c->fs_debug_dir, 912 c->btree_debug, &btree_deadlock_ops); 913 914 c->btree_debug_dir = debugfs_create_dir("btrees", c->fs_debug_dir); 915 if (IS_ERR_OR_NULL(c->btree_debug_dir)) 916 return; 917 918 for (bd = c->btree_debug; 919 bd < c->btree_debug + ARRAY_SIZE(c->btree_debug); 920 bd++) { 921 bd->id = bd - c->btree_debug; 922 debugfs_create_file(bch2_btree_id_str(bd->id), 923 0400, c->btree_debug_dir, bd, 924 &btree_debug_ops); 925 926 snprintf(name, sizeof(name), "%s-formats", 927 bch2_btree_id_str(bd->id)); 928 929 debugfs_create_file(name, 0400, c->btree_debug_dir, bd, 930 &btree_format_debug_ops); 931 932 snprintf(name, sizeof(name), "%s-bfloat-failed", 933 bch2_btree_id_str(bd->id)); 934 935 debugfs_create_file(name, 0400, c->btree_debug_dir, bd, 936 &bfloat_failed_debug_ops); 937 } 938 } 939 940 #endif 941 942 void bch2_debug_exit(void) 943 { 944 if (!IS_ERR_OR_NULL(bch_debug)) 945 debugfs_remove_recursive(bch_debug); 946 } 947 948 int __init bch2_debug_init(void) 949 { 950 int ret = 0; 951 952 bch_debug = debugfs_create_dir("bcachefs", NULL); 953 return ret; 954 } 955