Whamcloud - gitweb
debugfs: fix infinite loop while dumping the journal
authorWenchao Hao <haowenchao2@huawei.com>
Fri, 17 Nov 2023 10:23:15 +0000 (18:23 +0800)
committerTheodore Ts'o <tytso@mit.edu>
Wed, 17 Apr 2024 04:22:07 +0000 (00:22 -0400)
There are 2 scenarios which would trigger infinite loop:

1. None log is recorded, then dumplog with "-n", for example:
   debugfs -R "logdump -O -n 10" /dev/xxx
   while /dev/xxx has no valid log recorded.
2. The log area is full and cycle write is triggered, then dumplog with
   debugfs -R "logdump -aOS" /dev/xxx

This patch add a new flag "wrapped_flag" to mark if logdump has
reached to tail of logarea set in macro WRAP().

If wrapped_flag is true, and we comes to first_transaction_blocknr
again, just break the logdump loop.

[ Renamed reverse_flag to wrapped_flag to make it clearer what it is. -- TYT ]

Signed-off-by: Wenchao Hao <haowenchao2@huawei.com>
Link: https://lore.kernel.org/r/20231117102315.2431846-1-haowenchao2@huawei.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
debugfs/logdump.c

index b600228..c4d4664 100644 (file)
@@ -52,6 +52,7 @@ static int64_t                dump_counts;
 static blk64_t         block_to_dump, bitmap_to_dump, inode_block_to_dump;
 static unsigned int    group_to_dump, inode_offset_to_dump;
 static ext2_ino_t      inode_to_dump;
+static bool            wrapped_flag;
 
 struct journal_source
 {
@@ -80,8 +81,10 @@ static void dump_fc_block(FILE *out_file, char *buf, int blocksize,
 static void do_hexdump (FILE *, char *, int);
 
 #define WRAP(jsb, blocknr, maxlen)                                     \
-       if (blocknr >= (maxlen))                                        \
-           blocknr -= (maxlen - be32_to_cpu((jsb)->s_first));
+       if (blocknr >= (maxlen)) {                                      \
+               blocknr -= (maxlen - be32_to_cpu((jsb)->s_first));      \
+               wrapped_flag = true;                                    \
+       }
 
 void do_logdump(int argc, char **argv, int sci_idx EXT2FS_ATTR((unused)),
                    void *infop EXT2FS_ATTR((unused)))
@@ -115,6 +118,7 @@ void do_logdump(int argc, char **argv, int sci_idx EXT2FS_ATTR((unused)),
        inode_block_to_dump = ANY_BLOCK;
        inode_to_dump = -1;
        dump_counts = -1;
+       wrapped_flag = false;
 
        reset_getopt();
        while ((c = getopt (argc, argv, "ab:ci:f:OsSn:")) != EOF) {
@@ -477,8 +481,7 @@ static void dump_journal(char *cmdname, FILE *out_file,
                if (dump_old && (dump_counts != -1) && (cur_counts >= dump_counts))
                        break;
 
-               if ((blocknr == first_transaction_blocknr) &&
-                   (cur_counts != 0) && dump_old && (dump_counts != -1)) {
+               if ((blocknr == first_transaction_blocknr) && dump_old && wrapped_flag) {
                        fprintf(out_file, "Dump all %lld journal records.\n",
                                (long long) cur_counts);
                        break;