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