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