diff options
Diffstat (limited to 'c_src')
-rw-r--r-- | c_src/cmd_kill_btree_node.c | 29 | ||||
-rw-r--r-- | c_src/cmd_list_journal.c | 74 |
2 files changed, 65 insertions, 38 deletions
diff --git a/c_src/cmd_kill_btree_node.c b/c_src/cmd_kill_btree_node.c index 81dbdd4b..523b5b15 100644 --- a/c_src/cmd_kill_btree_node.c +++ b/c_src/cmd_kill_btree_node.c @@ -20,9 +20,8 @@ static void kill_btree_node_usage(void) "Usage: bcachefs kill_btree_node [OPTION]... <devices>\n" "\n" "Options:\n" - " -b (extents|inodes|dirents|xattrs) Btree to delete from\n" - " -l level Levle to delete from (0 == leaves)\n" - " -i index Index of btree node to kill\n" + " -n btree:level:idx Node to kill\n" + " -d dev Device index (default: kill all replicas)\n" " -h Display this help and exit\n" "Report bugs to <linux-bcachefs@vger.kernel.org>"); } @@ -37,11 +36,11 @@ int cmd_kill_btree_node(int argc, char *argv[]) { struct bch_opts opts = bch2_opts_empty(); DARRAY(struct kill_node) kill_nodes = {}; - int opt; + int opt, dev_idx = -1; opt_set(opts, read_only, true); - while ((opt = getopt(argc, argv, "n:h")) != -1) + while ((opt = getopt(argc, argv, "n:d:h")) != -1) switch (opt) { case 'n': { char *p = optarg; @@ -65,6 +64,10 @@ int cmd_kill_btree_node(int argc, char *argv[]) darray_push(&kill_nodes, n); break; } + case 'd': + if (kstrtoint(optarg, 10, &dev_idx)) + die("invalid device index %s", optarg); + break; case 'h': kill_btree_node_usage(); exit(EXIT_SUCCESS); @@ -96,20 +99,24 @@ int cmd_kill_btree_node(int argc, char *argv[]) int ret2 = 0; if (!i->idx) { - struct printbuf buf = PRINTBUF; - bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&b->key)); - bch_info(c, "killing btree node %s l=%u %s", - bch2_btree_id_str(i->btree), i->level, buf.buf); - printbuf_exit(&buf); - ret2 = 1; struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(bkey_i_to_s_c(&b->key)); bkey_for_each_ptr(ptrs, ptr) { + if (dev_idx >= 0 && ptr->dev != dev_idx) + continue; + struct bch_dev *ca = bch2_dev_tryget(c, ptr->dev); if (!ca) continue; + struct printbuf buf = PRINTBUF; + bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&b->key)); + bch_info(c, "killing btree node on dev %i %s l=%u\n %s", + ptr->dev, + bch2_btree_id_str(i->btree), i->level, buf.buf); + printbuf_exit(&buf); + int ret3 = pwrite(ca->disk_sb.bdev->bd_fd, zeroes, c->opts.block_size, ptr->offset << 9); bch2_dev_put(ca); diff --git a/c_src/cmd_list_journal.c b/c_src/cmd_list_journal.c index ca212c26..5f91337d 100644 --- a/c_src/cmd_list_journal.c +++ b/c_src/cmd_list_journal.c @@ -428,7 +428,8 @@ static void list_journal_usage(void) "Usage: bcachefs list_journal [OPTION]... <devices>\n" "\n" "Options:\n" - " -a Read entire journal, not just dirty entries\n" + " -a, --all Read entire journal, not just contiguous entries\n" + " -d, --dirty-only Only read dirty entries\n" " -B, --blacklisted Include blacklisted entries\n" " -F, --flush-only Only print flush entries/commits\n" " -D, --datetime Print datetime entries only\n" @@ -448,6 +449,8 @@ static void list_journal_usage(void) int cmd_list_journal(int argc, char *argv[]) { static const struct option longopts[] = { + { "all", no_argument, NULL, 'a' }, + { "dirty-only", no_argument, NULL, 'd' }, { "nr-entries", required_argument, NULL, 'n' }, { "blacklisted", no_argument, NULL, 'B' }, { "flush-only", no_argument, NULL, 'F' }, @@ -464,8 +467,9 @@ int cmd_list_journal(int argc, char *argv[]) { NULL } }; struct bch_opts opts = bch2_opts_empty(); - u32 nr_entries = U32_MAX; + u32 nr_entries = 0; journal_filter f = { .btree_filter = ~0ULL, .bkey_val = true }; + bool contiguous_only = true; char *t; int opt, ret; @@ -478,12 +482,16 @@ int cmd_list_journal(int argc, char *argv[]) opt_set(opts, fix_errors, FSCK_FIX_yes); opt_set(opts, retain_recovery_info ,true); opt_set(opts, read_journal_only,true); + opt_set(opts, read_entire_journal, true); - while ((opt = getopt_long(argc, argv, "an:BFDlLob:t:k:V:vh", + while ((opt = getopt_long(argc, argv, "adn:BFMDlLob:t:k:V:vh", longopts, NULL)) != -1) switch (opt) { case 'a': - opt_set(opts, read_entire_journal, true); + contiguous_only = false; + break; + case 'd': + opt_set(opts, read_entire_journal, false); break; case 'n': if (kstrtouint(optarg, 10, &nr_entries)) @@ -555,37 +563,49 @@ int cmd_list_journal(int argc, char *argv[]) struct journal_replay *p, **_p; struct genradix_iter iter; - u64 seq = 0; + u64 min_seq_to_print = 0; - genradix_for_each(&c->journal_entries, iter, _p) { - p = *_p; - if (!p) - continue; - if (le64_to_cpu(p->j.seq) + nr_entries < atomic64_read(&c->journal.seq)) - continue; + if (contiguous_only) { + u64 seq = 0; + genradix_for_each(&c->journal_entries, iter, _p) { + p = *_p; + if (!p) + continue; - while (seq < le64_to_cpu(p->j.seq)) { - while (seq < le64_to_cpu(p->j.seq) && - bch2_journal_seq_is_blacklisted(c, seq, false)) - seq++; + if (!seq) + seq = le64_to_cpu(p->j.seq); - if (seq == le64_to_cpu(p->j.seq)) - break; + struct u64_range missing; + while ((missing = bch2_journal_entry_missing_range(c, seq, le64_to_cpu(p->j.seq))).start) + seq = min_seq_to_print = missing.end; - u64 missing_start = seq; + seq = le64_to_cpu(p->j.seq) + 1; + } + } - while (seq < le64_to_cpu(p->j.seq) && - !bch2_journal_seq_is_blacklisted(c, seq, false)) - seq++; + if (nr_entries) + min_seq_to_print = max_t(s64, min_seq_to_print, + atomic64_read(&c->journal.seq) - nr_entries); - u64 missing_end = seq - 1; + u64 seq = 0; + genradix_for_each(&c->journal_entries, iter, _p) { + p = *_p; + if (!p) + continue; - if (missing_start == missing_end) - break; + if (le64_to_cpu(p->j.seq) < min_seq_to_print) + continue; + + if (!seq) + seq = le64_to_cpu(p->j.seq); - printf("missing %llu at %llu-%llu\n", - missing_end - missing_start, - missing_start, missing_end); + struct u64_range missing; + while ((missing = bch2_journal_entry_missing_range(c, seq, le64_to_cpu(p->j.seq))).start) { + printf("missing %llu entries at %llu-%llu%s\n", + missing.end - missing.start, + missing.start, missing.end - 1, + missing.end < c->journal.last_seq_ondisk ? " (not dirty)" : ""); + seq = missing.end; } seq = le64_to_cpu(p->j.seq) + 1; |