]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - cmd_dump.c
fix invalid write in pop_cmd()
[bcachefs-tools-debian] / cmd_dump.c
index 76b44c58959684d8b8c6326f8cce42984e2be11d..3123ba2526281e8a449731cd9caf4675b84538fd 100644 (file)
@@ -1,4 +1,5 @@
 #include <fcntl.h>
+#include <getopt.h>
 #include <string.h>
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -12,6 +13,7 @@
 #include "libbcachefs/btree_iter.h"
 #include "libbcachefs/error.h"
 #include "libbcachefs/extents.h"
+#include "libbcachefs/sb-members.h"
 #include "libbcachefs/super.h"
 
 static void dump_usage(void)
@@ -21,9 +23,9 @@ static void dump_usage(void)
             "\n"
             "Options:\n"
             "  -o output     Output qcow2 image(s)\n"
-            "  -f            Force; overwrite when needed\n"
-            "  -j            Dump entire journal, not just dirty entries\n"
-            "  -h            Display this help and exit\n"
+            "  -f, --force   Force; overwrite when needed\n"
+            "  --nojournal   Don't dump entire journal, just dirty entries\n"
+            "  -h, --help    Display this help and exit\n"
             "Report bugs to <linux-bcachefs@vger.kernel.org>");
 }
 
@@ -57,15 +59,12 @@ static void dump_one_device(struct bch_fs *c, struct bch_dev *ca, int fd,
 
        /* Btree: */
        for (i = 0; i < BTREE_ID_NR; i++) {
-               const struct bch_extent_ptr *ptr;
                struct bkey_ptrs_c ptrs;
-               struct btree_trans trans;
+               struct btree_trans *trans = bch2_trans_get(c);
                struct btree_iter iter;
                struct btree *b;
 
-               bch2_trans_init(&trans, c, 0, 0);
-
-               __for_each_btree_node(&trans, iter, i, POS_MIN, 0, 1, 0, b, ret) {
+               __for_each_btree_node(trans, iter, i, POS_MIN, 0, 1, 0, b, ret) {
                        struct btree_node_iter iter;
                        struct bkey u;
                        struct bkey_s_c k;
@@ -84,7 +83,7 @@ static void dump_one_device(struct bch_fs *c, struct bch_dev *ca, int fd,
                if (ret)
                        die("error %s walking btree nodes", bch2_err_str(ret));
 
-               b = c->btree_roots[i].b;
+               b = bch2_btree_id_root(c, i)->b;
                if (!btree_node_fake(b)) {
                        ptrs = bch2_bkey_ptrs_c(bkey_i_to_s_c(&b->key));
 
@@ -95,31 +94,39 @@ static void dump_one_device(struct bch_fs *c, struct bch_dev *ca, int fd,
                                                  btree_bytes(c));
                }
 
-               bch2_trans_iter_exit(&trans, &iter);
-               bch2_trans_exit(&trans);
+               bch2_trans_iter_exit(trans, &iter);
+               bch2_trans_put(trans);
        }
 
-       qcow2_write_image(ca->disk_sb.bdev->bd_buffered_fd, fd, &data,
+       qcow2_write_image(ca->disk_sb.bdev->bd_fd, fd, &data,
                          max_t(unsigned, btree_bytes(c) / 8, block_bytes(c)));
        darray_exit(&data);
 }
 
 int cmd_dump(int argc, char *argv[])
 {
+       static const struct option longopts[] = {
+               { "force",              no_argument,            NULL, 'f' },
+               { "nojournal",          no_argument,            NULL, 'j' },
+               { "verbose",            no_argument,            NULL, 'v' },
+               { "help",               no_argument,            NULL, 'h' },
+               { NULL }
+       };
        struct bch_opts opts = bch2_opts_empty();
-       struct bch_dev *ca;
        char *out = NULL;
-       unsigned i, nr_devices = 0;
-       bool force = false, entire_journal = false;
+       unsigned nr_devices = 0;
+       bool force = false, entire_journal = true;
        int fd, opt;
 
+       opt_set(opts, read_only,        true);
        opt_set(opts, nochanges,        true);
        opt_set(opts, norecovery,       true);
        opt_set(opts, degraded,         true);
        opt_set(opts, errors,           BCH_ON_ERROR_continue);
-       opt_set(opts, fix_errors,       FSCK_OPT_NO);
+       opt_set(opts, fix_errors,       FSCK_FIX_no);
 
-       while ((opt = getopt(argc, argv, "o:fjvh")) != -1)
+       while ((opt = getopt_long(argc, argv, "o:fvh",
+                                 longopts, NULL)) != -1)
                switch (opt) {
                case 'o':
                        out = optarg;
@@ -128,7 +135,7 @@ int cmd_dump(int argc, char *argv[])
                        force = true;
                        break;
                case 'j':
-                       entire_journal = true;
+                       entire_journal = false;
                        break;
                case 'v':
                        opt_set(opts, verbose, true);
@@ -147,26 +154,23 @@ int cmd_dump(int argc, char *argv[])
 
        struct bch_fs *c = bch2_fs_open(argv, argc, opts);
        if (IS_ERR(c))
-               die("error opening %s: %s", argv[0], bch2_err_str(PTR_ERR(c)));
+               die("error opening devices: %s", bch2_err_str(PTR_ERR(c)));
 
        down_read(&c->gc_lock);
 
-       for_each_online_member(ca, c, i)
+       for_each_online_member(c, ca)
                nr_devices++;
 
        BUG_ON(!nr_devices);
 
-       for_each_online_member(ca, c, i) {
+       for_each_online_member(c, ca) {
                int flags = O_WRONLY|O_CREAT|O_TRUNC;
 
                if (!force)
                        flags |= O_EXCL;
 
-               if (!c->devs[i])
-                       continue;
-
                char *path = nr_devices > 1
-                       ? mprintf("%s.%u.qcow2", out, i)
+                       ? mprintf("%s.%u.qcow2", out, ca->dev_idx)
                        : mprintf("%s.qcow2", out);
                fd = xopen(path, flags, 0600);
                free(path);