Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=c9c... Commit: c9c57f5f0409743435e171c57cc7e59bd0b09cac Parent: 3575517393317423b10a9717fc5157261993625d Author: Bob Peterson rpeterso@redhat.com AuthorDate: Mon Dec 13 10:42:38 2010 -0600 Committer: Bob Peterson rpeterso@redhat.com CommitterDate: Wed Feb 2 14:36:08 2011 -0600
gfs2_edit: better printing of directory leaf information
This patch gives gfs2_edit the ability to better parse out and print directory information for exhash directories several levels deep.
rhbz#656371 --- gfs2/edit/gfs2hex.c | 13 ++++- gfs2/edit/gfs2hex.h | 2 +- gfs2/edit/hexedit.c | 135 +++++++++++++++++++++++++++++++-------------------- gfs2/edit/hexedit.h | 4 ++ 4 files changed, 99 insertions(+), 55 deletions(-)
diff --git a/gfs2/edit/gfs2hex.c b/gfs2/edit/gfs2hex.c index 2934877..1505783 100644 --- a/gfs2/edit/gfs2hex.c +++ b/gfs2/edit/gfs2hex.c @@ -425,17 +425,25 @@ int do_indirect_extended(char *buf, struct iinfo *iinf, int hgt) ** ** Output(s): ** -** Returns: +** Returns: next leaf block, if any, in a chain of leaf blocks ** ******************************************************************************* ******************************************************************************/ -void do_leaf_extended(char *dlebuf, struct iinfo *indir) +uint64_t do_leaf_extended(char *dlebuf, struct iinfo *indir) { int x, i; struct gfs2_dirent de; + struct gfs2_leaf leaf; + struct gfs2_buffer_head tbh; /* kludge */
x = 0; memset(indir, 0, sizeof(*indir)); + tbh.b_data = dlebuf; + gfs2_leaf_in(&leaf, &tbh); + indir->ii[0].lf_depth = leaf.lf_depth; + indir->ii[0].lf_entries = leaf.lf_entries; + indir->ii[0].lf_dirent_format = leaf.lf_dirent_format; + indir->ii[0].lf_next = leaf.lf_next; /* Directory Entries: */ for (i = sizeof(struct gfs2_leaf); i < sbd.bsize; i += de.de_rec_len) { @@ -456,6 +464,7 @@ void do_leaf_extended(char *dlebuf, struct iinfo *indir) if (de.de_rec_len <= sizeof(struct gfs2_dirent)) break; } + return leaf.lf_next; }
diff --git a/gfs2/edit/gfs2hex.h b/gfs2/edit/gfs2hex.h index ebe6b0e..7b98d44 100644 --- a/gfs2/edit/gfs2hex.h +++ b/gfs2/edit/gfs2hex.h @@ -21,7 +21,7 @@ int edit_gfs2(void); void do_dinode_extended(struct gfs2_dinode *di, struct gfs2_buffer_head *lbh); void print_gfs2(const char *fmt, ...); int do_indirect_extended(char *diebuf, struct iinfo *iinf, int hgt); -void do_leaf_extended(char *dlebuf, struct iinfo *indir); +uint64_t do_leaf_extended(char *dlebuf, struct iinfo *indir); void eol(int col);
#endif /* __GFS2HEX_DOT_H__ */ diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c index 8919cef..c7d1849 100644 --- a/gfs2/edit/hexedit.c +++ b/gfs2/edit/hexedit.c @@ -95,6 +95,9 @@ extern void restoremeta(const char *in_fn, const char *out_device, } \ } while(0)
+static int display_indirect(struct iinfo *ind, int indblocks, int level, + uint64_t startoff); + static int gfs2_dinode_printval(struct gfs2_dinode *dip, const char *strfield) { checkprint(strfield, dip, di_mode); @@ -1267,7 +1270,11 @@ static int display_leaf(struct iinfo *ind) if (gfs2_struct_type == GFS2_METATYPE_SB) print_gfs2("The superblock has 2 directories"); else - print_gfs2("This directory block contains %d directory entries.", + print_gfs2("Directory block: lf_depth:%d, lf_entries:%d," + "fmt:%d next=0x%llx (%d dirents).", + ind->ii[0].lf_depth, ind->ii[0].lf_entries, + ind->ii[0].lf_dirent_format, + ind->ii[0].lf_next, ind->ii[0].dirents);
start_line = line; @@ -1276,7 +1283,7 @@ static int display_leaf(struct iinfo *ind) + start_row[dmode]) break; total_dirents++; - if (ind->ii[0].dirents > 1) { + if (ind->ii[0].dirents >= 1) { eol(5); if (termlines) { if (edit_row[dmode] >=0 && @@ -1370,9 +1377,76 @@ static int get_height(void) }
/* ------------------------------------------------------------------------ */ +/* print_block_details */ +/* ------------------------------------------------------------------------ */ +static void print_block_details(struct iinfo *ind, int level, int cur_height, + int pndx, uint64_t file_offset) +{ + struct iinfo *more_indir; + int more_ind; + char *tmpbuf; + uint64_t thisblk; + + thisblk = ind->ii[pndx].block; + more_indir = malloc(sizeof(struct iinfo)); + if (!more_indir) { + fprintf(stderr, "Out of memory in function " + "display_indirect\n"); + return; + } + tmpbuf = malloc(sbd.bsize); + if (!tmpbuf) { + fprintf(stderr, "Out of memory in function " + "display_indirect\n"); + return; + } + while (thisblk) { + lseek(sbd.device_fd, thisblk * sbd.bsize, SEEK_SET); + /* read in the desired block */ + if (read(sbd.device_fd, tmpbuf, sbd.bsize) != sbd.bsize) { + fprintf(stderr, "bad read: %s from %s:%d: block %lld " + "(0x%llx)\n", strerror(errno), __FUNCTION__, + __LINE__, + (unsigned long long)ind->ii[pndx].block, + (unsigned long long)ind->ii[pndx].block); + exit(-1); + } + thisblk = 0; + memset(more_indir, 0, sizeof(struct iinfo)); + if (S_ISDIR(di.di_mode) && level == di.di_height) { + thisblk = do_leaf_extended(tmpbuf, more_indir); + display_leaf(more_indir); + } else { + int x; + + for (x = 0; x < 512; x++) { + memcpy(&more_indir->ii[x].mp, + &ind->ii[pndx].mp, + sizeof(struct metapath)); + more_indir->ii[x].mp.mp_list[cur_height+1] = x; + } + more_ind = do_indirect_extended(tmpbuf, more_indir, + cur_height + 1); + display_indirect(more_indir, more_ind, level + 1, + file_offset); + } + if (thisblk) { + eol(0); + if (termlines) + move(line,9); + print_gfs2("Continuation block 0x%llx / %lld", + thisblk, thisblk); + } + } + free(tmpbuf); + free(more_indir); +} + +/* ------------------------------------------------------------------------ */ /* display_indirect */ /* ------------------------------------------------------------------------ */ -static int display_indirect(struct iinfo *ind, int indblocks, int level, uint64_t startoff) +static int display_indirect(struct iinfo *ind, int indblocks, int level, + uint64_t startoff) { int start_line, total_dirents; int cur_height = -1, pndx; @@ -1388,8 +1462,7 @@ static int display_indirect(struct iinfo *ind, int indblocks, int level, uint64_ else print_gfs2("This inode contains %d indirect blocks", indblocks); - } - else + } else print_gfs2("This indirect block contains %d indirect blocks", indblocks); } @@ -1417,6 +1490,8 @@ static int display_indirect(struct iinfo *ind, int indblocks, int level, uint64_ pndx++) { uint64_t file_offset;
+ if (pndx && ind->ii[pndx].block == ind->ii[pndx - 1].block) + continue; print_entry_ndx = pndx; if (termlines) { if (edit_row[dmode] >= 0 && @@ -1470,53 +1545,9 @@ static int display_indirect(struct iinfo *ind, int indblocks, int level, uint64_ file_offset = 0; if (dinode_valid() && !termlines && ((level + 1 < di.di_height) || - (S_ISDIR(di.di_mode) && !level))) { - struct iinfo *more_indir; - int more_ind; - char *tmpbuf; - - more_indir = malloc(sizeof(struct iinfo)); - tmpbuf = malloc(sbd.bsize); - if (tmpbuf) { - lseek(sbd.device_fd, - ind->ii[pndx].block * sbd.bsize, - SEEK_SET); - /* read in the desired block */ - if (read(sbd.device_fd, tmpbuf, sbd.bsize) != - sbd.bsize) { - fprintf(stderr, "bad read: %s from %s:" - "%d: block %lld (0x%llx)\n", - strerror(errno), - __FUNCTION__, __LINE__, - (unsigned long long)ind->ii[pndx].block, - (unsigned long long)ind->ii[pndx].block); - exit(-1); - } - memset(more_indir, 0, sizeof(struct iinfo)); - if (S_ISDIR(di.di_mode)) { - do_leaf_extended(tmpbuf, more_indir); - display_leaf(more_indir); - } else { - int x; - - for (x = 0; x < 512; x++) { - memcpy(&more_indir->ii[x].mp, - &ind->ii[pndx].mp, - sizeof(struct metapath)); - more_indir->ii[x]. - mp.mp_list[cur_height+1] = - x; - } - more_ind = do_indirect_extended(tmpbuf, - more_indir, - cur_height + 1); - display_indirect(more_indir, - more_ind, level + 1, - file_offset); - } - free(tmpbuf); - } - free(more_indir); + (S_ISDIR(di.di_mode) && level <= di.di_height))) { + print_block_details(ind, level, cur_height, pndx, + file_offset); } print_entry_ndx = pndx; /* restore after recursion */ eol(0); diff --git a/gfs2/edit/hexedit.h b/gfs2/edit/hexedit.h index d78779d..15aa112 100644 --- a/gfs2/edit/hexedit.h +++ b/gfs2/edit/hexedit.h @@ -202,6 +202,10 @@ struct indirect_info { int height; uint64_t block; uint32_t dirents; + uint16_t lf_depth; + uint16_t lf_entries; + uint32_t lf_dirent_format; + uint64_t lf_next; struct metapath mp; struct gfs2_dirents dirent[64]; };
cluster-commits@lists.fedorahosted.org