diff options
Diffstat (limited to 'c_src/cmd_kill_btree_node.c')
-rw-r--r-- | c_src/cmd_kill_btree_node.c | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/c_src/cmd_kill_btree_node.c b/c_src/cmd_kill_btree_node.c index 81dbdd4b..817cd580 100644 --- a/c_src/cmd_kill_btree_node.c +++ b/c_src/cmd_kill_btree_node.c @@ -1,4 +1,5 @@ #include <fcntl.h> +#include <getopt.h> #include <string.h> #include <sys/stat.h> #include <sys/types.h> @@ -20,9 +21,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, --node btree:level:idx Node to kill\n" + " -d, --dev dev Device index (default: kill all replicas)\n" " -h Display this help and exit\n" "Report bugs to <linux-bcachefs@vger.kernel.org>"); } @@ -35,13 +35,19 @@ struct kill_node { int cmd_kill_btree_node(int argc, char *argv[]) { + static const struct option longopts[] = { + { "node", required_argument, NULL, 'n' }, + { "dev", required_argument, NULL, 'd' }, + { "help", no_argument, NULL, 'h' }, + { NULL } + }; 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_long(argc, argv, "n:d:h", longopts, NULL)) != -1) switch (opt) { case 'n': { char *p = optarg; @@ -65,6 +71,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 +106,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); |