When printing indirect pointers gfs2_edit doesn't keep track of the
location of the pointer within the indirect block and only prints an
index for each non-zero pointer. Instead, store the offset of each
non-zero pointer and print it when displaying indirect blocks, as it is
done in interactive mode.

Resolves: rhbz#1518938

Signed-off-by: Andrew Price <[email protected]>
---
 gfs2/edit/extended.c | 10 +++++-----
 gfs2/edit/gfs2hex.c  |  2 ++
 gfs2/edit/hexedit.h  |  1 +
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/gfs2/edit/extended.c b/gfs2/edit/extended.c
index e8048532..214fdba4 100644
--- a/gfs2/edit/extended.c
+++ b/gfs2/edit/extended.c
@@ -51,6 +51,7 @@ static int get_height(void)
 static int _do_indirect_extended(char *diebuf, struct iinfo *iinf, int hgt)
 {
        unsigned int x, y;
+       off_t headoff;
        uint64_t p;
        int i_blocks;
 
@@ -62,15 +63,14 @@ static int _do_indirect_extended(char *diebuf, struct iinfo 
*iinf, int hgt)
                iinf->ii[x].dirents = 0;
                memset(&iinf->ii[x].dirent, 0, sizeof(struct gfs2_dirents));
        }
-       for (x = (sbd.gfs1 ? sizeof(struct gfs_indirect):
-                         sizeof(struct gfs2_meta_header)), y = 0;
-                x < sbd.bsize;
-                x += sizeof(uint64_t), y++) {
+       headoff = sbd.gfs1 ? sizeof(struct gfs_indirect) : sizeof(struct 
gfs2_meta_header);
+       for (x = headoff, y = 0; x < sbd.bsize; x += sizeof(uint64_t), y++) {
                p = be64_to_cpu(*(uint64_t *)(diebuf + x));
                if (p) {
                        iinf->ii[i_blocks].block = p;
                        iinf->ii[i_blocks].mp.mp_list[hgt] = i_blocks;
                        iinf->ii[i_blocks].is_dir = FALSE;
+                       iinf->ii[i_blocks].ptroff = (x - headoff) / 
sizeof(uint64_t);
                        i_blocks++;
                }
        }
@@ -177,7 +177,7 @@ static int display_indirect(struct iinfo *ind, int 
indblocks, int level,
                        for (h = 0; h < level; h++)
                                print_gfs2("   ");
                }
-               print_gfs2("%d => ", pndx);
+               print_gfs2("%d: 0x%"PRIx64" => ", pndx, ind->ii[pndx].ptroff);
                if (termlines)
                        move(line,9);
                print_gfs2("0x%"PRIx64" / %"PRId64, ind->ii[pndx].block,
diff --git a/gfs2/edit/gfs2hex.c b/gfs2/edit/gfs2hex.c
index 3d0f10dd..8abadd21 100644
--- a/gfs2/edit/gfs2hex.c
+++ b/gfs2/edit/gfs2hex.c
@@ -255,6 +255,8 @@ void do_dinode_extended(struct gfs2_dinode *dine, struct 
gfs2_buffer_head *lbh)
                                indirect->ii[indirect_blocks].mp.mp_list[0] =
                                        ptroff;
                                indirect->ii[indirect_blocks].is_dir = FALSE;
+                               indirect->ii[indirect_blocks].ptroff =
+                                             (x - sizeof(*dine)) / 
sizeof(uint64_t);
                                indirect_blocks++;
                        }
                        ptroff++;
diff --git a/gfs2/edit/hexedit.h b/gfs2/edit/hexedit.h
index 4f7207b0..d2992d8e 100644
--- a/gfs2/edit/hexedit.h
+++ b/gfs2/edit/hexedit.h
@@ -81,6 +81,7 @@ struct indirect_info {
        struct gfs2_leaf lf;
        struct metapath mp;
        struct gfs2_dirents dirent[64];
+       uint64_t ptroff;
 };
 
 struct iinfo {
-- 
2.13.6

Reply via email to