diff --git a/bcachefs.c b/bcachefs.c index 03ebfd20..b4958f13 100644 --- a/bcachefs.c +++ b/bcachefs.c @@ -75,6 +75,7 @@ static void usage(void) "These commands work on offline, unmounted filesystems\n" " dump Dump filesystem metadata to a qcow2 image\n" " list List filesystem metadata in textual form\n" + " list_journal List contents of journal\n" "\n" "Miscellaneous:\n" " version Display the version of the invoked bcachefs tool\n"); @@ -199,6 +200,8 @@ int main(int argc, char *argv[]) return cmd_dump(argc, argv); if (!strcmp(cmd, "list")) return cmd_list(argc, argv); + if (!strcmp(cmd, "list_journal")) + return cmd_list_journal(argc, argv); if (!strcmp(cmd, "setattr")) return cmd_setattr(argc, argv); diff --git a/cmd_debug.c b/cmd_debug.c index 5373845a..6d5f1c5f 100644 --- a/cmd_debug.c +++ b/cmd_debug.c @@ -15,6 +15,7 @@ #include "libbcachefs/buckets.h" #include "libbcachefs/error.h" #include "libbcachefs/journal.h" +#include "libbcachefs/journal_io.h" #include "libbcachefs/super.h" static void dump_usage(void) @@ -359,3 +360,58 @@ int cmd_list(int argc, char *argv[]) bch2_fs_stop(c); return 0; } + +static void list_journal_usage(void) +{ + puts("bcachefs list_journal - print contents of journal\n" + "Usage: bcachefs list_journal [OPTION]... \n" + "\n" + "Options:\n" + " -h Display this help and exit\n" + "Report bugs to "); +} + +int cmd_list_journal(int argc, char *argv[]) +{ + struct bch_opts opts = bch2_opts_empty(); + int opt; + + 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_YES); + opt_set(opts, keep_journal, true); + + while ((opt = getopt(argc, argv, "h")) != -1) + switch (opt) { + case 'h': + list_journal_usage(); + exit(EXIT_SUCCESS); + } + args_shift(optind); + + if (!argc) + die("Please supply device(s) to open"); + + struct bch_fs *c = bch2_fs_open(argv, argc, opts); + if (IS_ERR(c)) + die("error opening %s: %s", argv[0], strerror(-PTR_ERR(c))); + + struct journal_replay *p; + struct jset_entry *entry; + struct bkey_i *k, *_n; + + /* This could be greatly expanded: */ + + list_for_each_entry(p, &c->journal_entries, list) + for_each_jset_key(k, _n, entry, &p->j) { + char buf[200]; + + bch2_bkey_val_to_text(&PBUF(buf), c, bkey_i_to_s_c(k)); + printk(KERN_INFO "%s\n", buf); + } + + bch2_fs_stop(c); + return 0; +} diff --git a/cmds.h b/cmds.h index 230ad5b0..bcd27adc 100644 --- a/cmds.h +++ b/cmds.h @@ -39,6 +39,7 @@ int cmd_fsck(int argc, char *argv[]); int cmd_dump(int argc, char *argv[]); int cmd_list(int argc, char *argv[]); +int cmd_list_journal(int argc, char *argv[]); int cmd_migrate(int argc, char *argv[]); int cmd_migrate_superblock(int argc, char *argv[]);