public inbox for cluster-cvs@sourceware.org help / color / mirror / Atom feed
From: Bob Peterson <rpeterso@fedoraproject.org> To: cluster-cvs-relay@redhat.com Subject: RHEL5 - gfs2_edit: Improved gfs journal dumps Date: Thu, 31 Jul 2008 05:02:00 -0000 [thread overview] Message-ID: <20080730222443.029D112001F@lists.fedorahosted.org> (raw) Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=bf130aa9983f13ab5b2a40181680fc2c35f1f3e1 Commit: bf130aa9983f13ab5b2a40181680fc2c35f1f3e1 Parent: 67f13d16f385f42165d0196917fcd7bb8c5b0a1d Author: Bob Peterson <rpeterso@redhat.com> AuthorDate: Wed Jul 30 17:16:52 2008 -0500 Committer: Bob Peterson <rpeterso@redhat.com> CommitterDate: Wed Jul 30 17:21:30 2008 -0500 gfs2_edit: Improved gfs journal dumps bz 450004 This patch adds three important improvements to journal dumps: 1. It now recognizes and dumps GFS1 log descriptor continuation blocks and dumps them correctly. 2. It now prints a marker where the journal wrapped so you can locate the most recently added entries easily. 3. The absolute block number of the journal block is now printed with the entries (in addition to the journal offset). This makes it easier to find the correct journal block you need to see. --- gfs2/edit/hexedit.c | 173 ++++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 144 insertions(+), 29 deletions(-) diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c index 5a0e619..4d28a62 100644 --- a/gfs2/edit/hexedit.c +++ b/gfs2/edit/hexedit.c @@ -2235,15 +2235,129 @@ void gfs_log_header_print(struct gfs_log_header *lh) } /* ------------------------------------------------------------------------ */ +/* print_ld_blocks - print all blocks given in a log descriptor */ +/* returns: the number of block numbers it printed */ +/* ------------------------------------------------------------------------ */ +int print_ld_blocks(const uint64_t *b, const char *end, int start_line) +{ + int bcount = 0, i = 0; + static char str[256]; + + while (*b && (char *)b < end) { + if (!termlines || + (print_entry_ndx >= start_row[dmode] && + ((print_entry_ndx - start_row[dmode])+1) * + lines_per_row[dmode] <= termlines - start_line - 2)) { + if (i && i % 4 == 0) { + eol(0); + print_gfs2(" "); + } + i++; + sprintf(str, "0x%llx", + (unsigned long long)be64_to_cpu(*b)); + print_gfs2("%-18.18s ", str); + bcount++; + } + b++; + if (gfs1) + b++; + } + eol(0); + return bcount; +} + +/* ------------------------------------------------------------------------ */ +/* fsck_readi - same as libgfs2's gfs2_readi, but sets absolute block # */ +/* of the first bit of data read. */ +/* ------------------------------------------------------------------------ */ +int fsck_readi(struct gfs2_inode *ip, void *buf, uint64_t offset, + unsigned int size, uint64_t *abs_block) +{ + struct gfs2_sbd *sdp = ip->i_sbd; + struct gfs2_buffer_head *bh; + uint64_t lblock, dblock; + unsigned int o; + uint32_t extlen = 0; + unsigned int amount; + int not_new = 0; + int isdir = !!(S_ISDIR(ip->i_di.di_mode)); + int copied = 0; + + *abs_block = 0; + if (offset >= ip->i_di.di_size) + return 0; + if ((offset + size) > ip->i_di.di_size) + size = ip->i_di.di_size - offset; + if (!size) + return 0; + if (isdir) { + lblock = offset; + o = do_div(lblock, sdp->sd_jbsize); + } else { + lblock = offset >> sdp->sd_sb.sb_bsize_shift; + o = offset & (sdp->bsize - 1); + } + + if (!ip->i_di.di_height) /* inode_is_stuffed */ + o += sizeof(struct gfs2_dinode); + else if (isdir) + o += sizeof(struct gfs2_meta_header); + + while (copied < size) { + amount = size - copied; + if (amount > sdp->bsize - o) + amount = sdp->bsize - o; + if (!extlen) + block_map(ip, lblock, ¬_new, &dblock, &extlen, + FALSE, not_updated); + if (dblock) { + bh = bread(sdp, dblock); + if (*abs_block == 0) + *abs_block = bh->b_blocknr; + dblock++; + extlen--; + } else + bh = NULL; + if (bh) { + memcpy(buf, bh->b_data + o, amount); + brelse(bh, not_updated); + } else { + memset(buf, 0, amount); + } + copied += amount; + lblock++; + o = (isdir) ? sizeof(struct gfs2_meta_header) : 0; + } + return copied; +} + +void check_journal_wrap(uint64_t seq, uint64_t *highest_seq) +{ + if (seq < *highest_seq) { + print_gfs2("------------------------------------------------" + "------------------------------------------------"); + eol(0); + print_gfs2("Journal wrapped here."); + eol(0); + print_gfs2("------------------------------------------------" + "------------------------------------------------"); + eol(0); + } + *highest_seq = seq; +} + +/* ------------------------------------------------------------------------ */ /* dump_journal - dump a journal file's contents. */ /* ------------------------------------------------------------------------ */ void dump_journal(const char *journal) { struct gfs2_buffer_head *j_bh = NULL; - uint64_t jblock, j_size, jb; + uint64_t jblock, j_size, jb, abs_block; int error, start_line, journal_num; char jbuf[sbd.bsize]; struct gfs2_inode *j_inode = NULL; + int ld_blocks = 0; + uint64_t highest_seq = 0; start_line = line; lines_per_row[dmode] = 1; @@ -2264,17 +2378,18 @@ void dump_journal(const char *journal) if (j_bh) brelse(j_bh, not_updated); j_bh = bread(&sbd, jblock + jb); + abs_block = jblock + jb; memcpy(jbuf, j_bh->b_data, sbd.bsize); } else { - error = gfs2_readi(j_inode, (void *)&jbuf, jb, - sbd.bsize); + error = fsck_readi(j_inode, (void *)&jbuf, jb, + sbd.bsize, &abs_block); if (!error) /* end of file */ break; } if (get_block_type(jbuf) == GFS2_METATYPE_LD) { uint64_t *b; struct gfs2_log_descriptor ld; - int i = 0, ltndx; + int ltndx; uint32_t logtypes[2][6] = { {GFS2_LOG_DESC_METADATA, GFS2_LOG_DESC_REVOKE, @@ -2292,8 +2407,8 @@ void dump_journal(const char *journal) {"Metadata", "Unlinked inode", "Dealloc inode", "Quota", "Final Entry", "Unknown"}}; - print_gfs2("Block #%4llx: Log descriptor, ", - jb / (gfs1 ? 1 : sbd.bsize)); + print_gfs2("0x%llx (j+%4llx): Log descriptor, ", + abs_block, jb / (gfs1 ? 1 : sbd.bsize)); gfs2_log_descriptor_in(&ld, jbuf); print_gfs2("type %d ", ld.ld_type); @@ -2306,50 +2421,50 @@ void dump_journal(const char *journal) print_gfs2("len:%u, data1: %u", ld.ld_length, ld.ld_data1); eol(0); - print_gfs2(" "); + print_gfs2(" "); if (gfs1) b = (uint64_t *)(jbuf + sizeof(struct gfs_log_descriptor)); else b = (uint64_t *)(jbuf + sizeof(struct gfs2_log_descriptor)); - while (*b && (char *)b < (jbuf + sbd.bsize)) { - if (!termlines || - (print_entry_ndx >= start_row[dmode] && - ((print_entry_ndx - start_row[dmode])+1) * - lines_per_row[dmode] <= termlines - start_line - 2)) { - if (i && i % 4 == 0) { - eol(0); - print_gfs2(" "); - } - i++; - print_gfs2("0x%08llx ", be64_to_cpu(*b)); - } - b++; - if (gfs1) - b++; - } - eol(0); + ld_blocks = ld.ld_data1; + ld_blocks -= print_ld_blocks(b, (jbuf + sbd.bsize), + start_line); } else if (get_block_type(jbuf) == GFS2_METATYPE_LH) { struct gfs2_log_header lh; struct gfs_log_header lh1; if (gfs1) { gfs_log_header_in(&lh1, jbuf); - print_gfs2("Block #%4llx: Log header: Flags = " - "%08x, Seq = 0x%x, first = 0x%x " - "tail = 0x%x, last = 0x%x", + check_journal_wrap(lh1.lh_sequence, + &highest_seq); + print_gfs2("0x%llx (j+%4llx): Log header: " + "Flags:%x, Seq: 0x%x, " + "1st: 0x%x, tail: 0x%x, " + "last: 0x%x", abs_block, jb, lh1.lh_flags, lh1.lh_sequence, lh1.lh_first, lh1.lh_tail, lh1.lh_last_dump); } else { gfs2_log_header_in(&lh, jbuf); - print_gfs2("Block #%4llx: Log header: Seq" - "= 0x%x, tail = 0x%x, blk = 0x%x", + check_journal_wrap(lh.lh_sequence, + &highest_seq); + print_gfs2("0x%llx (j+%4llx): Log header: Seq" + ": 0x%x, tail: 0x%x, blk: 0x%x", + abs_block, jb / sbd.bsize, lh.lh_sequence, lh.lh_tail, lh.lh_blkno); } eol(0); + } else if (gfs1 && ld_blocks > 0) { + print_gfs2("0x%llx (j+%4llx): GFS log descriptor" + " continuation block", abs_block, jb); + eol(0); + print_gfs2(" "); + ld_blocks -= print_ld_blocks((uint64_t *)jbuf, + (jbuf + sbd.bsize), + start_line); } } brelse(j_bh, not_updated);
reply other threads:[~2008-07-30 22:25 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20080730222443.029D112001F@lists.fedorahosted.org \ --to=rpeterso@fedoraproject.org \ --cc=cluster-cvs-relay@redhat.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).