Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=4e8... Commit: 4e825e58684ed45936cf885b4393c915933270a5 Parent: ff658f227fa956f1f8e68d37ae49579960358cbd Author: Bob Peterson rpeterso@redhat.com AuthorDate: Mon Dec 13 12:34:46 2010 -0600 Committer: Bob Peterson rpeterso@redhat.com CommitterDate: Wed Feb 2 14:36:09 2011 -0600
gfs2_edit: Split extended display functions into extended.c
The gfs2_edit code currently has three modes of interactive display: (1) hex mode, (2) structure display, (3) extended data. This patch breaks the functions related to display mode (3) into its own source file: extended.c. Today, mode (2), structure display, is contained in gfs2hex.c, and (1) hex mode is contained in hexedit.c, which also contains the bulk of the support code.
rhbz#656371 --- gfs2/edit/Makefile | 3 +- gfs2/edit/extended.c | 700 ++++++++++++++++++++++++++++++++++++++++++++++++++ gfs2/edit/extended.h | 8 + gfs2/edit/gfs2hex.c | 66 +---- gfs2/edit/gfs2hex.h | 14 +- gfs2/edit/hexedit.c | 571 ++--------------------------------------- gfs2/edit/hexedit.h | 72 ++++-- 7 files changed, 793 insertions(+), 641 deletions(-)
diff --git a/gfs2/edit/Makefile b/gfs2/edit/Makefile index 7c50c4f..6121791 100644 --- a/gfs2/edit/Makefile +++ b/gfs2/edit/Makefile @@ -14,6 +14,7 @@ TARGET= gfs2_edit
SOURCE= \ + extended.c \ gfs2hex.c \ savemeta.c \ hexedit.c @@ -39,7 +40,7 @@ endif
all: gfs2_edit
-gfs2_edit: ${SOURCE} hexedit.h gfs2hex.h ${LIBS}/libgfs2.a +gfs2_edit: ${SOURCE} hexedit.h extended.h gfs2hex.h ${LIBS}/libgfs2.a ${CC} ${CFLAGS} ${INCLUDE} -L${LIBS} ${LDFLAGS} ${SOURCE} ${LOADLIBES} ${LDLIBS} -lncurses -o $@ -lgfs2
install: all diff --git a/gfs2/edit/extended.c b/gfs2/edit/extended.c new file mode 100644 index 0000000..3c45060 --- /dev/null +++ b/gfs2/edit/extended.c @@ -0,0 +1,700 @@ +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include <string.h> +#include <inttypes.h> +#include <sys/types.h> +#include <linux/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> +#include <curses.h> +#include <term.h> +#include <time.h> +#include <signal.h> +#include <sys/ioctl.h> +#include <sys/mount.h> +#include <dirent.h> + +#include <linux/gfs2_ondisk.h> +#include "copyright.cf" + +#include "hexedit.h" +#include "libgfs2.h" +#include "extended.h" +#include "gfs2hex.h" + +static void print_block_details(struct iinfo *ind, int level, int cur_height, + int pndx, uint64_t file_offset); + +/* ------------------------------------------------------------------------ */ +/* get_height */ +/* ------------------------------------------------------------------------ */ +static int get_height(void) +{ + int cur_height = 0, i; + + if (gfs2_struct_type != GFS2_METATYPE_DI) { + for (i = 0; i <= blockhist && i < 5; i++) { + if (blockstack[(blockhist - i) % + BLOCK_STACK_SIZE].gfs2_struct_type == + GFS2_METATYPE_DI) + break; + cur_height++; + } + } + return cur_height; +} + +/* ------------------------------------------------------------------------ */ +/* _do_indirect_extended */ +/* ------------------------------------------------------------------------ */ +static int _do_indirect_extended(char *diebuf, struct iinfo *iinf, int hgt) +{ + unsigned int x, y; + uint64_t p; + int i_blocks; + + i_blocks = 0; + for (x = 0; x < 512; x++) { + iinf->ii[x].is_dir = 0; + iinf->ii[x].height = 0; + iinf->ii[x].block = 0; + iinf->ii[x].dirents = 0; + memset(&iinf->ii[x].dirent, 0, sizeof(struct gfs2_dirents)); + } + for (x = (gfs1 ? sizeof(struct gfs_indirect): + sizeof(struct gfs2_meta_header)), 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; + i_blocks++; + } + } + return i_blocks; +} + +/* ------------------------------------------------------------------------ */ +/* do_indirect_extended */ +/* ------------------------------------------------------------------------ */ +int do_indirect_extended(char *diebuf, struct iinfo *iinf) +{ + return _do_indirect_extended(diebuf, iinf, get_height()); +} + +/* ------------------------------------------------------------------------ */ +/* dinode_valid - check if we have a dinode in recent history */ +/* ------------------------------------------------------------------------ */ +static int dinode_valid(void) +{ + int i; + + if (gfs2_struct_type == GFS2_METATYPE_DI) + return 1; + for (i = 0; i <= blockhist && i < 5; i++) { + if (blockstack[(blockhist - i) % + BLOCK_STACK_SIZE].gfs2_struct_type == + GFS2_METATYPE_DI) + return 1; + } + return 0; +} + +/* ------------------------------------------------------------------------ */ +/* metapath_to_lblock - convert from metapath, height to logical block */ +/* ------------------------------------------------------------------------ */ +static uint64_t metapath_to_lblock(struct metapath *mp, int hgt) +{ + int h; + uint64_t lblock = 0; + uint64_t factor[GFS2_MAX_META_HEIGHT]; + + if (di.di_height < 2) + return mp->mp_list[0]; + /* figure out multiplication factors for each height */ + memset(&factor, 0, sizeof(factor)); + factor[di.di_height - 1] = 1ull; + for (h = di.di_height - 2; h >= 0; h--) + factor[h] = factor[h + 1] * sbd.sd_inptrs; + for (h = 0; h <= hgt; h++) + lblock += (mp->mp_list[h] * factor[h]); + return lblock; +} + +/* ------------------------------------------------------------------------ */ +/* display_indirect */ +/* ------------------------------------------------------------------------ */ +static int display_indirect(struct iinfo *ind, int indblocks, int level, + uint64_t startoff) +{ + int start_line, total_dirents; + int cur_height = -1, pndx; + + last_entry_onscreen[dmode] = 0; + if (!has_indirect_blocks()) + return -1; + if (!level) { + if (gfs2_struct_type == GFS2_METATYPE_DI) { + if (S_ISDIR(di.di_mode)) + print_gfs2("This directory contains %d indirect blocks", + indblocks); + else + print_gfs2("This inode contains %d indirect blocks", + indblocks); + } else + print_gfs2("This indirect block contains %d indirect blocks", + indblocks); + } + total_dirents = 0; + if (dinode_valid() && !S_ISDIR(di.di_mode)) { + /* See if we are on an inode or have one in history. */ + if (level) + cur_height = level; + else { + cur_height = get_height(); + print_gfs2(" (at height %d of %d)", + cur_height, di.di_height); + } + } + eol(0); + if (!level && indblocks) { + print_gfs2("Indirect blocks:"); + eol(0); + } + start_line = line; + for (pndx = start_row[dmode]; + (!termlines || pndx < termlines - start_line - 1 + + start_row[dmode]) && pndx < indblocks; + 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 && + line - start_line == + edit_row[dmode] - start_row[dmode]) + COLORS_HIGHLIGHT; + move(line, 1); + } + if (!termlines) { + int h; + + for (h = 0; h < level; h++) + print_gfs2(" "); + } + print_gfs2("%d => ", pndx); + if (termlines) + move(line,9); + print_gfs2("0x%llx / %lld", ind->ii[pndx].block, + ind->ii[pndx].block); + if (termlines) { + if (edit_row[dmode] >= 0 && + line - start_line == + edit_row[dmode] - start_row[dmode]) { + sprintf(estring, "%"PRIx64, + ind->ii[print_entry_ndx].block); + strcpy(edit_fmt, "%"PRIx64); + edit_size[dmode] = strlen(estring); + COLORS_NORMAL; + } + } + if (dinode_valid() && !S_ISDIR(di.di_mode)) { + float human_off; + char h; + + file_offset = metapath_to_lblock(&ind->ii[pndx].mp, + cur_height) * + sbd.bsize; + print_gfs2(" "); + h = 'K'; + human_off = (file_offset / 1024.0); + if (human_off > 1024.0) { h = 'M'; human_off /= 1024.0; } + if (human_off > 1024.0) { h = 'G'; human_off /= 1024.0; } + if (human_off > 1024.0) { h = 'T'; human_off /= 1024.0; } + if (human_off > 1024.0) { h = 'P'; human_off /= 1024.0; } + if (human_off > 1024.0) { h = 'E'; human_off /= 1024.0; } + print_gfs2("(data offset 0x%llx / %lld / %6.2f%c)", + file_offset, file_offset, human_off, h); + print_gfs2(" "); + } + else + file_offset = 0; + if (dinode_valid() && !termlines && + ((level + 1 < di.di_height) || + (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); + } /* for each display row */ + if (line >= 7) /* 7 because it was bumped at the end */ + last_entry_onscreen[dmode] = line - 7; + eol(0); + end_row[dmode] = indblocks; + if (end_row[dmode] < last_entry_onscreen[dmode]) + end_row[dmode] = last_entry_onscreen[dmode]; + lines_per_row[dmode] = 1; + return 0; +} + +/* ------------------------------------------------------------------------ */ +/* print_inode_type */ +/* ------------------------------------------------------------------------ */ +static void print_inode_type(__be16 de_type) +{ + if (gfs1) { + switch(de_type) { + case GFS_FILE_NON: + print_gfs2("Unknown"); + break; + case GFS_FILE_REG: + print_gfs2("File "); + break; + case GFS_FILE_DIR: + print_gfs2("Dir "); + break; + case GFS_FILE_LNK: + print_gfs2("Symlink"); + break; + case GFS_FILE_BLK: + print_gfs2("BlkDev "); + break; + case GFS_FILE_CHR: + print_gfs2("ChrDev "); + break; + case GFS_FILE_FIFO: + print_gfs2("Fifo "); + break; + case GFS_FILE_SOCK: + print_gfs2("Socket "); + break; + default: + print_gfs2("%04x ", de_type); + break; + } + return; + } + switch(de_type) { + case DT_UNKNOWN: + print_gfs2("Unknown"); + break; + case DT_REG: + print_gfs2("File "); + break; + case DT_DIR: + print_gfs2("Dir "); + break; + case DT_LNK: + print_gfs2("Symlink"); + break; + case DT_BLK: + print_gfs2("BlkDev "); + break; + case DT_CHR: + print_gfs2("ChrDev "); + break; + case DT_FIFO: + print_gfs2("Fifo "); + break; + case DT_SOCK: + print_gfs2("Socket "); + break; + default: + print_gfs2("%04x ", de_type); + break; + } +} + +/* ------------------------------------------------------------------------ */ +/* display_leaf - display directory leaf */ +/* ------------------------------------------------------------------------ */ +static int display_leaf(struct iinfo *ind) +{ + int start_line, total_dirents = start_row[dmode]; + int d; + + eol(0); + if (gfs2_struct_type == GFS2_METATYPE_SB) + print_gfs2("The superblock has 2 directories"); + else + 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; + for (d = start_row[dmode]; d < ind->ii[0].dirents; d++) { + if (termlines && d >= termlines - start_line - 2 + + start_row[dmode]) + break; + total_dirents++; + if (ind->ii[0].dirents >= 1) { + eol(5); + if (termlines) { + if (edit_row[dmode] >=0 && + line - start_line - 1 == + edit_row[dmode] - start_row[dmode]) { + COLORS_HIGHLIGHT; + sprintf(estring, "%"PRIx64, + ind->ii[0].dirent[d].block); + strcpy(edit_fmt, "%"PRIx64); + } + } + print_gfs2("%d. (%d). %lld (0x%llx): ", + total_dirents, d + 1, + ind->ii[0].dirent[d].block, + ind->ii[0].dirent[d].block); + } + print_inode_type(ind->ii[0].dirent[d].dirent.de_type); + print_gfs2(" %s", ind->ii[0].dirent[d].filename); + if (termlines) { + if (edit_row[dmode] >= 0 && + line - start_line - 1 == edit_row[dmode] - + start_row[dmode]) + COLORS_NORMAL; + } + } + if (line >= 4) + last_entry_onscreen[dmode] = line - 4; + eol(0); + end_row[dmode] = ind->ii[0].dirents; + if (end_row[dmode] < last_entry_onscreen[dmode]) + end_row[dmode] = last_entry_onscreen[dmode]; + return 0; +} + +/* ------------------------------------------------------------------------ */ +/* 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); +} + +/* ------------------------------------------------------------------------ */ +/* gfs_jindex_print - print an jindex entry. */ +/* ------------------------------------------------------------------------ */ +static void gfs_jindex_print(struct gfs_jindex *ji) +{ + pv((unsigned long long)ji, ji_addr, "%llu", "0x%llx"); + pv(ji, ji_nsegment, "%u", "0x%x"); + pv(ji, ji_pad, "%u", "0x%x"); +} + +/* ------------------------------------------------------------------------ */ +/* print_jindex - print the jindex file. */ +/* ------------------------------------------------------------------------ */ +static int print_jindex(struct gfs2_inode *dij) +{ + int error, start_line; + struct gfs_jindex ji; + char jbuf[sizeof(struct gfs_jindex)]; + + start_line = line; + error = 0; + print_gfs2("Journal index entries found: %d.", + dij->i_di.di_size / sizeof(struct gfs_jindex)); + eol(0); + lines_per_row[dmode] = 4; + for (print_entry_ndx=0; ; print_entry_ndx++) { + error = gfs2_readi(dij, (void *)&jbuf, + print_entry_ndx*sizeof(struct gfs_jindex), + sizeof(struct gfs_jindex)); + gfs_jindex_in(&ji, jbuf); + if (!error) /* end of file */ + break; + if (!termlines || + (print_entry_ndx >= start_row[dmode] && + ((print_entry_ndx - start_row[dmode])+1) * + lines_per_row[dmode] <= termlines - start_line - 2)) { + if (edit_row[dmode] == print_entry_ndx) { + COLORS_HIGHLIGHT; + strcpy(efield, "ji_addr"); + sprintf(estring, "%" PRIx64, ji.ji_addr); + } + print_gfs2("Journal #%d", print_entry_ndx); + eol(0); + if (edit_row[dmode] == print_entry_ndx) + COLORS_NORMAL; + gfs_jindex_print(&ji); + last_entry_onscreen[dmode] = print_entry_ndx; + } + } + end_row[dmode] = print_entry_ndx; + return error; +} + +/* ------------------------------------------------------------------------ */ +/* parse_rindex - print the rgindex file. */ +/* ------------------------------------------------------------------------ */ +static int parse_rindex(struct gfs2_inode *dip, int print_rindex) +{ + int error, start_line; + struct gfs2_rindex ri; + char rbuf[sizeof(struct gfs_rindex)]; + char highlighted_addr[32]; + + start_line = line; + error = 0; + print_gfs2("RG index entries found: %d.", dip->i_di.di_size / risize()); + eol(0); + lines_per_row[dmode] = 6; + memset(highlighted_addr, 0, sizeof(highlighted_addr)); + + for (print_entry_ndx=0; ; print_entry_ndx++) { + uint64_t roff; + + roff = print_entry_ndx * risize(); + + if (gfs1) + error = gfs1_readi(dip, (void *)&rbuf, roff, risize()); + else + error = gfs2_readi(dip, (void *)&rbuf, roff, risize()); + if (!error) /* end of file */ + break; + gfs2_rindex_in(&ri, rbuf); + if (!termlines || + (print_entry_ndx >= start_row[dmode] && + ((print_entry_ndx - start_row[dmode])+1) * lines_per_row[dmode] <= + termlines - start_line - 2)) { + if (edit_row[dmode] == print_entry_ndx) { + COLORS_HIGHLIGHT; + sprintf(highlighted_addr, "%llx", (unsigned long long)ri.ri_addr); + } + print_gfs2("RG #%d", print_entry_ndx); + if (!print_rindex) + print_gfs2(" located at: %llu (0x%llx)", + ri.ri_addr, ri.ri_addr); + eol(0); + if (edit_row[dmode] == print_entry_ndx) + COLORS_NORMAL; + if(print_rindex) + gfs2_rindex_print(&ri); + else { + struct gfs2_buffer_head *tmp_bh; + + tmp_bh = bread(&sbd, ri.ri_addr); + if (gfs1) { + struct gfs_rgrp rg1; + gfs_rgrp_in(&rg1, tmp_bh); + gfs_rgrp_print(&rg1); + } else { + struct gfs2_rgrp rg; + gfs2_rgrp_in(&rg, tmp_bh); + gfs2_rgrp_print(&rg); + } + brelse(tmp_bh); + } + last_entry_onscreen[dmode] = print_entry_ndx; + } + } + strcpy(estring, highlighted_addr); + end_row[dmode] = print_entry_ndx; + return error; +} + +/* ------------------------------------------------------------------------ */ +/* print_inum - print the inum file. */ +/* ------------------------------------------------------------------------ */ +static int print_inum(struct gfs2_inode *dii) +{ + uint64_t inum, inodenum; + int rc; + + rc = gfs2_readi(dii, (void *)&inum, 0, sizeof(inum)); + if (!rc) { + print_gfs2("The inum file is empty."); + eol(0); + return 0; + } + if (rc != sizeof(inum)) { + print_gfs2("Error reading inum file."); + eol(0); + return -1; + } + inodenum = be64_to_cpu(inum); + print_gfs2("Next inode num = %lld (0x%llx)", inodenum, inodenum); + eol(0); + return 0; +} + +/* ------------------------------------------------------------------------ */ +/* print_statfs - print the statfs file. */ +/* ------------------------------------------------------------------------ */ +static int print_statfs(struct gfs2_inode *dis) +{ + struct gfs2_statfs_change sfb, sfc; + int rc; + + rc = gfs2_readi(dis, (void *)&sfb, 0, sizeof(sfb)); + if (!rc) { + print_gfs2("The statfs file is empty."); + eol(0); + return 0; + } + if (rc != sizeof(sfb)) { + print_gfs2("Error reading statfs file."); + eol(0); + return -1; + } + gfs2_statfs_change_in(&sfc, (char *)&sfb); + print_gfs2("statfs file contents:"); + eol(0); + gfs2_statfs_change_print(&sfc); + return 0; +} + +/* ------------------------------------------------------------------------ */ +/* print_quota - print the quota file. */ +/* ------------------------------------------------------------------------ */ +static int print_quota(struct gfs2_inode *diq) +{ + struct gfs2_quota qbuf, q; + int i, error; + + print_gfs2("quota file contents:"); + eol(0); + print_gfs2("quota entries found: %d.", diq->i_di.di_size / sizeof(q)); + eol(0); + for (i=0; ; i++) { + error = gfs2_readi(diq, (void *)&qbuf, i * sizeof(q), sizeof(qbuf)); + if (!error) + break; + if (error != sizeof(qbuf)) { + print_gfs2("Error reading quota file."); + eol(0); + return -1; + } + gfs2_quota_in(&q, (char *)&qbuf); + print_gfs2("Entry #%d", i + 1); + eol(0); + gfs2_quota_print(&q); + } + return 0; +} + +/* ------------------------------------------------------------------------ */ +/* display_extended */ +/* ------------------------------------------------------------------------ */ +int display_extended(void) +{ + struct gfs2_inode *tmp_inode; + struct gfs2_buffer_head *tmp_bh; + + dsplines = termlines - line - 1; + /* Display any indirect pointers that we have. */ + if (block_is_rindex()) { + tmp_bh = bread(&sbd, block); + tmp_inode = inode_get(&sbd, tmp_bh); + parse_rindex(tmp_inode, TRUE); + brelse(tmp_bh); + } + else if (has_indirect_blocks() && !indirect_blocks && + !display_leaf(indirect)) + return -1; + else if (display_indirect(indirect, indirect_blocks, 0, 0) == 0) + return -1; + else if (block_is_rglist()) { + if (gfs1) + tmp_bh = bread(&sbd, sbd1->sb_rindex_di.no_addr); + else + tmp_bh = bread(&sbd, masterblock("rindex")); + tmp_inode = inode_get(&sbd, tmp_bh); + parse_rindex(tmp_inode, FALSE); + brelse(tmp_bh); + } + else if (block_is_jindex()) { + tmp_bh = bread(&sbd, block); + tmp_inode = inode_get(&sbd, tmp_bh); + print_jindex(tmp_inode); + brelse(tmp_bh); + } + else if (block_is_inum_file()) { + tmp_bh = bread(&sbd, block); + tmp_inode = inode_get(&sbd, tmp_bh); + print_inum(tmp_inode); + brelse(tmp_bh); + } + else if (block_is_statfs_file()) { + tmp_bh = bread(&sbd, block); + tmp_inode = inode_get(&sbd, tmp_bh); + print_statfs(tmp_inode); + brelse(tmp_bh); + } + else if (block_is_quota_file()) { + tmp_bh = bread(&sbd, block); + tmp_inode = inode_get(&sbd, tmp_bh); + print_quota(tmp_inode); + brelse(tmp_bh); + } + return 0; +} + diff --git a/gfs2/edit/extended.h b/gfs2/edit/extended.h new file mode 100644 index 0000000..cfb67be --- /dev/null +++ b/gfs2/edit/extended.h @@ -0,0 +1,8 @@ +#ifndef __EXTENDED_DOT_H__ +#define __EXTENDED_DOT_H__ + +extern int do_indirect_extended(char *diebuf, struct iinfo *iinf); +extern int display_extended(void); + +#endif + diff --git a/gfs2/edit/gfs2hex.c b/gfs2/edit/gfs2hex.c index 1505783..4b6025a 100644 --- a/gfs2/edit/gfs2hex.c +++ b/gfs2/edit/gfs2hex.c @@ -29,6 +29,7 @@ #define WANT_GFS_CONVERSION_FUNCTIONS #include <linux/gfs2_ondisk.h>
+#include "extended.h" #include "gfs2hex.h" /* from libgfs2: */ #include "libgfs2.h" @@ -40,11 +41,10 @@ print_it(" ", fmt, fmt2, struct->member); \ } while (FALSE);
- struct gfs2_sb sb; struct gfs2_buffer_head *bh; struct gfs2_dinode di; -int line, termlines; +int line, termlines, modelines[DMODES]; char edit_fmt[80]; char estring[1024]; char efield[64]; @@ -127,8 +127,7 @@ void eol(int col) /* end of line */ if (termlines) { line++; move(line, col); - } - else { + } else { printf("\n"); for (; col > 0; col--) printf(" "); @@ -159,12 +158,10 @@ static void check_highlight(int highlight) if (highlight) { COLORS_HIGHLIGHT; last_entry_onscreen[dmode] = print_entry_ndx; - } - else + } else COLORS_NORMAL; } - } - else { + } else { if ((line * lines_per_row[dmode]) - 4 == (edit_row[dmode] - start_row[dmode]) * lines_per_row[dmode]) { if (highlight) { @@ -191,8 +188,7 @@ void print_it(const char *label, const char *fmt, const char *fmt2, ...) move(line,0); printw("%s", label); move(line,24); - } - else { + } else { if (!strcmp(label, " ")) printf("%-11s", label); else @@ -215,16 +211,14 @@ void print_it(const char *label, const char *fmt, const char *fmt2, ...) if (termlines) { move(line, 50); printw("%s", tmp_string); - } - else { + } else { int i; for (i=20 - decimalsize; i > 0; i--) printf(" "); printf("%s", tmp_string); } check_highlight(FALSE); - } - else { + } else { if (strstr(fmt,"X") || strstr(fmt,"x")) fmtstring="(hex)"; else if (strstr(fmt,"s")) @@ -373,50 +367,6 @@ void do_dinode_extended(struct gfs2_dinode *dine, struct gfs2_buffer_head *lbh) /****************************************************************************** ******************************************************************************* ** -** do_indirect_extended() -** -** Description: -** -** Input(s): -** -** Output(s): -** -** Returns: -** -******************************************************************************* -******************************************************************************/ -int do_indirect_extended(char *buf, struct iinfo *iinf, int hgt) -{ - unsigned int x, y; - uint64_t p; - int i_blocks; - - i_blocks = 0; - for (x = 0; x < 512; x++) { - iinf->ii[x].is_dir = 0; - iinf->ii[x].height = 0; - iinf->ii[x].block = 0; - iinf->ii[x].dirents = 0; - memset(&iinf->ii[x].dirent, 0, sizeof(struct gfs2_dirents)); - } - for (x = (gfs1 ? sizeof(struct gfs_indirect): - sizeof(struct gfs2_meta_header)), y = 0; - x < sbd.bsize; - x += sizeof(uint64_t), y++) { - p = be64_to_cpu(*(uint64_t *)(buf + 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; - i_blocks++; - } - } - return i_blocks; -} - -/****************************************************************************** -******************************************************************************* -** ** do_leaf_extended() ** ** Description: diff --git a/gfs2/edit/gfs2hex.h b/gfs2/edit/gfs2hex.h index 7b98d44..04db331 100644 --- a/gfs2/edit/gfs2hex.h +++ b/gfs2/edit/gfs2hex.h @@ -16,12 +16,12 @@
#include "hexedit.h"
-int display_gfs2(void); -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); -uint64_t do_leaf_extended(char *dlebuf, struct iinfo *indir); -void eol(int col); +extern int display_gfs2(void); +extern int edit_gfs2(void); +extern void do_dinode_extended(struct gfs2_dinode *di, + struct gfs2_buffer_head *lbh); +extern void print_gfs2(const char *fmt, ...); +extern uint64_t do_leaf_extended(char *dlebuf, struct iinfo *indir); +extern void eol(int col);
#endif /* __GFS2HEX_DOT_H__ */ diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c index 1c3fafe..17a2962 100644 --- a/gfs2/edit/hexedit.c +++ b/gfs2/edit/hexedit.c @@ -37,14 +37,7 @@ #include "hexedit.h" #include "libgfs2.h" #include "gfs2hex.h" - -#include <syslog.h> - -#define RGLIST_DUMMY_BLOCK -2 - -#define pv(struct, member, fmt, fmt2) do { \ - print_it(" "#member, fmt, fmt2, struct->member); \ - } while (FALSE); +#include "extended.h"
const char *mtypes[] = {"none", "sb", "rg", "rb", "di", "in", "lf", "jd", "lh", "ld", "ea", "ed", "lb", "13", "qc"}; @@ -95,9 +88,6 @@ 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); @@ -675,11 +665,9 @@ static int hexdump(uint64_t startaddr, int len) ptr2 = (unsigned char *)lpBuffer + offset; l = offset; print_entry_ndx = 0; - while (((termlines && - line < termlines && - line <= ((screen_chunk_size / 16) + 2)) || - (!termlines && l < len)) && - l < sbd.bsize) { + while (((termlines && line < termlines && + line <= ((screen_chunk_size / 16) + 2)) || + (!termlines && l < len)) && l < sbd.bsize) { int ptr_not_null = 0;
if (termlines) { @@ -792,17 +780,6 @@ uint64_t masterblock(const char *fn) }
/* ------------------------------------------------------------------------ */ -/* risize - size of one rindex entry, whether gfs1 or gfs2 */ -/* ------------------------------------------------------------------------ */ -static int risize(void) -{ - if (gfs1) - return sizeof(struct gfs_rindex); - else - return sizeof(struct gfs2_rindex); -} - -/* ------------------------------------------------------------------------ */ /* rgcount - return how many rgrps there are. */ /* ------------------------------------------------------------------------ */ static void rgcount(void) @@ -842,7 +819,7 @@ static uint64_t find_rgrp_block(struct gfs2_inode *dif, int rg) /* ------------------------------------------------------------------------ */ /* gfs_rgrp_in - Read in a resource group header */ /* ------------------------------------------------------------------------ */ -static void gfs_rgrp_in(struct gfs_rgrp *rgrp, struct gfs2_buffer_head *rbh) +void gfs_rgrp_in(struct gfs_rgrp *rgrp, struct gfs2_buffer_head *rbh) { struct gfs_rgrp *str = (struct gfs_rgrp *)rbh->b_data;
@@ -876,7 +853,7 @@ static void gfs_rgrp_out(struct gfs_rgrp *rgrp, struct gfs2_buffer_head *rbh) /* ------------------------------------------------------------------------ */ /* gfs_rgrp_print - print a gfs1 resource group */ /* ------------------------------------------------------------------------ */ -static void gfs_rgrp_print(struct gfs_rgrp *rg) +void gfs_rgrp_print(struct gfs_rgrp *rg) { gfs2_meta_header_print(&rg->rg_header); pv(rg, rg_flags, "%u", "0x%x"); @@ -963,75 +940,6 @@ static void set_rgrp_flags(int rgnum, uint32_t new_flags, int modify, int full) }
/* ------------------------------------------------------------------------ */ -/* parse_rindex - print the rgindex file. */ -/* ------------------------------------------------------------------------ */ -static int parse_rindex(struct gfs2_inode *dip, int print_rindex) -{ - int error, start_line; - struct gfs2_rindex ri; - char rbuf[sizeof(struct gfs_rindex)]; - char highlighted_addr[32]; - - start_line = line; - error = 0; - print_gfs2("RG index entries found: %d.", dip->i_di.di_size / risize()); - eol(0); - lines_per_row[dmode] = 6; - memset(highlighted_addr, 0, sizeof(highlighted_addr)); - - for (print_entry_ndx=0; ; print_entry_ndx++) { - uint64_t roff; - - roff = print_entry_ndx * risize(); - - if (gfs1) - error = gfs1_readi(dip, (void *)&rbuf, roff, risize()); - else - error = gfs2_readi(dip, (void *)&rbuf, roff, risize()); - if (!error) /* end of file */ - break; - gfs2_rindex_in(&ri, rbuf); - if (!termlines || - (print_entry_ndx >= start_row[dmode] && - ((print_entry_ndx - start_row[dmode])+1) * lines_per_row[dmode] <= - termlines - start_line - 2)) { - if (edit_row[dmode] == print_entry_ndx) { - COLORS_HIGHLIGHT; - sprintf(highlighted_addr, "%llx", (unsigned long long)ri.ri_addr); - } - print_gfs2("RG #%d", print_entry_ndx); - if (!print_rindex) - print_gfs2(" located at: %llu (0x%llx)", - ri.ri_addr, ri.ri_addr); - eol(0); - if (edit_row[dmode] == print_entry_ndx) - COLORS_NORMAL; - if(print_rindex) - gfs2_rindex_print(&ri); - else { - struct gfs2_buffer_head *tmp_bh; - - tmp_bh = bread(&sbd, ri.ri_addr); - if (gfs1) { - struct gfs_rgrp rg1; - gfs_rgrp_in(&rg1, tmp_bh); - gfs_rgrp_print(&rg1); - } else { - struct gfs2_rgrp rg; - gfs2_rgrp_in(&rg, tmp_bh); - gfs2_rgrp_print(&rg); - } - brelse(tmp_bh); - } - last_entry_onscreen[dmode] = print_entry_ndx; - } - } - strcpy(estring, highlighted_addr); - end_row[dmode] = print_entry_ndx; - return error; -} - -/* ------------------------------------------------------------------------ */ /* gfs_jindex_in - read in a gfs1 jindex structure. */ /* ------------------------------------------------------------------------ */ void gfs_jindex_in(struct gfs_jindex *jindex, char *jbuf) @@ -1045,142 +953,9 @@ void gfs_jindex_in(struct gfs_jindex *jindex, char *jbuf) }
/* ------------------------------------------------------------------------ */ -/* gfs_jindex_print - print an jindex entry. */ -/* ------------------------------------------------------------------------ */ -static void gfs_jindex_print(struct gfs_jindex *ji) -{ - pv((unsigned long long)ji, ji_addr, "%llu", "0x%llx"); - pv(ji, ji_nsegment, "%u", "0x%x"); - pv(ji, ji_pad, "%u", "0x%x"); -} - -/* ------------------------------------------------------------------------ */ -/* print_jindex - print the jindex file. */ -/* ------------------------------------------------------------------------ */ -static int print_jindex(struct gfs2_inode *dij) -{ - int error, start_line; - struct gfs_jindex ji; - char jbuf[sizeof(struct gfs_jindex)]; - - start_line = line; - error = 0; - print_gfs2("Journal index entries found: %d.", - dij->i_di.di_size / sizeof(struct gfs_jindex)); - eol(0); - lines_per_row[dmode] = 4; - for (print_entry_ndx=0; ; print_entry_ndx++) { - error = gfs2_readi(dij, (void *)&jbuf, - print_entry_ndx*sizeof(struct gfs_jindex), - sizeof(struct gfs_jindex)); - gfs_jindex_in(&ji, jbuf); - if (!error) /* end of file */ - break; - if (!termlines || - (print_entry_ndx >= start_row[dmode] && - ((print_entry_ndx - start_row[dmode])+1) * - lines_per_row[dmode] <= termlines - start_line - 2)) { - if (edit_row[dmode] == print_entry_ndx) { - COLORS_HIGHLIGHT; - strcpy(efield, "ji_addr"); - sprintf(estring, "%" PRIx64, ji.ji_addr); - } - print_gfs2("Journal #%d", print_entry_ndx); - eol(0); - if (edit_row[dmode] == print_entry_ndx) - COLORS_NORMAL; - gfs_jindex_print(&ji); - last_entry_onscreen[dmode] = print_entry_ndx; - } - } - end_row[dmode] = print_entry_ndx; - return error; -} - -/* ------------------------------------------------------------------------ */ -/* print_inum - print the inum file. */ -/* ------------------------------------------------------------------------ */ -static int print_inum(struct gfs2_inode *dii) -{ - uint64_t inum, inodenum; - int rc; - - rc = gfs2_readi(dii, (void *)&inum, 0, sizeof(inum)); - if (!rc) { - print_gfs2("The inum file is empty."); - eol(0); - return 0; - } - if (rc != sizeof(inum)) { - print_gfs2("Error reading inum file."); - eol(0); - return -1; - } - inodenum = be64_to_cpu(inum); - print_gfs2("Next inode num = %lld (0x%llx)", inodenum, inodenum); - eol(0); - return 0; -} - -/* ------------------------------------------------------------------------ */ -/* print_statfs - print the statfs file. */ -/* ------------------------------------------------------------------------ */ -static int print_statfs(struct gfs2_inode *dis) -{ - struct gfs2_statfs_change sfb, sfc; - int rc; - - rc = gfs2_readi(dis, (void *)&sfb, 0, sizeof(sfb)); - if (!rc) { - print_gfs2("The statfs file is empty."); - eol(0); - return 0; - } - if (rc != sizeof(sfb)) { - print_gfs2("Error reading statfs file."); - eol(0); - return -1; - } - gfs2_statfs_change_in(&sfc, (char *)&sfb); - print_gfs2("statfs file contents:"); - eol(0); - gfs2_statfs_change_print(&sfc); - return 0; -} - -/* ------------------------------------------------------------------------ */ -/* print_quota - print the quota file. */ -/* ------------------------------------------------------------------------ */ -static int print_quota(struct gfs2_inode *diq) -{ - struct gfs2_quota qbuf, q; - int i, error; - - print_gfs2("quota file contents:"); - eol(0); - print_gfs2("quota entries found: %d.", diq->i_di.di_size / sizeof(q)); - eol(0); - for (i=0; ; i++) { - error = gfs2_readi(diq, (void *)&qbuf, i * sizeof(q), sizeof(qbuf)); - if (!error) - break; - if (error != sizeof(qbuf)) { - print_gfs2("Error reading quota file."); - eol(0); - return -1; - } - gfs2_quota_in(&q, (char *)&qbuf); - print_gfs2("Entry #%d", i + 1); - eol(0); - gfs2_quota_print(&q); - } - return 0; -} - -/* ------------------------------------------------------------------------ */ /* has_indirect_blocks */ /* ------------------------------------------------------------------------ */ -static int has_indirect_blocks(void) +int has_indirect_blocks(void) { if (indirect_blocks || gfs2_struct_type == GFS2_METATYPE_SB || gfs2_struct_type == GFS2_METATYPE_LF || @@ -1261,7 +1036,7 @@ static void print_inode_type(__be16 de_type) /* ------------------------------------------------------------------------ */ /* display_leaf - display directory leaf */ /* ------------------------------------------------------------------------ */ -static int display_leaf(struct iinfo *ind) +int display_leaf(struct iinfo *ind) { int start_line, total_dirents = start_row[dmode]; int d; @@ -1319,250 +1094,6 @@ static int display_leaf(struct iinfo *ind) }
/* ------------------------------------------------------------------------ */ -/* metapath_to_lblock - convert from metapath, height to logical block */ -/* ------------------------------------------------------------------------ */ -static uint64_t metapath_to_lblock(struct metapath *mp, int hgt) -{ - int h; - uint64_t lblock = 0; - uint64_t factor[GFS2_MAX_META_HEIGHT]; - - if (di.di_height < 2) - return mp->mp_list[0]; - /* figure out multiplication factors for each height */ - memset(&factor, 0, sizeof(factor)); - factor[di.di_height - 1] = 1ull; - for (h = di.di_height - 2; h >= 0; h--) - factor[h] = factor[h + 1] * sbd.sd_inptrs; - for (h = 0; h <= hgt; h++) - lblock += (mp->mp_list[h] * factor[h]); - return lblock; -} - -/* ------------------------------------------------------------------------ */ -/* dinode_valid - check if we have a dinode in recent history */ -/* ------------------------------------------------------------------------ */ -static int dinode_valid(void) -{ - int i; - - if (gfs2_struct_type == GFS2_METATYPE_DI) - return 1; - for (i = 0; i <= blockhist && i < 5; i++) { - if (blockstack[(blockhist - i) % - BLOCK_STACK_SIZE].gfs2_struct_type == - GFS2_METATYPE_DI) - return 1; - } - return 0; -} - -/* ------------------------------------------------------------------------ */ -/* get_height */ -/* ------------------------------------------------------------------------ */ -static int get_height(void) -{ - int cur_height = 0, i; - - if (gfs2_struct_type != GFS2_METATYPE_DI) { - for (i = 0; i <= blockhist && i < 5; i++) { - if (blockstack[(blockhist - i) % - BLOCK_STACK_SIZE].gfs2_struct_type == - GFS2_METATYPE_DI) - break; - cur_height++; - } - } - return cur_height; -} - -/* ------------------------------------------------------------------------ */ -/* 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) -{ - int start_line, total_dirents; - int cur_height = -1, pndx; - - last_entry_onscreen[dmode] = 0; - if (!has_indirect_blocks()) - return -1; - if (!level) { - if (gfs2_struct_type == GFS2_METATYPE_DI) { - if (S_ISDIR(di.di_mode)) - print_gfs2("This directory contains %d indirect blocks", - indblocks); - else - print_gfs2("This inode contains %d indirect blocks", - indblocks); - } else - print_gfs2("This indirect block contains %d indirect blocks", - indblocks); - } - total_dirents = 0; - if (dinode_valid() && !S_ISDIR(di.di_mode)) { - /* See if we are on an inode or have one in history. */ - if (level) - cur_height = level; - else { - cur_height = get_height(); - print_gfs2(" (at height %d of %d)", - cur_height, di.di_height); - } - } - eol(0); - if (!level && indblocks) { - print_gfs2("Indirect blocks:"); - eol(0); - } - start_line = line; - dsplines = termlines - line - 1; - for (pndx = start_row[dmode]; - (!termlines || pndx < termlines - start_line - 1 - + start_row[dmode]) && pndx < indblocks; - 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 && - line - start_line == - edit_row[dmode] - start_row[dmode]) - COLORS_HIGHLIGHT; - move(line, 1); - } - if (!termlines) { - int h; - - for (h = 0; h < level; h++) - print_gfs2(" "); - } - print_gfs2("%d => ", pndx); - if (termlines) - move(line,9); - print_gfs2("0x%llx / %lld", ind->ii[pndx].block, - ind->ii[pndx].block); - if (termlines) { - if (edit_row[dmode] >= 0 && - line - start_line == - edit_row[dmode] - start_row[dmode]) { - sprintf(estring, "%"PRIx64, - ind->ii[print_entry_ndx].block); - strcpy(edit_fmt, "%"PRIx64); - edit_size[dmode] = strlen(estring); - COLORS_NORMAL; - } - } - if (dinode_valid() && !S_ISDIR(di.di_mode)) { - float human_off; - char h; - - file_offset = metapath_to_lblock(&ind->ii[pndx].mp, - cur_height) * - sbd.bsize; - print_gfs2(" "); - h = 'K'; - human_off = (file_offset / 1024.0); - if (human_off > 1024.0) { h = 'M'; human_off /= 1024.0; } - if (human_off > 1024.0) { h = 'G'; human_off /= 1024.0; } - if (human_off > 1024.0) { h = 'T'; human_off /= 1024.0; } - if (human_off > 1024.0) { h = 'P'; human_off /= 1024.0; } - if (human_off > 1024.0) { h = 'E'; human_off /= 1024.0; } - print_gfs2("(data offset 0x%llx / %lld / %6.2f%c)", - file_offset, file_offset, human_off, h); - print_gfs2(" "); - } - else - file_offset = 0; - if (dinode_valid() && !termlines && - ((level + 1 < di.di_height) || - (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); - } /* for each display row */ - if (line >= 7) /* 7 because it was bumped at the end */ - last_entry_onscreen[dmode] = line - 7; - eol(0); - end_row[dmode] = indblocks; - if (end_row[dmode] < last_entry_onscreen[dmode]) - end_row[dmode] = last_entry_onscreen[dmode]; - lines_per_row[dmode] = 1; - return 0; -} - -/* ------------------------------------------------------------------------ */ /* block_is_rindex */ /* ------------------------------------------------------------------------ */ int block_is_rindex(void) @@ -1574,18 +1105,6 @@ int block_is_rindex(void) }
/* ------------------------------------------------------------------------ */ -/* block_is_rglist - there's no such block as the rglist. This is a */ -/* special case meant to parse the rindex and follow the */ -/* blocks to the real rgs. */ -/* ------------------------------------------------------------------------ */ -static int block_is_rglist(void) -{ - if (block == RGLIST_DUMMY_BLOCK) - return TRUE; - return FALSE; -} - -/* ------------------------------------------------------------------------ */ /* block_is_jindex */ /* ------------------------------------------------------------------------ */ int block_is_jindex(void) @@ -1679,63 +1198,6 @@ static int block_has_extended_info(void) }
/* ------------------------------------------------------------------------ */ -/* display_extended */ -/* ------------------------------------------------------------------------ */ -static int display_extended(void) -{ - struct gfs2_inode *tmp_inode; - struct gfs2_buffer_head *tmp_bh; - - /* Display any indirect pointers that we have. */ - if (block_is_rindex()) { - tmp_bh = bread(&sbd, block); - tmp_inode = inode_get(&sbd, tmp_bh); - parse_rindex(tmp_inode, TRUE); - brelse(tmp_bh); - } - else if (has_indirect_blocks() && !indirect_blocks && - !display_leaf(indirect)) - return -1; - else if (display_indirect(indirect, indirect_blocks, 0, 0) == 0) - return -1; - else if (block_is_rglist()) { - if (gfs1) - tmp_bh = bread(&sbd, - sbd1->sb_rindex_di.no_addr); - else - tmp_bh = bread(&sbd, masterblock("rindex")); - tmp_inode = inode_get(&sbd, tmp_bh); - parse_rindex(tmp_inode, FALSE); - brelse(tmp_bh); - } - else if (block_is_jindex()) { - tmp_bh = bread(&sbd, block); - tmp_inode = inode_get(&sbd, tmp_bh); - print_jindex(tmp_inode); - brelse(tmp_bh); - } - else if (block_is_inum_file()) { - tmp_bh = bread(&sbd, block); - tmp_inode = inode_get(&sbd, tmp_bh); - print_inum(tmp_inode); - brelse(tmp_bh); - } - else if (block_is_statfs_file()) { - tmp_bh = bread(&sbd, block); - tmp_inode = inode_get(&sbd, tmp_bh); - print_statfs(tmp_inode); - brelse(tmp_bh); - } - else if (block_is_quota_file()) { - tmp_bh = bread(&sbd, block); - tmp_inode = inode_get(&sbd, tmp_bh); - print_quota(tmp_inode); - brelse(tmp_bh); - } - return 0; -} - -/* ------------------------------------------------------------------------ */ /* read_superblock - read the superblock */ /* ------------------------------------------------------------------------ */ static void read_superblock(int fd) @@ -1889,16 +1351,15 @@ int display(int identify_only) do_dinode_extended(&di, bh); /* get extended data, if any */ } else if (gfs2_struct_type == GFS2_METATYPE_IN) { /* indirect block list */ - int i, hgt = get_height(); - if (blockhist) { + int i; + for (i = 0; i < 512; i++) memcpy(&indirect->ii[i].mp, &blockstack[blockhist - 1].mp, sizeof(struct metapath)); } - indirect_blocks = do_indirect_extended(bh->b_data, indirect, - hgt); + indirect_blocks = do_indirect_extended(bh->b_data, indirect); } else if (gfs2_struct_type == GFS2_METATYPE_LF) { /* directory leaf */ do_leaf_extended(bh->b_data, indirect); @@ -2303,16 +1764,16 @@ static void hex_edit(int *exitch) left_off = ((block * sbd.bsize) < 0xffffffff) ? 9 : 17; /* 8 and 16 char addresses on screen */ - if (bobgets(estring, edit_row[dmode] + 3, - (edit_col[dmode] * 2) + (edit_col[dmode] / 4) + left_off, - 2, exitch)) { + if (bobgets(estring, edit_row[HEX_MODE] + 3, + (edit_col[HEX_MODE] * 2) + (edit_col[HEX_MODE] / 4) + + left_off, 2, exitch)) { if (strstr(edit_fmt,"X") || strstr(edit_fmt,"x")) { int hexoffset; int i, sl = strlen(estring); for (i = 0; i < sl; i+=2) { - hexoffset = (edit_row[dmode] * 16) + - edit_col[dmode] + (i / 2); + hexoffset = (edit_row[HEX_MODE] * 16) + + edit_col[HEX_MODE] + (i / 2); ch = 0x00; if (isdigit(estring[i])) ch = (estring[i] - '0') * 0x10; diff --git a/gfs2/edit/hexedit.h b/gfs2/edit/hexedit.h index 15aa112..8d2e9b8 100644 --- a/gfs2/edit/hexedit.h +++ b/gfs2/edit/hexedit.h @@ -66,6 +66,12 @@ enum dsp_mode { HEX_MODE = 0, GFS2_MODE = 1, EXTENDED_MODE = 2, INIT_MODE = 3 }; #define GFS_LOG_DESC_Q (402) /* quota */ #define GFS_LOG_DESC_LAST (500) /* final in a logged transaction */
+#define pv(struct, member, fmt, fmt2) do { \ + print_it(" "#member, fmt, fmt2, struct->member); \ + } while (FALSE); +#define RGLIST_DUMMY_BLOCK -2 + +extern struct gfs2_sb sb; extern uint64_t block; extern int blockhist; extern int edit_mode; @@ -171,26 +177,6 @@ struct gfs_rgrp { char rg_reserved[64]; };
-extern int block_is_jindex(void); -extern int block_is_rindex(void); -extern int block_is_inum_file(void); -extern int block_is_statfs_file(void); -extern int block_is_quota_file(void); -extern int block_is_per_node(void); -extern int block_is_in_per_node(void); -extern int display_block_type(int from_restore); -extern void gfs_jindex_in(struct gfs_jindex *jindex, char *buf); -extern void gfs_log_header_in(struct gfs_log_header *head, - struct gfs2_buffer_head *bh); -extern void gfs_log_header_print(struct gfs_log_header *lh); -extern void gfs_dinode_in(struct gfs_dinode *di, struct gfs2_buffer_head *bh); -extern void savemeta(char *out_fn, int saveoption); -extern void restoremeta(const char *in_fn, const char *out_device, - uint64_t printblocksonly); -extern int display(int identify_only); -extern uint64_t check_keywords(const char *kword); -extern uint64_t masterblock(const char *fn); - struct gfs2_dirents { uint64_t block; struct gfs2_dirent dirent; @@ -262,6 +248,29 @@ extern struct indirect_info masterdir; /* Master directory info */ extern int indirect_blocks; /* count of indirect blocks */ extern enum dsp_mode dmode;
+/* ------------------------------------------------------------------------ */ +/* risize - size of one rindex entry, whether gfs1 or gfs2 */ +/* ------------------------------------------------------------------------ */ +static inline int risize(void) +{ + if (gfs1) + return sizeof(struct gfs_rindex); + else + return sizeof(struct gfs2_rindex); +} + +/* ------------------------------------------------------------------------ */ +/* block_is_rglist - there's no such block as the rglist. This is a */ +/* special case meant to parse the rindex and follow the */ +/* blocks to the real rgs. */ +/* ------------------------------------------------------------------------ */ +static inline int block_is_rglist(void) +{ + if (block == RGLIST_DUMMY_BLOCK) + return TRUE; + return FALSE; +} + #define SCREEN_HEIGHT (16) #define SCREEN_WIDTH (16)
@@ -341,4 +350,27 @@ extern enum dsp_mode dmode; } \ } while (0)
+extern int block_is_jindex(void); +extern int block_is_rindex(void); +extern int block_is_inum_file(void); +extern int block_is_statfs_file(void); +extern int block_is_quota_file(void); +extern int block_is_per_node(void); +extern int block_is_in_per_node(void); +extern int display_block_type(int from_restore); +extern void gfs_jindex_in(struct gfs_jindex *jindex, char *buf); +extern void gfs_log_header_in(struct gfs_log_header *head, + struct gfs2_buffer_head *bh); +extern void gfs_log_header_print(struct gfs_log_header *lh); +extern void gfs_dinode_in(struct gfs_dinode *di, struct gfs2_buffer_head *bh); +extern void savemeta(char *out_fn, int saveoption); +extern void restoremeta(const char *in_fn, const char *out_device, + uint64_t printblocksonly); +extern int display(int identify_only); +extern uint64_t check_keywords(const char *kword); +extern uint64_t masterblock(const char *fn); +extern void gfs_rgrp_print(struct gfs_rgrp *rg); +extern void gfs_rgrp_in(struct gfs_rgrp *rgrp, struct gfs2_buffer_head *rbh); +extern int has_indirect_blocks(void); + #endif /* __HEXVIEW_DOT_H__ */
cluster-commits@lists.fedorahosted.org