cluster: RHEL57 - gfs2_edit: better printing of directory leaf information
Bob Peterson
rpeterso at fedoraproject.org
Wed Feb 2 21:15:39 UTC 2011
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=c9c57f5f0409743435e171c57cc7e59bd0b09cac
Commit: c9c57f5f0409743435e171c57cc7e59bd0b09cac
Parent: 3575517393317423b10a9717fc5157261993625d
Author: Bob Peterson <rpeterso at redhat.com>
AuthorDate: Mon Dec 13 10:42:38 2010 -0600
Committer: Bob Peterson <rpeterso at 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];
};
More information about the cluster-commits
mailing list