1dc728923Sopenharmony_ciFrom 6e4cc3d5eeb2dfaa055e652b5390beaa6c3d05da Mon Sep 17 00:00:00 2001 2dc728923Sopenharmony_ciFrom: "lihaoxiang (F)" <lihaoxiang9@huawei.com> 3dc728923Sopenharmony_ciDate: Thu, 14 Jul 2022 09:32:48 +0800 4dc728923Sopenharmony_ciSubject: [PATCH] debugfs: teach logdump the -n <num_trans> option 5dc728923Sopenharmony_ci 6dc728923Sopenharmony_ciThe current version's debugfs possessed the function 7dc728923Sopenharmony_cilogdump. Executing with option -O could output the log history. But 8dc728923Sopenharmony_ciwhen it occurred the block which had no magic number in it's header, 9dc728923Sopenharmony_cithe program would exit. 10dc728923Sopenharmony_ci 11dc728923Sopenharmony_ciSometimes we were locating problems, needed for more transactions that 12dc728923Sopenharmony_cihad replayed instead of the latest batch of transactions and we 13dc728923Sopenharmony_ciweren't hope to display all the history in the meanwhile. So we 14dc728923Sopenharmony_ciintroduced the option -n used for controlling the print of history 15dc728923Sopenharmony_citransactions. Specially, this parameter was depending on the option 16dc728923Sopenharmony_ci-O otherwise it couldn't work. 17dc728923Sopenharmony_ci 18dc728923Sopenharmony_ciSo in this modification, we used logdump with -O -n <num_trans>. The 19dc728923Sopenharmony_ci-n options causes logdump to continue past a block with a missing 20dc728923Sopenharmony_cimagic nuber. Instead, it will terminate only when the entire log has 21dc728923Sopenharmony_cibeen printed or after <num_trans> transactions. 22dc728923Sopenharmony_ci 23dc728923Sopenharmony_ciLink: https://lore.kernel.org/r/608df030-593f-8c69-cb65-632a34729d23@huawei.com 24dc728923Sopenharmony_ciSigned-off-by: lihaoxiang <lihaoxiang9@huawei.com> 25dc728923Sopenharmony_ciSigned-off-by: Theodore Ts'o <tytso@mit.edu> 26dc728923Sopenharmony_ci--- 27dc728923Sopenharmony_ci debugfs/debugfs.8.in | 13 +++++++++++-- 28dc728923Sopenharmony_ci debugfs/logdump.c | 32 ++++++++++++++++++++++++++++---- 29dc728923Sopenharmony_ci 2 files changed, 39 insertions(+), 6 deletions(-) 30dc728923Sopenharmony_ci 31dc728923Sopenharmony_cidiff --git a/debugfs/debugfs.8.in b/debugfs/debugfs.8.in 32dc728923Sopenharmony_ciindex aa6128a..a3227a8 100644 33dc728923Sopenharmony_ci--- a/debugfs/debugfs.8.in 34dc728923Sopenharmony_ci+++ b/debugfs/debugfs.8.in 35dc728923Sopenharmony_ci@@ -505,7 +505,7 @@ which is a hard link to 36dc728923Sopenharmony_ci .IR filespec . 37dc728923Sopenharmony_ci Note this does not adjust the inode reference counts. 38dc728923Sopenharmony_ci .TP 39dc728923Sopenharmony_ci-.BI logdump " [-acsOS] [-b block] [-i filespec] [-f journal_file] [output_file]" 40dc728923Sopenharmony_ci+.BI logdump " [-acsOS] [-b block] [-n num_trans ] [-i filespec] [-f journal_file] [output_file]" 41dc728923Sopenharmony_ci Dump the contents of the ext3 journal. By default, dump the journal inode as 42dc728923Sopenharmony_ci specified in the superblock. However, this can be overridden with the 43dc728923Sopenharmony_ci .I \-i 44dc728923Sopenharmony_ci@@ -528,7 +528,7 @@ The 45dc728923Sopenharmony_ci .I \-a 46dc728923Sopenharmony_ci option causes the 47dc728923Sopenharmony_ci .B logdump 48dc728923Sopenharmony_ci-program to print the contents of all of the descriptor blocks. 49dc728923Sopenharmony_ci+to print the contents of all of the descriptor blocks. 50dc728923Sopenharmony_ci The 51dc728923Sopenharmony_ci .I \-b 52dc728923Sopenharmony_ci option causes 53dc728923Sopenharmony_ci@@ -548,6 +548,15 @@ The 54dc728923Sopenharmony_ci option causes logdump to display old (checkpointed) journal entries. 55dc728923Sopenharmony_ci This can be used to try to track down journal problems even after the 56dc728923Sopenharmony_ci journal has been replayed. 57dc728923Sopenharmony_ci+.IP 58dc728923Sopenharmony_ci+The 59dc728923Sopenharmony_ci+.I \-n 60dc728923Sopenharmony_ci+option causes 61dc728923Sopenharmony_ci+.B logdump 62dc728923Sopenharmony_ci+to continue past a journal block which is missing a magic number. 63dc728923Sopenharmony_ci+Instead, it will stop only when the entire log is printed or after 64dc728923Sopenharmony_ci+.I num_trans 65dc728923Sopenharmony_ci+transactions. 66dc728923Sopenharmony_ci .TP 67dc728923Sopenharmony_ci .BI ls " [-l] [-c] [-d] [-p] [-r] filespec" 68dc728923Sopenharmony_ci Print a listing of the files in the directory 69dc728923Sopenharmony_cidiff --git a/debugfs/logdump.c b/debugfs/logdump.c 70dc728923Sopenharmony_ciindex 6b0133e..614414e 100644 71dc728923Sopenharmony_ci--- a/debugfs/logdump.c 72dc728923Sopenharmony_ci+++ b/debugfs/logdump.c 73dc728923Sopenharmony_ci@@ -48,6 +48,7 @@ enum journal_location {JOURNAL_IS_INTERNAL, JOURNAL_IS_EXTERNAL}; 74dc728923Sopenharmony_ci #define ANY_BLOCK ((blk64_t) -1) 75dc728923Sopenharmony_ci 76dc728923Sopenharmony_ci static int dump_all, dump_super, dump_old, dump_contents, dump_descriptors; 77dc728923Sopenharmony_ci+static int64_t dump_counts; 78dc728923Sopenharmony_ci static blk64_t block_to_dump, bitmap_to_dump, inode_block_to_dump; 79dc728923Sopenharmony_ci static unsigned int group_to_dump, inode_offset_to_dump; 80dc728923Sopenharmony_ci static ext2_ino_t inode_to_dump; 81dc728923Sopenharmony_ci@@ -113,9 +114,10 @@ void do_logdump(int argc, char **argv, int sci_idx EXT2FS_ATTR((unused)), 82dc728923Sopenharmony_ci bitmap_to_dump = -1; 83dc728923Sopenharmony_ci inode_block_to_dump = ANY_BLOCK; 84dc728923Sopenharmony_ci inode_to_dump = -1; 85dc728923Sopenharmony_ci+ dump_counts = -1; 86dc728923Sopenharmony_ci 87dc728923Sopenharmony_ci reset_getopt(); 88dc728923Sopenharmony_ci- while ((c = getopt (argc, argv, "ab:ci:f:OsS")) != EOF) { 89dc728923Sopenharmony_ci+ while ((c = getopt (argc, argv, "ab:ci:f:OsSn:")) != EOF) { 90dc728923Sopenharmony_ci switch (c) { 91dc728923Sopenharmony_ci case 'a': 92dc728923Sopenharmony_ci dump_all++; 93dc728923Sopenharmony_ci@@ -148,6 +150,14 @@ void do_logdump(int argc, char **argv, int sci_idx EXT2FS_ATTR((unused)), 94dc728923Sopenharmony_ci case 'S': 95dc728923Sopenharmony_ci dump_super++; 96dc728923Sopenharmony_ci break; 97dc728923Sopenharmony_ci+ case 'n': 98dc728923Sopenharmony_ci+ dump_counts = strtol(optarg, &tmp, 10); 99dc728923Sopenharmony_ci+ if (*tmp) { 100dc728923Sopenharmony_ci+ com_err(argv[0], 0, 101dc728923Sopenharmony_ci+ "Bad log counts number - %s", optarg); 102dc728923Sopenharmony_ci+ return; 103dc728923Sopenharmony_ci+ } 104dc728923Sopenharmony_ci+ break; 105dc728923Sopenharmony_ci default: 106dc728923Sopenharmony_ci goto print_usage; 107dc728923Sopenharmony_ci } 108dc728923Sopenharmony_ci@@ -289,7 +299,7 @@ cleanup: 109dc728923Sopenharmony_ci return; 110dc728923Sopenharmony_ci 111dc728923Sopenharmony_ci print_usage: 112dc728923Sopenharmony_ci- fprintf(stderr, "%s: Usage: logdump [-acsOS] [-b<block>] [-i<filespec>]\n\t" 113dc728923Sopenharmony_ci+ fprintf(stderr, "%s: Usage: logdump [-acsOS] [-n<num_trans>] [-b<block>] [-i<filespec>]\n\t" 114dc728923Sopenharmony_ci "[-f<journal_file>] [output_file]\n", argv[0]); 115dc728923Sopenharmony_ci } 116dc728923Sopenharmony_ci 117dc728923Sopenharmony_ci@@ -369,6 +379,8 @@ static void dump_journal(char *cmdname, FILE *out_file, 118dc728923Sopenharmony_ci int fc_done; 119dc728923Sopenharmony_ci __u64 total_len; 120dc728923Sopenharmony_ci __u32 maxlen; 121dc728923Sopenharmony_ci+ int64_t cur_counts = 0; 122dc728923Sopenharmony_ci+ bool exist_no_magic = false; 123dc728923Sopenharmony_ci 124dc728923Sopenharmony_ci /* First, check to see if there's an ext2 superblock header */ 125dc728923Sopenharmony_ci retval = read_journal_block(cmdname, source, 0, buf, 2048); 126dc728923Sopenharmony_ci@@ -459,6 +471,9 @@ static void dump_journal(char *cmdname, FILE *out_file, 127dc728923Sopenharmony_ci } 128dc728923Sopenharmony_ci 129dc728923Sopenharmony_ci while (1) { 130dc728923Sopenharmony_ci+ if (dump_old && (dump_counts != -1) && (cur_counts >= dump_counts)) 131dc728923Sopenharmony_ci+ break; 132dc728923Sopenharmony_ci+ 133dc728923Sopenharmony_ci retval = read_journal_block(cmdname, source, 134dc728923Sopenharmony_ci ((ext2_loff_t) blocknr) * blocksize, 135dc728923Sopenharmony_ci buf, blocksize); 136dc728923Sopenharmony_ci@@ -472,8 +487,16 @@ static void dump_journal(char *cmdname, FILE *out_file, 137dc728923Sopenharmony_ci blocktype = be32_to_cpu(header->h_blocktype); 138dc728923Sopenharmony_ci 139dc728923Sopenharmony_ci if (magic != JBD2_MAGIC_NUMBER) { 140dc728923Sopenharmony_ci- fprintf (out_file, "No magic number at block %u: " 141dc728923Sopenharmony_ci- "end of journal.\n", blocknr); 142dc728923Sopenharmony_ci+ if (exist_no_magic == false) { 143dc728923Sopenharmony_ci+ exist_no_magic = true; 144dc728923Sopenharmony_ci+ fprintf(out_file, "No magic number at block %u: " 145dc728923Sopenharmony_ci+ "end of journal.\n", blocknr); 146dc728923Sopenharmony_ci+ } 147dc728923Sopenharmony_ci+ if (dump_old && (dump_counts != -1)) { 148dc728923Sopenharmony_ci+ blocknr++; 149dc728923Sopenharmony_ci+ WRAP(jsb, blocknr, maxlen); 150dc728923Sopenharmony_ci+ continue; 151dc728923Sopenharmony_ci+ } 152dc728923Sopenharmony_ci break; 153dc728923Sopenharmony_ci } 154dc728923Sopenharmony_ci 155dc728923Sopenharmony_ci@@ -500,6 +523,7 @@ static void dump_journal(char *cmdname, FILE *out_file, 156dc728923Sopenharmony_ci continue; 157dc728923Sopenharmony_ci 158dc728923Sopenharmony_ci case JBD2_COMMIT_BLOCK: 159dc728923Sopenharmony_ci+ cur_counts++; 160dc728923Sopenharmony_ci transaction++; 161dc728923Sopenharmony_ci blocknr++; 162dc728923Sopenharmony_ci WRAP(jsb, blocknr, maxlen); 163dc728923Sopenharmony_ci-- 164dc728923Sopenharmony_ci1.8.3.1 165dc728923Sopenharmony_ci 166