Hi,

This patch adds a keyword "journals" to gfs2_edit. Its purpose is
to print information about the GFS2 journals: location, size, and
whether they're clean, dirty or damaged.

Example output:

# ./gfs2_edit -p journals /dev/mpathc/scratch
Block #Journal Status:       of 536870912 (0x20000000) 
-------------------- Journal List --------------------
journal0: 0x19    128MB dirty.
journal1: 0x805b  128MB clean.
journal2: 0x100a3 128MB dirty.
journal3: 0x180e5 128MB clean.
journal4: 0x2012e 128MB clean.
------------------------------------------------------

Regards,

Bob Peterson
Red Hat File Systems

Signed-off-by: Bob Peterson <[email protected]> 
---
diff --git a/gfs2/edit/extended.c b/gfs2/edit/extended.c
index 27c32a9..ac1e5d7 100644
--- a/gfs2/edit/extended.c
+++ b/gfs2/edit/extended.c
@@ -427,7 +427,7 @@ static void gfs_jindex_print(struct gfs_jindex *ji)
         pv(ji, ji_pad, "%u", "0x%x");
 }
 
-static int print_jindex(struct gfs2_inode *dij)
+static int print_gfs_jindex(struct gfs2_inode *dij)
 {
        int error, start_line;
        struct gfs_jindex ji;
@@ -467,6 +467,35 @@ static int print_jindex(struct gfs2_inode *dij)
        return error;
 }
 
+static int print_gfs2_jindex(void)
+{
+       int d, error;
+       struct gfs2_log_header head;
+       struct gfs2_inode *ip;
+
+       for (d = 0; d < indirect->ii[0].dirents; d++) {
+               if (strncmp(indirect->ii[0].dirent[d].filename, "journal", 7))
+                       continue;
+               ip = lgfs2_inode_read(&sbd, indirect->ii[0].dirent[d].block);
+               print_gfs2("%s: 0x%-5x %dMB ",
+                          indirect->ii[0].dirent[d].filename,
+                          indirect->ii[0].dirent[d].block,
+                          ip->i_di.di_size / 1048576);
+               error = gfs2_find_jhead(ip, &head);
+               if (error) {
+                       print_gfs2("corrupt.");
+               } else {
+                       if (head.lh_flags & GFS2_LOG_HEAD_UNMOUNT)
+                               print_gfs2("clean.");
+                       else
+                               print_gfs2("dirty.");
+               }
+               eol(0);
+               inode_put(&ip);
+       }
+       return 0;
+}
+
 static int parse_rindex(struct gfs2_inode *dip, int print_rindex)
 {
        int error, start_line;
@@ -618,8 +647,13 @@ int display_extended(void)
                parse_rindex(tmp_inode, TRUE);
                inode_put(&tmp_inode);
                brelse(tmp_bh);
-       }
-       else if (has_indirect_blocks() && !indirect_blocks &&
+       } else if (block_is_journals()) {
+               if (sbd.gfs1)
+                       block = sbd1->sb_jindex_di.no_addr;
+               else
+                       block = masterblock("jindex");
+               print_gfs2_jindex();
+       } else if (has_indirect_blocks() && !indirect_blocks &&
                 !display_leaf(indirect))
                return -1;
        else if (display_indirect(indirect, indirect_blocks, 0, 0) == 0)
@@ -635,13 +669,12 @@ int display_extended(void)
                parse_rindex(tmp_inode, FALSE);
                inode_put(&tmp_inode);
                brelse(tmp_bh);
-       }
-       else if (block_is_jindex()) {
+       } else if (block_is_jindex()) {
                tmp_bh = bread(&sbd, block);
                tmp_inode = lgfs2_inode_get(&sbd, tmp_bh);
                if (tmp_inode == NULL)
                        return -1;
-               print_jindex(tmp_inode);
+               print_gfs_jindex(tmp_inode);
                inode_put(&tmp_inode);
                brelse(tmp_bh);
        }
diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index f0d9789..738dc4e 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -592,6 +592,8 @@ int display_block_type(int from_restore)
        }
        if (block == RGLIST_DUMMY_BLOCK)
                print_gfs2("RG List       ");
+       else if (block == JOURNALS_DUMMY_BLOCK)
+               print_gfs2("Journal Status:      ");
        else
                print_gfs2("%lld    (0x%llx)", block, block);
        if (termlines) {
@@ -605,6 +607,9 @@ int display_block_type(int from_restore)
                ret_type = GFS2_METATYPE_RG;
                struct_len = sbd.gfs1 ? sizeof(struct gfs_rgrp) :
                        sizeof(struct gfs2_rgrp);
+       } else if (block == JOURNALS_DUMMY_BLOCK) {
+               ret_type = GFS2_METATYPE_DI;
+               struct_len = 0;
        } else {
                ret_type = get_block_type(bh);
                switch (ret_type) {
@@ -777,6 +782,8 @@ int display_block_type(int from_restore)
                print_gfs2("-------------- Master directory -----------------");
        else if (!sbd.gfs1 && block == RGLIST_DUMMY_BLOCK)
                print_gfs2("------------------ RG List ----------------------");
+       else if (!sbd.gfs1 && block == JOURNALS_DUMMY_BLOCK)
+               print_gfs2("-------------------- Journal List 
--------------------");
        else {
                if (sbd.gfs1) {
                        if (block == sbd1->sb_rindex_di.no_addr)
@@ -1215,6 +1222,7 @@ static int block_has_extended_info(void)
        if (has_indirect_blocks() ||
            block_is_rindex() ||
            block_is_rgtree() ||
+           block_is_journals() ||
            block_is_jindex() ||
            block_is_inum_file() ||
            block_is_statfs_file() ||
@@ -1334,6 +1342,11 @@ int display(int identify_only)
                        blk = sbd1->sb_rindex_di.no_addr;
                else
                        blk = masterblock("rindex");
+       } else if (block == JOURNALS_DUMMY_BLOCK) {
+               if (sbd.gfs1)
+                       blk = sbd1->sb_jindex_di.no_addr;
+               else
+                       blk = masterblock("jindex");
        } else
                blk = block;
        if (termlines) {
@@ -1400,6 +1413,7 @@ int display(int identify_only)
        else if (gfs2_struct_type == GFS2_METATYPE_LF) { /* directory leaf */
                do_leaf_extended(bh->b_data, indirect);
        }
+
        last_entry_onscreen[dmode] = 0;
        if (dmode == EXTENDED_MODE && !block_has_extended_info())
                dmode = HEX_MODE;
@@ -1415,9 +1429,10 @@ int display(int identify_only)
        if (dmode == HEX_MODE)          /* if hex display mode           */
                hexdump(dev_offset, (gfs2_struct_type == GFS2_METATYPE_DI)?
                        struct_len + di.di_size:sbd.bsize);
-       else if (dmode == GFS2_MODE)    /* if structure display          */
-               display_gfs2();            /* display the gfs2 structure    */
-       else
+       else if (dmode == GFS2_MODE) { /* if structure display */
+               if (block != JOURNALS_DUMMY_BLOCK)
+                       display_gfs2();       /* display the gfs2 structure */
+       } else
                display_extended();        /* display extended blocks       */
        /* No else here because display_extended can switch back to hex mode */
        if (termlines)
@@ -1748,6 +1763,8 @@ uint64_t check_keywords(const char *kword)
 
                rgnum = atoi(kword + 3);
                blk = get_rg_addr(rgnum);
+       } else if (!strncmp(kword, "journals", 8)) {
+               blk = JOURNALS_DUMMY_BLOCK;
        } else if (!strncmp(kword, "journal", 7) && isdigit(kword[7])) {
                uint64_t j_size;
 
@@ -1783,7 +1800,8 @@ static uint64_t goto_block(void)
                        temp_blk = block + delta;
                }
 
-               if (temp_blk == RGLIST_DUMMY_BLOCK || temp_blk < max_block) {
+               if (temp_blk == RGLIST_DUMMY_BLOCK ||
+                   temp_blk == JOURNALS_DUMMY_BLOCK || temp_blk < max_block) {
                        offset = 0;
                        block = temp_blk;
                        push_block(block);
@@ -2832,6 +2850,7 @@ static void usage(void)
        fprintf(stderr,"     master - prints the master directory.\n");
        fprintf(stderr,"     root - prints the root directory.\n");
        fprintf(stderr,"     jindex - prints the journal index directory.\n");
+       fprintf(stderr,"     journals - prints the journal status.\n");
        fprintf(stderr,"     per_node - prints the per_node directory.\n");
        fprintf(stderr,"     inum - prints the inum file.\n");
        fprintf(stderr,"     statfs - prints the statfs file.\n");
diff --git a/gfs2/edit/hexedit.h b/gfs2/edit/hexedit.h
index 706909c..21cf70a 100644
--- a/gfs2/edit/hexedit.h
+++ b/gfs2/edit/hexedit.h
@@ -25,6 +25,7 @@ enum dsp_mode { HEX_MODE = 0, GFS2_MODE = 1, EXTENDED_MODE = 
2, INIT_MODE = 3 };
                print_it("  "#member, fmt, fmt2, struct->member);       \
        } while (FALSE);
 #define RGLIST_DUMMY_BLOCK -2
+#define JOURNALS_DUMMY_BLOCK -3
 
 extern struct gfs2_sb sb;
 extern uint64_t block;
@@ -121,6 +122,13 @@ static inline int block_is_rgtree(void)
        return FALSE;
 }
 
+static inline int block_is_journals(void)
+{
+       if (block == JOURNALS_DUMMY_BLOCK)
+               return TRUE;
+       return FALSE;
+}
+
 #define SCREEN_HEIGHT   (16)
 #define SCREEN_WIDTH    (16)
 

Reply via email to