|
Packit |
6ef888 |
#include "clusterautoconfig.h"
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
#include <stdio.h>
|
|
Packit |
6ef888 |
#include <stdlib.h>
|
|
Packit |
6ef888 |
#include <ctype.h>
|
|
Packit |
6ef888 |
#include <string.h>
|
|
Packit |
6ef888 |
#include <inttypes.h>
|
|
Packit |
6ef888 |
#include <sys/types.h>
|
|
Packit |
6ef888 |
#include <linux/types.h>
|
|
Packit |
6ef888 |
#include <sys/stat.h>
|
|
Packit |
6ef888 |
#include <fcntl.h>
|
|
Packit |
6ef888 |
#include <unistd.h>
|
|
Packit |
6ef888 |
#include <errno.h>
|
|
Packit |
6ef888 |
#include <curses.h>
|
|
Packit |
6ef888 |
#include <term.h>
|
|
Packit |
6ef888 |
#include <time.h>
|
|
Packit |
6ef888 |
#include <signal.h>
|
|
Packit |
6ef888 |
#include <sys/ioctl.h>
|
|
Packit |
6ef888 |
#include <sys/mount.h>
|
|
Packit |
6ef888 |
#include <dirent.h>
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
#include <linux/gfs2_ondisk.h>
|
|
Packit |
6ef888 |
#include "copyright.cf"
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
#include "hexedit.h"
|
|
Packit |
6ef888 |
#include "libgfs2.h"
|
|
Packit |
6ef888 |
#include "gfs2hex.h"
|
|
Packit |
6ef888 |
#include "extended.h"
|
|
Packit |
6ef888 |
#include "journal.h"
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
const char *mtypes[] = {"none", "sb", "rg", "rb", "di", "in", "lf", "jd",
|
|
Packit |
6ef888 |
"lh", "ld", "ea", "ed", "lb", "13", "qc"};
|
|
Packit |
6ef888 |
const char *allocdesc[2][5] = {
|
|
Packit |
6ef888 |
{"Free ", "Data ", "Unlnk", "Meta ", "Resrv"},
|
|
Packit |
6ef888 |
{"Free ", "Data ", "FreeM", "Meta ", "Resrv"},};
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
struct gfs2_buffer_head *bh;
|
|
Packit |
6ef888 |
struct gfs2_rgrp *lrgrp;
|
|
Packit |
6ef888 |
struct gfs2_meta_header *lmh;
|
|
Packit |
6ef888 |
struct gfs2_dinode *ldi;
|
|
Packit |
6ef888 |
struct gfs2_leaf *lleaf;
|
|
Packit |
6ef888 |
struct gfs2_log_header *llh;
|
|
Packit |
6ef888 |
struct gfs2_log_descriptor *lld;
|
|
Packit |
6ef888 |
int pgnum;
|
|
Packit |
6ef888 |
int details = 0;
|
|
Packit |
6ef888 |
long int gziplevel = 9;
|
|
Packit |
6ef888 |
static int termcols;
|
|
Packit |
6ef888 |
char *device = NULL;
|
|
Packit |
6ef888 |
extern uint64_t block;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------- */
|
|
Packit |
6ef888 |
/* erase - clear the screen */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------- */
|
|
Packit |
6ef888 |
static void Erase(void)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
bkgd(A_NORMAL|COLOR_PAIR(COLOR_NORMAL));
|
|
Packit |
6ef888 |
/* clear();*/ /* doesn't set background correctly */
|
|
Packit |
6ef888 |
erase();
|
|
Packit |
6ef888 |
/*bkgd(bg);*/
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------- */
|
|
Packit |
6ef888 |
/* display_title_lines */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------- */
|
|
Packit |
6ef888 |
static void display_title_lines(void)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
Erase();
|
|
Packit |
6ef888 |
COLORS_TITLE;
|
|
Packit |
6ef888 |
move(0, 0);
|
|
Packit |
6ef888 |
printw("%-80s",TITLE1);
|
|
Packit |
6ef888 |
move(termlines, 0);
|
|
Packit |
6ef888 |
printw("%-79s",TITLE2);
|
|
Packit |
6ef888 |
COLORS_NORMAL;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------- */
|
|
Packit |
6ef888 |
/* bobgets - get a string */
|
|
Packit |
6ef888 |
/* returns: 1 if user exited by hitting enter */
|
|
Packit |
6ef888 |
/* 0 if user exited by hitting escape */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------- */
|
|
Packit |
6ef888 |
static int bobgets(char string[],int x,int y,int sz,int *ch)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
int done,runningy,rc;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
move(x,y);
|
|
Packit |
6ef888 |
done=FALSE;
|
|
Packit |
6ef888 |
COLORS_INVERSE;
|
|
Packit |
6ef888 |
move(x,y);
|
|
Packit |
6ef888 |
addstr(string);
|
|
Packit |
6ef888 |
move(x,y);
|
|
Packit |
6ef888 |
curs_set(2);
|
|
Packit |
6ef888 |
refresh();
|
|
Packit |
6ef888 |
runningy=y;
|
|
Packit |
6ef888 |
rc=0;
|
|
Packit |
6ef888 |
while (!done) {
|
|
Packit |
6ef888 |
*ch = getch();
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if(*ch < 0x0100 && isprint(*ch)) {
|
|
Packit |
6ef888 |
char *p=string+strlen(string); // end of the string
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
*(p+1)='\0';
|
|
Packit |
6ef888 |
while (insert && p > &string[runningy-y]) {
|
|
Packit |
6ef888 |
*p=*(p-1);
|
|
Packit |
6ef888 |
p--;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
string[runningy-y]=*ch;
|
|
Packit |
6ef888 |
runningy++;
|
|
Packit |
6ef888 |
move(x,y);
|
|
Packit |
6ef888 |
addstr(string);
|
|
Packit |
6ef888 |
if (runningy-y >= sz) {
|
|
Packit |
6ef888 |
rc=1;
|
|
Packit |
6ef888 |
*ch = KEY_RIGHT;
|
|
Packit |
6ef888 |
done = TRUE;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
else {
|
|
Packit |
6ef888 |
// special character, is it one we recognize?
|
|
Packit |
6ef888 |
switch(*ch)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
case(KEY_ENTER):
|
|
Packit |
6ef888 |
case('\n'):
|
|
Packit |
6ef888 |
case('\r'):
|
|
Packit |
6ef888 |
rc=1;
|
|
Packit |
6ef888 |
done=TRUE;
|
|
Packit |
6ef888 |
string[runningy-y] = '\0';
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
case(KEY_CANCEL):
|
|
Packit |
6ef888 |
case(0x01B):
|
|
Packit |
6ef888 |
rc=0;
|
|
Packit |
6ef888 |
done=TRUE;
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
case(KEY_LEFT):
|
|
Packit |
6ef888 |
if (dmode == HEX_MODE) {
|
|
Packit |
6ef888 |
done = TRUE;
|
|
Packit |
6ef888 |
rc = 1;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
runningy--;
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
case(KEY_RIGHT):
|
|
Packit |
6ef888 |
if (dmode == HEX_MODE) {
|
|
Packit |
6ef888 |
done = TRUE;
|
|
Packit |
6ef888 |
rc = 1;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
runningy++;
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
case(KEY_DC):
|
|
Packit |
6ef888 |
case(0x07F):
|
|
Packit |
6ef888 |
if (runningy>=y) {
|
|
Packit |
6ef888 |
char *p;
|
|
Packit |
6ef888 |
p = &string[runningy - y];
|
|
Packit |
6ef888 |
while (*p) {
|
|
Packit |
6ef888 |
*p = *(p + 1);
|
|
Packit |
6ef888 |
p++;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
*p = '\0';
|
|
Packit |
6ef888 |
runningy--;
|
|
Packit |
6ef888 |
// remove the character from the string
|
|
Packit |
6ef888 |
move(x,y);
|
|
Packit |
6ef888 |
addstr(string);
|
|
Packit |
6ef888 |
COLORS_NORMAL;
|
|
Packit |
6ef888 |
addstr(" ");
|
|
Packit |
6ef888 |
COLORS_INVERSE;
|
|
Packit |
6ef888 |
runningy++;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
case(KEY_BACKSPACE):
|
|
Packit |
6ef888 |
if (runningy>y) {
|
|
Packit |
6ef888 |
char *p;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
p = &string[runningy - y - 1];
|
|
Packit |
6ef888 |
while (*p) {
|
|
Packit |
6ef888 |
*p = *(p + 1);
|
|
Packit |
6ef888 |
p++;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
*p='\0';
|
|
Packit |
6ef888 |
runningy--;
|
|
Packit |
6ef888 |
// remove the character from the string
|
|
Packit |
6ef888 |
move(x,y);
|
|
Packit |
6ef888 |
addstr(string);
|
|
Packit |
6ef888 |
COLORS_NORMAL;
|
|
Packit |
6ef888 |
addstr(" ");
|
|
Packit |
6ef888 |
COLORS_INVERSE;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
case KEY_DOWN: // Down
|
|
Packit |
6ef888 |
rc=0x5000U;
|
|
Packit |
6ef888 |
done=TRUE;
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
case KEY_UP: // Up
|
|
Packit |
6ef888 |
rc=0x4800U;
|
|
Packit |
6ef888 |
done=TRUE;
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
case 0x014b:
|
|
Packit |
6ef888 |
insert=!insert;
|
|
Packit |
6ef888 |
move(0,68);
|
|
Packit |
6ef888 |
if (insert)
|
|
Packit |
6ef888 |
printw("insert ");
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
printw("replace");
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
default:
|
|
Packit |
6ef888 |
move(0,70);
|
|
Packit |
6ef888 |
printw("%08x",*ch);
|
|
Packit |
6ef888 |
// ignore all other characters
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
} // end switch on non-printable character
|
|
Packit |
6ef888 |
} // end non-printable character
|
|
Packit |
6ef888 |
move(x,runningy);
|
|
Packit |
6ef888 |
refresh();
|
|
Packit |
6ef888 |
} // while !done
|
|
Packit |
6ef888 |
if (sz>0)
|
|
Packit |
6ef888 |
string[sz]='\0';
|
|
Packit |
6ef888 |
COLORS_NORMAL;
|
|
Packit |
6ef888 |
return rc;
|
|
Packit |
6ef888 |
}/* bobgets */
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/******************************************************************************
|
|
Packit |
6ef888 |
** instr - instructions
|
|
Packit |
6ef888 |
******************************************************************************/
|
|
Packit |
6ef888 |
static void gfs2instr(const char *s1, const char *s2)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
COLORS_HIGHLIGHT;
|
|
Packit |
6ef888 |
move(line,0);
|
|
Packit |
6ef888 |
printw(s1);
|
|
Packit |
6ef888 |
COLORS_NORMAL;
|
|
Packit |
6ef888 |
move(line,17);
|
|
Packit |
6ef888 |
printw(s2);
|
|
Packit |
6ef888 |
line++;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/******************************************************************************
|
|
Packit |
6ef888 |
*******************************************************************************
|
|
Packit |
6ef888 |
**
|
|
Packit |
6ef888 |
** void print_usage()
|
|
Packit |
6ef888 |
**
|
|
Packit |
6ef888 |
** Description:
|
|
Packit |
6ef888 |
** This routine prints out the appropriate commands for this application.
|
|
Packit |
6ef888 |
**
|
|
Packit |
6ef888 |
*******************************************************************************
|
|
Packit |
6ef888 |
******************************************************************************/
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
static void print_usage(void)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
int ch;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
line = 2;
|
|
Packit |
6ef888 |
Erase();
|
|
Packit |
6ef888 |
display_title_lines();
|
|
Packit |
6ef888 |
move(line++,0);
|
|
Packit |
6ef888 |
printw("Supported commands: (roughly conforming to the rules of 'less')");
|
|
Packit |
6ef888 |
line++;
|
|
Packit |
6ef888 |
move(line++,0);
|
|
Packit |
6ef888 |
printw("Navigation:");
|
|
Packit |
6ef888 |
gfs2instr("<pg up>/<down>","Move up or down one screen full");
|
|
Packit |
6ef888 |
gfs2instr("<up>/<down>","Move up or down one line");
|
|
Packit |
6ef888 |
gfs2instr("<left>/<right>","Move left or right one byte");
|
|
Packit |
6ef888 |
gfs2instr("<home>","Return to the superblock.");
|
|
Packit |
6ef888 |
gfs2instr(" f","Forward one 4K block");
|
|
Packit |
6ef888 |
gfs2instr(" b","Backward one 4K block");
|
|
Packit |
6ef888 |
gfs2instr(" g","Goto a given block (number, master, root, rindex, jindex, etc)");
|
|
Packit |
6ef888 |
gfs2instr(" j","Jump to the highlighted 64-bit block number.");
|
|
Packit |
6ef888 |
gfs2instr(" ","(You may also arrow up to the block number and hit enter)");
|
|
Packit |
6ef888 |
gfs2instr("<backspace>","Return to a previous block (a block stack is kept)");
|
|
Packit |
6ef888 |
gfs2instr("<space>","Jump forward to block before backspace (opposite of backspace)");
|
|
Packit |
6ef888 |
line++;
|
|
Packit |
6ef888 |
move(line++, 0);
|
|
Packit |
6ef888 |
printw("Other commands:");
|
|
Packit |
6ef888 |
gfs2instr(" h","This Help display");
|
|
Packit |
6ef888 |
gfs2instr(" c","Toggle the color scheme");
|
|
Packit |
6ef888 |
gfs2instr(" m","Switch display mode: hex -> GFS2 structure -> Extended");
|
|
Packit |
6ef888 |
gfs2instr(" q","Quit (same as hitting <escape> key)");
|
|
Packit |
6ef888 |
gfs2instr("<enter>","Edit a value (enter to save, esc to discard)");
|
|
Packit |
6ef888 |
gfs2instr(" ","(Currently only works on the hex display)");
|
|
Packit |
6ef888 |
gfs2instr("<escape>","Quit the program");
|
|
Packit |
6ef888 |
line++;
|
|
Packit |
6ef888 |
move(line++, 0);
|
|
Packit |
6ef888 |
printw("Notes: Areas shown in red are outside the bounds of the struct/file.");
|
|
Packit |
6ef888 |
move(line++, 0);
|
|
Packit |
6ef888 |
printw(" Areas shown in blue are file contents.");
|
|
Packit |
6ef888 |
move(line++, 0);
|
|
Packit |
6ef888 |
printw(" Characters shown in green are selected for edit on <enter>.");
|
|
Packit |
6ef888 |
move(line++, 0);
|
|
Packit |
6ef888 |
move(line++, 0);
|
|
Packit |
6ef888 |
printw("Press any key to return.");
|
|
Packit |
6ef888 |
refresh();
|
|
Packit |
6ef888 |
while ((ch=getch()) == 0); // wait for input
|
|
Packit |
6ef888 |
Erase();
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* get_block_type */
|
|
Packit |
6ef888 |
/* returns: metatype if block is a GFS2 structure block type */
|
|
Packit |
6ef888 |
/* 0 if block is not a GFS2 structure */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
uint32_t get_block_type(const struct gfs2_buffer_head *lbh, int *structlen)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
uint32_t ty = lgfs2_get_block_type(lbh);
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (ty != 0 && structlen != NULL) {
|
|
Packit |
6ef888 |
unsigned ver = sbd.gfs1 ? LGFS2_MD_GFS1 : LGFS2_MD_GFS2;
|
|
Packit |
6ef888 |
const struct lgfs2_metadata *mtype = lgfs2_find_mtype(ty, ver);
|
|
Packit |
6ef888 |
if (mtype != NULL)
|
|
Packit |
6ef888 |
*structlen = mtype->size;
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
*structlen = sbd.bsize;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
return ty;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* display_block_type */
|
|
Packit |
6ef888 |
/* returns: metatype if block is a GFS2 structure block type */
|
|
Packit |
6ef888 |
/* 0 if block is not a GFS2 structure */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
int display_block_type(struct gfs2_buffer_head *dbh, int from_restore)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
const struct gfs2_meta_header *mh;
|
|
Packit |
6ef888 |
int ret_type = 0; /* return type */
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* first, print out the kind of GFS2 block this is */
|
|
Packit |
6ef888 |
if (termlines) {
|
|
Packit |
6ef888 |
line = 1;
|
|
Packit |
6ef888 |
move(line, 0);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
print_gfs2("Block #");
|
|
Packit |
6ef888 |
if (termlines) {
|
|
Packit |
6ef888 |
if (edit_row[dmode] == -1)
|
|
Packit |
6ef888 |
COLORS_HIGHLIGHT;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
if (block == RGLIST_DUMMY_BLOCK)
|
|
Packit |
6ef888 |
print_gfs2("RG List ");
|
|
Packit |
6ef888 |
else if (block == JOURNALS_DUMMY_BLOCK)
|
|
Packit |
6ef888 |
print_gfs2("Journal Status: ");
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
print_gfs2("%"PRIu64" (0x%"PRIx64")", dbh->b_blocknr, dbh->b_blocknr);
|
|
Packit |
6ef888 |
if (termlines) {
|
|
Packit |
6ef888 |
if (edit_row[dmode] == -1)
|
|
Packit |
6ef888 |
COLORS_NORMAL;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
print_gfs2(" ");
|
|
Packit |
6ef888 |
if (!from_restore)
|
|
Packit |
6ef888 |
print_gfs2("of %"PRIu64" (0x%"PRIx64") ", max_block, max_block);
|
|
Packit |
6ef888 |
if (block == RGLIST_DUMMY_BLOCK) {
|
|
Packit |
6ef888 |
ret_type = GFS2_METATYPE_RG;
|
|
Packit |
6ef888 |
struct_len = sbd.gfs1 ? sizeof(struct gfs_rgrp) :
|
|
Packit |
6ef888 |
sizeof(struct gfs2_rgrp);
|
|
Packit |
6ef888 |
} else if (block == JOURNALS_DUMMY_BLOCK) {
|
|
Packit |
6ef888 |
ret_type = GFS2_METATYPE_DI;
|
|
Packit |
6ef888 |
struct_len = 0;
|
|
Packit |
6ef888 |
} else {
|
|
Packit |
6ef888 |
ret_type = get_block_type(dbh, &struct_len);
|
|
Packit |
6ef888 |
switch (ret_type) {
|
|
Packit |
6ef888 |
case GFS2_METATYPE_SB: /* 1 */
|
|
Packit |
6ef888 |
print_gfs2("(superblock)");
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
case GFS2_METATYPE_RG: /* 2 */
|
|
Packit |
6ef888 |
print_gfs2("(rsrc grp hdr)");
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
case GFS2_METATYPE_RB: /* 3 */
|
|
Packit |
6ef888 |
print_gfs2("(rsrc grp bitblk)");
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
case GFS2_METATYPE_DI: /* 4 */
|
|
Packit |
6ef888 |
print_gfs2("(disk inode)");
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
case GFS2_METATYPE_IN: /* 5 */
|
|
Packit |
6ef888 |
print_gfs2("(indir blklist)");
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
case GFS2_METATYPE_LF: /* 6 */
|
|
Packit |
6ef888 |
print_gfs2("(directory leaf)");
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
case GFS2_METATYPE_JD:
|
|
Packit |
6ef888 |
print_gfs2("(journal data)");
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
case GFS2_METATYPE_LH:
|
|
Packit |
6ef888 |
print_gfs2("(log header)");
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
case GFS2_METATYPE_LD:
|
|
Packit |
6ef888 |
print_gfs2("(log descriptor)");
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
case GFS2_METATYPE_EA:
|
|
Packit |
6ef888 |
print_gfs2("(extended attr hdr)");
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
case GFS2_METATYPE_ED:
|
|
Packit |
6ef888 |
print_gfs2("(extended attr data)");
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
case GFS2_METATYPE_LB:
|
|
Packit |
6ef888 |
print_gfs2("(log buffer)");
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
case GFS2_METATYPE_QC:
|
|
Packit |
6ef888 |
print_gfs2("(quota change)");
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
case 0:
|
|
Packit |
6ef888 |
struct_len = sbd.bsize;
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
default:
|
|
Packit |
6ef888 |
print_gfs2("(wtf?)");
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
mh = dbh->iov.iov_base;
|
|
Packit |
6ef888 |
eol(0);
|
|
Packit |
6ef888 |
if (from_restore)
|
|
Packit |
6ef888 |
return ret_type;
|
|
Packit |
6ef888 |
if (termlines && dmode == HEX_MODE) {
|
|
Packit |
6ef888 |
int type;
|
|
Packit |
6ef888 |
struct rgrp_tree *rgd;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
rgd = gfs2_blk2rgrpd(&sbd, block);
|
|
Packit |
6ef888 |
if (rgd) {
|
|
Packit |
6ef888 |
gfs2_rgrp_read(&sbd, rgd);
|
|
Packit |
6ef888 |
if ((be32_to_cpu(mh->mh_type) == GFS2_METATYPE_RG) ||
|
|
Packit |
6ef888 |
(be32_to_cpu(mh->mh_type) == GFS2_METATYPE_RB))
|
|
Packit |
6ef888 |
type = 4;
|
|
Packit |
6ef888 |
else {
|
|
Packit |
6ef888 |
type = lgfs2_get_bitmap(&sbd, block, rgd);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
} else
|
|
Packit |
6ef888 |
type = 4;
|
|
Packit |
6ef888 |
screen_chunk_size = ((termlines - 4) * 16) >> 8 << 8;
|
|
Packit |
6ef888 |
if (!screen_chunk_size)
|
|
Packit |
6ef888 |
screen_chunk_size = 256;
|
|
Packit |
6ef888 |
pgnum = (offset / screen_chunk_size);
|
|
Packit |
6ef888 |
if (type >= 0) {
|
|
Packit |
6ef888 |
print_gfs2("(p.%d of %d--%s)", pgnum + 1,
|
|
Packit |
6ef888 |
(sbd.bsize % screen_chunk_size) > 0 ?
|
|
Packit |
6ef888 |
sbd.bsize / screen_chunk_size + 1 : sbd.bsize /
|
|
Packit |
6ef888 |
screen_chunk_size, allocdesc[sbd.gfs1][type]);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
/*eol(9);*/
|
|
Packit |
6ef888 |
if ((be32_to_cpu(mh->mh_type) == GFS2_METATYPE_RG)) {
|
|
Packit |
6ef888 |
int ptroffset = edit_row[dmode] * 16 + edit_col[dmode];
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (rgd && (ptroffset >= struct_len || pgnum)) {
|
|
Packit |
6ef888 |
int blknum, b, btype;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
blknum = pgnum * screen_chunk_size;
|
|
Packit |
6ef888 |
blknum += (ptroffset - struct_len);
|
|
Packit |
6ef888 |
blknum *= 4;
|
|
Packit |
6ef888 |
blknum += rgd->ri.ri_data0;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
print_gfs2(" blk ");
|
|
Packit |
6ef888 |
for (b = blknum; b < blknum + 4; b++) {
|
|
Packit |
6ef888 |
btype = lgfs2_get_bitmap(&sbd, b, rgd);
|
|
Packit |
6ef888 |
if (btype >= 0) {
|
|
Packit |
6ef888 |
print_gfs2("0x%x-%s ", b,
|
|
Packit |
6ef888 |
allocdesc[sbd.gfs1][btype]);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
} else if ((be32_to_cpu(mh->mh_type) == GFS2_METATYPE_RB)) {
|
|
Packit |
6ef888 |
int ptroffset = edit_row[dmode] * 16 + edit_col[dmode];
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (rgd && (ptroffset >= struct_len || pgnum)) {
|
|
Packit |
6ef888 |
int blknum, b, btype, rb_number;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
rb_number = block - rgd->ri.ri_addr;
|
|
Packit |
6ef888 |
blknum = 0;
|
|
Packit |
6ef888 |
/* count the number of bytes representing
|
|
Packit |
6ef888 |
blocks prior to the displayed screen. */
|
|
Packit |
6ef888 |
for (b = 0; b < rb_number; b++) {
|
|
Packit |
6ef888 |
struct_len = (b ?
|
|
Packit |
6ef888 |
sizeof(struct gfs2_meta_header) :
|
|
Packit |
6ef888 |
sizeof(struct gfs2_rgrp));
|
|
Packit |
6ef888 |
blknum += (sbd.bsize - struct_len);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
struct_len = sizeof(struct gfs2_meta_header);
|
|
Packit |
6ef888 |
/* add the number of bytes on this screen */
|
|
Packit |
6ef888 |
blknum += (ptroffset - struct_len);
|
|
Packit |
6ef888 |
/* factor in the page number */
|
|
Packit |
6ef888 |
blknum += pgnum * screen_chunk_size;
|
|
Packit |
6ef888 |
/* convert bytes to blocks */
|
|
Packit |
6ef888 |
blknum *= GFS2_NBBY;
|
|
Packit |
6ef888 |
/* add the starting offset for this rgrp */
|
|
Packit |
6ef888 |
blknum += rgd->ri.ri_data0;
|
|
Packit |
6ef888 |
print_gfs2(" blk ");
|
|
Packit |
6ef888 |
for (b = blknum; b < blknum + 4; b++) {
|
|
Packit |
6ef888 |
btype = lgfs2_get_bitmap(&sbd, b, rgd);
|
|
Packit |
6ef888 |
if (btype >= 0) {
|
|
Packit |
6ef888 |
print_gfs2("0x%x-%s ", b,
|
|
Packit |
6ef888 |
allocdesc[sbd.gfs1][btype]);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
if (rgd)
|
|
Packit |
6ef888 |
gfs2_rgrp_relse(rgd);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
if (block == sbd.sd_sb.sb_root_dir.no_addr)
|
|
Packit |
6ef888 |
print_gfs2("--------------- Root directory ------------------");
|
|
Packit |
6ef888 |
else if (!sbd.gfs1 && block == sbd.sd_sb.sb_master_dir.no_addr)
|
|
Packit |
6ef888 |
print_gfs2("-------------- Master directory -----------------");
|
|
Packit |
6ef888 |
else if (!sbd.gfs1 && block == RGLIST_DUMMY_BLOCK)
|
|
Packit |
6ef888 |
print_gfs2("------------------ RG List ----------------------");
|
|
Packit |
6ef888 |
else if (!sbd.gfs1 && block == JOURNALS_DUMMY_BLOCK)
|
|
Packit |
6ef888 |
print_gfs2("-------------------- Journal List --------------------");
|
|
Packit |
6ef888 |
else {
|
|
Packit |
6ef888 |
if (sbd.gfs1) {
|
|
Packit |
6ef888 |
if (block == sbd1->sb_rindex_di.no_addr)
|
|
Packit |
6ef888 |
print_gfs2("---------------- rindex file -------------------");
|
|
Packit |
6ef888 |
else if (block == gfs1_quota_di.no_addr)
|
|
Packit |
6ef888 |
print_gfs2("---------------- Quota file --------------------");
|
|
Packit |
6ef888 |
else if (block == sbd1->sb_jindex_di.no_addr)
|
|
Packit |
6ef888 |
print_gfs2("--------------- Journal Index ------------------");
|
|
Packit |
6ef888 |
else if (block == gfs1_license_di.no_addr)
|
|
Packit |
6ef888 |
print_gfs2("--------------- License file -------------------");
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
else {
|
|
Packit |
6ef888 |
int d;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
for (d = 2; d < 8; d++) {
|
|
Packit |
6ef888 |
if (block == masterdir.dirent[d].block) {
|
|
Packit |
6ef888 |
if (!strncmp(masterdir.dirent[d].filename, "jindex", 6))
|
|
Packit |
6ef888 |
print_gfs2("--------------- Journal Index ------------------");
|
|
Packit |
6ef888 |
else if (!strncmp(masterdir.dirent[d].filename, "per_node", 8))
|
|
Packit |
6ef888 |
print_gfs2("--------------- Per-node Dir -------------------");
|
|
Packit |
6ef888 |
else if (!strncmp(masterdir.dirent[d].filename, "inum", 4))
|
|
Packit |
6ef888 |
print_gfs2("---------------- Inum file ---------------------");
|
|
Packit |
6ef888 |
else if (!strncmp(masterdir.dirent[d].filename, "statfs", 6))
|
|
Packit |
6ef888 |
print_gfs2("---------------- statfs file -------------------");
|
|
Packit |
6ef888 |
else if (!strncmp(masterdir.dirent[d].filename, "rindex", 6))
|
|
Packit |
6ef888 |
print_gfs2("---------------- rindex file -------------------");
|
|
Packit |
6ef888 |
else if (!strncmp(masterdir.dirent[d].filename, "quota", 5))
|
|
Packit |
6ef888 |
print_gfs2("---------------- Quota file --------------------");
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
eol(0);
|
|
Packit |
6ef888 |
return ret_type;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
static const struct lgfs2_metadata *find_mtype(uint32_t mtype, const unsigned versions)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
const struct lgfs2_metadata *m = lgfs2_metadata;
|
|
Packit |
6ef888 |
unsigned n = 0;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
do {
|
|
Packit |
6ef888 |
if ((m[n].versions & versions) && m[n].mh_type == mtype)
|
|
Packit |
6ef888 |
return &m[n];
|
|
Packit |
6ef888 |
n++;
|
|
Packit |
6ef888 |
} while (n < lgfs2_metadata_size);
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
return NULL;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
static int get_pnum(int ptroffset)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
int pnum;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
pnum = pgnum * screen_chunk_size;
|
|
Packit |
6ef888 |
pnum += (ptroffset - struct_len);
|
|
Packit |
6ef888 |
pnum /= sizeof(uint64_t);
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
return pnum;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* hexdump - hex dump the filesystem block to the screen */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
static int hexdump(uint64_t startaddr, int len, int trunc_zeros,
|
|
Packit |
6ef888 |
uint64_t flagref, uint64_t ref_blk)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
const unsigned char *pointer, *ptr2;
|
|
Packit |
6ef888 |
int i;
|
|
Packit |
6ef888 |
uint64_t l;
|
|
Packit |
6ef888 |
const char *lpBuffer = bh->b_data;
|
|
Packit |
6ef888 |
const char *zeros_strt = lpBuffer + sbd.bsize;
|
|
Packit |
6ef888 |
int print_field, cursor_line;
|
|
Packit |
6ef888 |
const uint32_t block_type = get_block_type(bh, NULL);
|
|
Packit |
6ef888 |
uint64_t *ref;
|
|
Packit |
6ef888 |
int ptroffset = 0;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
strcpy(edit_fmt,"%02x");
|
|
Packit |
6ef888 |
pointer = (unsigned char *)lpBuffer + offset;
|
|
Packit |
6ef888 |
ptr2 = (unsigned char *)lpBuffer + offset;
|
|
Packit |
6ef888 |
ref = (uint64_t *)lpBuffer + offset;
|
|
Packit |
6ef888 |
if (trunc_zeros) {
|
|
Packit |
6ef888 |
while (zeros_strt > lpBuffer && (*(zeros_strt - 1) == 0))
|
|
Packit |
6ef888 |
zeros_strt--;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
l = offset;
|
|
Packit |
6ef888 |
print_entry_ndx = 0;
|
|
Packit |
6ef888 |
while (((termlines && line < termlines &&
|
|
Packit |
6ef888 |
line <= ((screen_chunk_size / 16) + 2)) ||
|
|
Packit |
6ef888 |
(!termlines && l < len)) && l < sbd.bsize) {
|
|
Packit |
6ef888 |
int ptr_not_null = 0;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (termlines) {
|
|
Packit |
6ef888 |
move(line, 0);
|
|
Packit |
6ef888 |
COLORS_OFFSETS; /* cyan for offsets */
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
if (startaddr < 0xffffffff)
|
|
Packit |
6ef888 |
print_gfs2("%.8"PRIx64, startaddr + l);
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
print_gfs2("%.16"PRIx64, startaddr + l);
|
|
Packit |
6ef888 |
if (termlines) {
|
|
Packit |
6ef888 |
if (l < struct_len)
|
|
Packit |
6ef888 |
COLORS_NORMAL; /* normal part of structure */
|
|
Packit |
6ef888 |
else if (gfs2_struct_type == GFS2_METATYPE_DI &&
|
|
Packit |
6ef888 |
l < struct_len + di.di_size)
|
|
Packit |
6ef888 |
COLORS_CONTENTS; /* after struct but not eof */
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
COLORS_SPECIAL; /* beyond end of the struct */
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
print_field = -1;
|
|
Packit |
6ef888 |
cursor_line = 0;
|
|
Packit |
6ef888 |
for (i = 0; i < 16; i++) { /* first print it in hex */
|
|
Packit |
6ef888 |
/* Figure out if we have a null pointer--for colors */
|
|
Packit |
6ef888 |
if (((gfs2_struct_type == GFS2_METATYPE_IN) ||
|
|
Packit |
6ef888 |
(gfs2_struct_type == GFS2_METATYPE_DI &&
|
|
Packit |
6ef888 |
l < struct_len + di.di_size &&
|
|
Packit |
6ef888 |
(di.di_height > 0 || !S_ISREG(di.di_mode)))) &&
|
|
Packit |
6ef888 |
(i==0 || i==8)) {
|
|
Packit |
6ef888 |
int j;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
ptr_not_null = 0;
|
|
Packit |
6ef888 |
for (j = 0; j < 8; j++) {
|
|
Packit |
6ef888 |
if (*(pointer + j)) {
|
|
Packit |
6ef888 |
ptr_not_null = 1;
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
if (termlines) {
|
|
Packit |
6ef888 |
if (l + i < struct_len)
|
|
Packit |
6ef888 |
COLORS_NORMAL; /* in the structure */
|
|
Packit |
6ef888 |
else if (gfs2_struct_type == GFS2_METATYPE_DI
|
|
Packit |
6ef888 |
&& l + i < struct_len + di.di_size) {
|
|
Packit |
6ef888 |
if ((!di.di_height &&
|
|
Packit |
6ef888 |
S_ISREG(di.di_mode)) ||
|
|
Packit |
6ef888 |
!ptr_not_null)
|
|
Packit |
6ef888 |
COLORS_CONTENTS;/*stuff data */
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
COLORS_SPECIAL;/* non-null */
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
else if (gfs2_struct_type == GFS2_METATYPE_IN){
|
|
Packit |
6ef888 |
if (ptr_not_null)
|
|
Packit |
6ef888 |
COLORS_SPECIAL;/* non-null */
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
COLORS_CONTENTS;/* null */
|
|
Packit |
6ef888 |
} else
|
|
Packit |
6ef888 |
COLORS_SPECIAL; /* past the struct */
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
if (i%4 == 0)
|
|
Packit |
6ef888 |
print_gfs2(" ");
|
|
Packit |
6ef888 |
if (termlines && line == edit_row[dmode] + 3 &&
|
|
Packit |
6ef888 |
i == edit_col[dmode]) {
|
|
Packit |
6ef888 |
COLORS_HIGHLIGHT; /* in the structure */
|
|
Packit |
6ef888 |
memset(estring,0,3);
|
|
Packit |
6ef888 |
sprintf(estring,"%02x",*pointer);
|
|
Packit |
6ef888 |
cursor_line = 1;
|
|
Packit |
6ef888 |
print_field = (char *)pointer - bh->b_data;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
print_gfs2("%02x",*pointer);
|
|
Packit |
6ef888 |
if (termlines && line == edit_row[dmode] + 3 &&
|
|
Packit |
6ef888 |
i == edit_col[dmode]) {
|
|
Packit |
6ef888 |
if (l < struct_len + offset)
|
|
Packit |
6ef888 |
COLORS_NORMAL; /* in the structure */
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
COLORS_SPECIAL; /* beyond structure */
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
pointer++;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
print_gfs2(" [");
|
|
Packit |
6ef888 |
for (i=0; i<16; i++) { /* now print it in character format */
|
|
Packit |
6ef888 |
if ((*ptr2 >=' ') && (*ptr2 <= '~'))
|
|
Packit |
6ef888 |
print_gfs2("%c",*ptr2);
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
print_gfs2(".");
|
|
Packit |
6ef888 |
ptr2++;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
print_gfs2("] ");
|
|
Packit |
6ef888 |
if (print_field >= 0) {
|
|
Packit |
6ef888 |
const struct lgfs2_metadata *m = find_mtype(block_type,
|
|
Packit |
6ef888 |
sbd.gfs1 ? LGFS2_MD_GFS1 : LGFS2_MD_GFS2);
|
|
Packit |
6ef888 |
if (m) {
|
|
Packit |
6ef888 |
const struct lgfs2_metafield *f;
|
|
Packit |
6ef888 |
unsigned n;
|
|
Packit |
6ef888 |
for (n = 0; n < m->nfields; n++) {
|
|
Packit |
6ef888 |
f = &m->fields[n];
|
|
Packit |
6ef888 |
if (print_field >= f->offset &&
|
|
Packit |
6ef888 |
print_field < (f->offset + f->length)) {
|
|
Packit |
6ef888 |
print_gfs2("%s", m->fields[n].name);
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
if (cursor_line) {
|
|
Packit |
6ef888 |
if (block_type == GFS2_METATYPE_IN ||
|
|
Packit |
6ef888 |
block_type == GFS2_METATYPE_LD ||
|
|
Packit |
6ef888 |
((block_type == GFS2_METATYPE_DI) &&
|
|
Packit |
6ef888 |
((struct gfs2_dinode*)bh->b_data)->di_height) ||
|
|
Packit |
6ef888 |
S_ISDIR(di.di_mode)) {
|
|
Packit |
6ef888 |
ptroffset = edit_row[dmode] * 16 +
|
|
Packit |
6ef888 |
edit_col[dmode];
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (ptroffset >= struct_len || pgnum) {
|
|
Packit |
6ef888 |
int pnum = get_pnum(ptroffset);
|
|
Packit |
6ef888 |
if (block_type == GFS2_METATYPE_LD)
|
|
Packit |
6ef888 |
print_gfs2("*");
|
|
Packit |
6ef888 |
print_gfs2("pointer 0x%x", pnum);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
if (line - 3 > last_entry_onscreen[dmode])
|
|
Packit |
6ef888 |
last_entry_onscreen[dmode] = line - 3;
|
|
Packit |
6ef888 |
if (flagref && be64_to_cpu(*ref) == flagref)
|
|
Packit |
6ef888 |
print_gfs2("<------------------------- ref in 0x%"PRIx64" "
|
|
Packit |
6ef888 |
"to 0x%"PRIx64, ref_blk, flagref);
|
|
Packit |
6ef888 |
ref++;
|
|
Packit |
6ef888 |
if (flagref && be64_to_cpu(*ref) == flagref)
|
|
Packit |
6ef888 |
print_gfs2("<------------------------- ref in 0x%"PRIx64" "
|
|
Packit |
6ef888 |
"to 0x%"PRIx64, ref_blk, flagref);
|
|
Packit |
6ef888 |
ref++;
|
|
Packit |
6ef888 |
eol(0);
|
|
Packit |
6ef888 |
l += 16;
|
|
Packit |
6ef888 |
print_entry_ndx++;
|
|
Packit |
6ef888 |
/* This should only happen if trunc_zeros is specified: */
|
|
Packit |
6ef888 |
if ((const char *)pointer >= zeros_strt)
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
} /* while */
|
|
Packit |
6ef888 |
if (block_type == GFS2_METATYPE_LD && ptroffset >= struct_len) {
|
|
Packit |
6ef888 |
COLORS_NORMAL;
|
|
Packit |
6ef888 |
eol(0);
|
|
Packit |
6ef888 |
print_gfs2(" * 'j' will jump to the journaled block, "
|
|
Packit |
6ef888 |
"not the absolute block.");
|
|
Packit |
6ef888 |
eol(0);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
if (sbd.gfs1) {
|
|
Packit |
6ef888 |
COLORS_NORMAL;
|
|
Packit |
6ef888 |
print_gfs2(" *** This seems to be a GFS-1 file system ***");
|
|
Packit |
6ef888 |
eol(0);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
return (offset+len);
|
|
Packit |
6ef888 |
}/* hexdump */
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* masterblock - find a file (by name) in the master directory and return */
|
|
Packit |
6ef888 |
/* its block number. */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
uint64_t masterblock(const char *fn)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
int d;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
for (d = 2; d < 8; d++)
|
|
Packit |
6ef888 |
if (!strncmp(masterdir.dirent[d].filename, fn, strlen(fn)))
|
|
Packit |
6ef888 |
return (masterdir.dirent[d].block);
|
|
Packit |
6ef888 |
return 0;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* rgcount - return how many rgrps there are. */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
static void rgcount(void)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
printf("%lld RGs in this file system.\n",
|
|
Packit |
6ef888 |
(unsigned long long)sbd.md.riinode->i_di.di_size /
|
|
Packit |
6ef888 |
sizeof(struct gfs2_rindex));
|
|
Packit |
6ef888 |
inode_put(&sbd.md.riinode);
|
|
Packit |
6ef888 |
gfs2_rgrp_free(&sbd.rgtree);
|
|
Packit |
6ef888 |
exit(EXIT_SUCCESS);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* find_rgrp_block - locate the block for a given rgrp number */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
static uint64_t find_rgrp_block(struct gfs2_inode *dif, int rg)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
int amt;
|
|
Packit |
6ef888 |
struct gfs2_rindex fbuf, ri;
|
|
Packit |
6ef888 |
uint64_t foffset, gfs1_adj = 0;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
foffset = rg * sizeof(struct gfs2_rindex);
|
|
Packit |
6ef888 |
if (sbd.gfs1) {
|
|
Packit |
6ef888 |
uint64_t sd_jbsize =
|
|
Packit |
6ef888 |
(sbd.bsize - sizeof(struct gfs2_meta_header));
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
gfs1_adj = (foffset / sd_jbsize) *
|
|
Packit |
6ef888 |
sizeof(struct gfs2_meta_header);
|
|
Packit |
6ef888 |
gfs1_adj += sizeof(struct gfs2_meta_header);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
amt = gfs2_readi(dif, (void *)&fbuf, foffset + gfs1_adj,
|
|
Packit |
6ef888 |
sizeof(struct gfs2_rindex));
|
|
Packit |
6ef888 |
if (!amt) /* end of file */
|
|
Packit |
6ef888 |
return 0;
|
|
Packit |
6ef888 |
gfs2_rindex_in(&ri, (void *)&fbuf);
|
|
Packit |
6ef888 |
return ri.ri_addr;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* gfs_rgrp_print - print a gfs1 resource group */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
void gfs_rgrp_print(struct gfs_rgrp *rg)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
gfs2_meta_header_print(&rg->rg_header);
|
|
Packit |
6ef888 |
pv(rg, rg_flags, "%u", "0x%x");
|
|
Packit |
6ef888 |
pv(rg, rg_free, "%u", "0x%x");
|
|
Packit |
6ef888 |
pv(rg, rg_useddi, "%u", "0x%x");
|
|
Packit |
6ef888 |
pv(rg, rg_freedi, "%u", "0x%x");
|
|
Packit |
6ef888 |
gfs2_inum_print(&rg->rg_freedi_list);
|
|
Packit |
6ef888 |
pv(rg, rg_usedmeta, "%u", "0x%x");
|
|
Packit |
6ef888 |
pv(rg, rg_freemeta, "%u", "0x%x");
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* get_rg_addr */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
static uint64_t get_rg_addr(int rgnum)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
uint64_t rgblk = 0, gblock;
|
|
Packit |
6ef888 |
struct gfs2_inode *riinode;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (sbd.gfs1)
|
|
Packit |
6ef888 |
gblock = sbd1->sb_rindex_di.no_addr;
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
gblock = masterblock("rindex");
|
|
Packit |
6ef888 |
riinode = lgfs2_inode_read(&sbd, gblock);
|
|
Packit |
6ef888 |
if (riinode == NULL)
|
|
Packit |
6ef888 |
return 0;
|
|
Packit |
6ef888 |
if (rgnum < riinode->i_di.di_size / sizeof(struct gfs2_rindex))
|
|
Packit |
6ef888 |
rgblk = find_rgrp_block(riinode, rgnum);
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
fprintf(stderr, "Error: File system only has %lld RGs.\n",
|
|
Packit |
6ef888 |
(unsigned long long)riinode->i_di.di_size /
|
|
Packit |
6ef888 |
sizeof(struct gfs2_rindex));
|
|
Packit |
6ef888 |
inode_put(&riinode);
|
|
Packit |
6ef888 |
return rgblk;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* set_rgrp_flags - Set an rgrp's flags to a given value */
|
|
Packit |
6ef888 |
/* rgnum: which rg to print or modify flags for (0 - X) */
|
|
Packit |
6ef888 |
/* new_flags: value to set new rg_flags to (if modify == TRUE) */
|
|
Packit |
6ef888 |
/* modify: TRUE if the value is to be modified, FALSE if it's to be printed */
|
|
Packit |
6ef888 |
/* full: TRUE if the full RG should be printed. */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
static void set_rgrp_flags(int rgnum, uint32_t new_flags, int modify, int full)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
union {
|
|
Packit |
6ef888 |
struct gfs2_rgrp rg2;
|
|
Packit |
6ef888 |
struct gfs_rgrp rg1;
|
|
Packit |
6ef888 |
} rg;
|
|
Packit |
6ef888 |
struct gfs2_buffer_head *rbh;
|
|
Packit |
6ef888 |
uint64_t rgblk;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
rgblk = get_rg_addr(rgnum);
|
|
Packit |
6ef888 |
rbh = bread(&sbd, rgblk);
|
|
Packit |
6ef888 |
if (sbd.gfs1)
|
|
Packit |
6ef888 |
gfs_rgrp_in(&rg.rg1, rbh);
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
gfs2_rgrp_in(&rg.rg2, rbh->b_data);
|
|
Packit |
6ef888 |
if (modify) {
|
|
Packit |
6ef888 |
printf("RG #%d (block %llu / 0x%llx) rg_flags changed from 0x%08x to 0x%08x\n",
|
|
Packit |
6ef888 |
rgnum, (unsigned long long)rgblk,
|
|
Packit |
6ef888 |
(unsigned long long)rgblk, rg.rg2.rg_flags, new_flags);
|
|
Packit |
6ef888 |
rg.rg2.rg_flags = new_flags;
|
|
Packit |
6ef888 |
if (sbd.gfs1)
|
|
Packit |
6ef888 |
gfs_rgrp_out(&rg.rg1, rbh);
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
gfs2_rgrp_out(&rg.rg2, rbh->b_data);
|
|
Packit |
6ef888 |
bmodified(rbh);
|
|
Packit |
6ef888 |
brelse(rbh);
|
|
Packit |
6ef888 |
} else {
|
|
Packit |
6ef888 |
if (full) {
|
|
Packit |
6ef888 |
print_gfs2("RG #%d", rgnum);
|
|
Packit |
6ef888 |
print_gfs2(" located at: %"PRIu64" (0x%"PRIx64")", rgblk, rgblk);
|
|
Packit |
6ef888 |
eol(0);
|
|
Packit |
6ef888 |
if (sbd.gfs1)
|
|
Packit |
6ef888 |
gfs_rgrp_print(&rg.rg1);
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
gfs2_rgrp_print(&rg.rg2);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
printf("RG #%d (block %llu / 0x%llx) rg_flags = 0x%08x\n",
|
|
Packit |
6ef888 |
rgnum, (unsigned long long)rgblk,
|
|
Packit |
6ef888 |
(unsigned long long)rgblk, rg.rg2.rg_flags);
|
|
Packit |
6ef888 |
brelse(rbh);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
if (modify)
|
|
Packit |
6ef888 |
fsync(sbd.device_fd);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* has_indirect_blocks */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
int has_indirect_blocks(void)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
if (indirect_blocks || gfs2_struct_type == GFS2_METATYPE_SB ||
|
|
Packit |
6ef888 |
gfs2_struct_type == GFS2_METATYPE_LF ||
|
|
Packit |
6ef888 |
(gfs2_struct_type == GFS2_METATYPE_DI &&
|
|
Packit |
6ef888 |
(S_ISDIR(di.di_mode) || (sbd.gfs1 && di.__pad1 == GFS_FILE_DIR))))
|
|
Packit |
6ef888 |
return TRUE;
|
|
Packit |
6ef888 |
return FALSE;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
int block_is_rindex(uint64_t blk)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
if ((sbd.gfs1 && blk == sbd1->sb_rindex_di.no_addr) ||
|
|
Packit |
6ef888 |
(blk == masterblock("rindex")))
|
|
Packit |
6ef888 |
return TRUE;
|
|
Packit |
6ef888 |
return FALSE;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
int block_is_jindex(uint64_t blk)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
if ((sbd.gfs1 && blk == sbd1->sb_jindex_di.no_addr))
|
|
Packit |
6ef888 |
return TRUE;
|
|
Packit |
6ef888 |
return FALSE;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
int block_is_inum_file(uint64_t blk)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
if (!sbd.gfs1 && blk == masterblock("inum"))
|
|
Packit |
6ef888 |
return TRUE;
|
|
Packit |
6ef888 |
return FALSE;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
int block_is_statfs_file(uint64_t blk)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
if (sbd.gfs1 && blk == gfs1_license_di.no_addr)
|
|
Packit |
6ef888 |
return TRUE;
|
|
Packit |
6ef888 |
if (!sbd.gfs1 && blk == masterblock("statfs"))
|
|
Packit |
6ef888 |
return TRUE;
|
|
Packit |
6ef888 |
return FALSE;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
int block_is_quota_file(uint64_t blk)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
if (sbd.gfs1 && blk == gfs1_quota_di.no_addr)
|
|
Packit |
6ef888 |
return TRUE;
|
|
Packit |
6ef888 |
if (!sbd.gfs1 && blk == masterblock("quota"))
|
|
Packit |
6ef888 |
return TRUE;
|
|
Packit |
6ef888 |
return FALSE;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
int block_is_per_node(uint64_t blk)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
if (!sbd.gfs1 && blk == masterblock("per_node"))
|
|
Packit |
6ef888 |
return TRUE;
|
|
Packit |
6ef888 |
return FALSE;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* block_has_extended_info */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
static int block_has_extended_info(void)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
if (has_indirect_blocks() ||
|
|
Packit |
6ef888 |
block_is_rindex(block) ||
|
|
Packit |
6ef888 |
block_is_rgtree(block) ||
|
|
Packit |
6ef888 |
block_is_journals(block) ||
|
|
Packit |
6ef888 |
block_is_jindex(block) ||
|
|
Packit |
6ef888 |
block_is_inum_file(block) ||
|
|
Packit |
6ef888 |
block_is_statfs_file(block) ||
|
|
Packit |
6ef888 |
block_is_quota_file(block))
|
|
Packit |
6ef888 |
return TRUE;
|
|
Packit |
6ef888 |
return FALSE;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
static void read_superblock(int fd)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
sbd1 = (struct gfs_sb *)&sbd.sd_sb;
|
|
Packit |
6ef888 |
ioctl(fd, BLKFLSBUF, 0);
|
|
Packit |
6ef888 |
memset(&sbd, 0, sizeof(struct gfs2_sbd));
|
|
Packit |
6ef888 |
sbd.bsize = GFS2_DEFAULT_BSIZE;
|
|
Packit |
6ef888 |
sbd.device_fd = fd;
|
|
Packit |
6ef888 |
bh = bread(&sbd, 0x10);
|
|
Packit |
6ef888 |
sbd.jsize = GFS2_DEFAULT_JSIZE;
|
|
Packit |
6ef888 |
sbd.rgsize = GFS2_DEFAULT_RGSIZE;
|
|
Packit |
6ef888 |
sbd.qcsize = GFS2_DEFAULT_QCSIZE;
|
|
Packit |
6ef888 |
sbd.time = time(NULL);
|
|
Packit |
6ef888 |
sbd.rgtree.osi_node = NULL;
|
|
Packit |
6ef888 |
gfs2_sb_in(&sbd.sd_sb, bh->b_data);
|
|
Packit |
6ef888 |
/* Check to see if this is really gfs1 */
|
|
Packit |
6ef888 |
if (sbd1->sb_fs_format == GFS_FORMAT_FS &&
|
|
Packit |
6ef888 |
sbd1->sb_header.mh_type == GFS_METATYPE_SB &&
|
|
Packit |
6ef888 |
sbd1->sb_header.mh_format == GFS_FORMAT_SB &&
|
|
Packit |
6ef888 |
sbd1->sb_multihost_format == GFS_FORMAT_MULTI) {
|
|
Packit |
6ef888 |
struct gfs_sb *sbbuf = (struct gfs_sb *)bh->b_data;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
sbd.gfs1 = TRUE;
|
|
Packit |
6ef888 |
sbd1->sb_flags = be32_to_cpu(sbbuf->sb_flags);
|
|
Packit |
6ef888 |
sbd1->sb_seg_size = be32_to_cpu(sbbuf->sb_seg_size);
|
|
Packit |
6ef888 |
gfs2_inum_in(&sbd1->sb_rindex_di, (void *)&sbbuf->sb_rindex_di);
|
|
Packit |
6ef888 |
gfs2_inum_in(&gfs1_quota_di, (void *)&sbbuf->sb_quota_di);
|
|
Packit |
6ef888 |
gfs2_inum_in(&gfs1_license_di, (void *)&sbbuf->sb_license_di);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
sbd.gfs1 = FALSE;
|
|
Packit |
6ef888 |
sbd.bsize = sbd.sd_sb.sb_bsize;
|
|
Packit |
6ef888 |
if (!sbd.bsize)
|
|
Packit |
6ef888 |
sbd.bsize = GFS2_DEFAULT_BSIZE;
|
|
Packit |
6ef888 |
if (lgfs2_get_dev_info(fd, &sbd.dinfo)) {
|
|
Packit |
6ef888 |
perror(device);
|
|
Packit |
6ef888 |
exit(-1);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
if(compute_constants(&sbd)) {
|
|
Packit |
6ef888 |
fprintf(stderr, "Failed to compute constants.\n");
|
|
Packit |
6ef888 |
exit(-1);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
if (sbd.gfs1 || (sbd.sd_sb.sb_header.mh_magic == GFS2_MAGIC &&
|
|
Packit |
6ef888 |
sbd.sd_sb.sb_header.mh_type == GFS2_METATYPE_SB))
|
|
Packit |
6ef888 |
block = 0x10 * (GFS2_DEFAULT_BSIZE / sbd.bsize);
|
|
Packit |
6ef888 |
else {
|
|
Packit |
6ef888 |
block = starting_blk = 0;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
fix_device_geometry(&sbd;;
|
|
Packit |
6ef888 |
if(sbd.gfs1) {
|
|
Packit |
6ef888 |
sbd.sd_inptrs = (sbd.bsize - sizeof(struct gfs_indirect)) /
|
|
Packit |
6ef888 |
sizeof(uint64_t);
|
|
Packit |
6ef888 |
sbd.sd_diptrs = (sbd.bsize - sizeof(struct gfs_dinode)) /
|
|
Packit |
6ef888 |
sizeof(uint64_t);
|
|
Packit |
6ef888 |
sbd.md.riinode = lgfs2_inode_read(&sbd, sbd1->sb_rindex_di.no_addr);
|
|
Packit |
6ef888 |
} else {
|
|
Packit |
6ef888 |
sbd.sd_inptrs = (sbd.bsize - sizeof(struct gfs2_meta_header)) /
|
|
Packit |
6ef888 |
sizeof(uint64_t);
|
|
Packit |
6ef888 |
sbd.sd_diptrs = (sbd.bsize - sizeof(struct gfs2_dinode)) /
|
|
Packit |
6ef888 |
sizeof(uint64_t);
|
|
Packit |
6ef888 |
sbd.master_dir = lgfs2_inode_read(&sbd,
|
|
Packit |
6ef888 |
sbd.sd_sb.sb_master_dir.no_addr);
|
|
Packit |
6ef888 |
if (sbd.master_dir == NULL) {
|
|
Packit |
6ef888 |
sbd.md.riinode = NULL;
|
|
Packit |
6ef888 |
} else {
|
|
Packit |
6ef888 |
gfs2_lookupi(sbd.master_dir, "rindex", 6, &sbd.md.riinode);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
brelse(bh);
|
|
Packit |
6ef888 |
bh = NULL;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
static int read_rindex(void)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
struct gfs2_rindex *ri;
|
|
Packit |
6ef888 |
uint64_t count;
|
|
Packit |
6ef888 |
int sane;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
sbd.fssize = sbd.device.length;
|
|
Packit |
6ef888 |
if (sbd.md.riinode) /* If we found the rindex */
|
|
Packit |
6ef888 |
rindex_read(&sbd, 0, &count, &sane);
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (!OSI_EMPTY_ROOT(&sbd.rgtree)) {
|
|
Packit |
6ef888 |
ri = &((struct rgrp_tree *)osi_last(&sbd.rgtree))->ri;
|
|
Packit |
6ef888 |
sbd.fssize = ri->ri_data0 + ri->ri_data;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
return 0;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
static int read_master_dir(void)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
ioctl(sbd.device_fd, BLKFLSBUF, 0);
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
bh = bread(&sbd, sbd.sd_sb.sb_master_dir.no_addr);
|
|
Packit |
6ef888 |
if (bh == NULL)
|
|
Packit |
6ef888 |
return 1;
|
|
Packit |
6ef888 |
gfs2_dinode_in(&di, bh->b_data);
|
|
Packit |
6ef888 |
do_dinode_extended(&di, bh); /* get extended data, if any */
|
|
Packit |
6ef888 |
memcpy(&masterdir, &indirect[0], sizeof(struct indirect_info));
|
|
Packit |
6ef888 |
return 0;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
int display(int identify_only, int trunc_zeros, uint64_t flagref,
|
|
Packit |
6ef888 |
uint64_t ref_blk)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
uint64_t blk;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (block == RGLIST_DUMMY_BLOCK) {
|
|
Packit |
6ef888 |
if (sbd.gfs1)
|
|
Packit |
6ef888 |
blk = sbd1->sb_rindex_di.no_addr;
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
blk = masterblock("rindex");
|
|
Packit |
6ef888 |
} else if (block == JOURNALS_DUMMY_BLOCK) {
|
|
Packit |
6ef888 |
if (sbd.gfs1)
|
|
Packit |
6ef888 |
blk = sbd1->sb_jindex_di.no_addr;
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
blk = masterblock("jindex");
|
|
Packit |
6ef888 |
} else
|
|
Packit |
6ef888 |
blk = block;
|
|
Packit |
6ef888 |
if (termlines) {
|
|
Packit |
6ef888 |
display_title_lines();
|
|
Packit |
6ef888 |
move(2,0);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
if (bh == NULL || bh->b_blocknr != blk) { /* If we changed blocks from the last read */
|
|
Packit |
6ef888 |
if (bh != NULL)
|
|
Packit |
6ef888 |
brelse(bh);
|
|
Packit |
6ef888 |
dev_offset = blk * sbd.bsize;
|
|
Packit |
6ef888 |
ioctl(sbd.device_fd, BLKFLSBUF, 0);
|
|
Packit |
6ef888 |
if (!(bh = bread(&sbd, blk))) {
|
|
Packit |
6ef888 |
fprintf(stderr, "read error: %s from %s:%d: "
|
|
Packit |
6ef888 |
"offset %lld (0x%llx)\n",
|
|
Packit |
6ef888 |
strerror(errno), __FUNCTION__, __LINE__,
|
|
Packit |
6ef888 |
(unsigned long long)dev_offset,
|
|
Packit |
6ef888 |
(unsigned long long)dev_offset);
|
|
Packit |
6ef888 |
exit(-1);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
line = 1;
|
|
Packit |
6ef888 |
gfs2_struct_type = display_block_type(bh, FALSE);
|
|
Packit |
6ef888 |
if (identify_only)
|
|
Packit |
6ef888 |
return 0;
|
|
Packit |
6ef888 |
indirect_blocks = 0;
|
|
Packit |
6ef888 |
lines_per_row[dmode] = 1;
|
|
Packit |
6ef888 |
if (gfs2_struct_type == GFS2_METATYPE_SB || blk == 0x10 * (4096 / sbd.bsize)) {
|
|
Packit |
6ef888 |
gfs2_sb_in(&sbd.sd_sb, bh->b_data);
|
|
Packit |
6ef888 |
memset(indirect, 0, sizeof(struct iinfo));
|
|
Packit |
6ef888 |
indirect->ii[0].block = sbd.sd_sb.sb_master_dir.no_addr;
|
|
Packit |
6ef888 |
indirect->ii[0].is_dir = TRUE;
|
|
Packit |
6ef888 |
indirect->ii[0].dirents = 2;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
memcpy(&indirect->ii[0].dirent[0].filename, "root", 4);
|
|
Packit |
6ef888 |
indirect->ii[0].dirent[0].dirent.de_inum.no_formal_ino =
|
|
Packit |
6ef888 |
sbd.sd_sb.sb_root_dir.no_formal_ino;
|
|
Packit |
6ef888 |
indirect->ii[0].dirent[0].dirent.de_inum.no_addr =
|
|
Packit |
6ef888 |
sbd.sd_sb.sb_root_dir.no_addr;
|
|
Packit |
6ef888 |
indirect->ii[0].dirent[0].block = sbd.sd_sb.sb_root_dir.no_addr;
|
|
Packit |
6ef888 |
indirect->ii[0].dirent[0].dirent.de_type = DT_DIR;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
memcpy(&indirect->ii[0].dirent[1].filename, "master", 7);
|
|
Packit |
6ef888 |
indirect->ii[0].dirent[1].dirent.de_inum.no_formal_ino =
|
|
Packit |
6ef888 |
sbd.sd_sb.sb_master_dir.no_formal_ino;
|
|
Packit |
6ef888 |
indirect->ii[0].dirent[1].dirent.de_inum.no_addr =
|
|
Packit |
6ef888 |
sbd.sd_sb.sb_master_dir.no_addr;
|
|
Packit |
6ef888 |
indirect->ii[0].dirent[1].block = sbd.sd_sb.sb_master_dir.no_addr;
|
|
Packit |
6ef888 |
indirect->ii[0].dirent[1].dirent.de_type = DT_DIR;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
else if (gfs2_struct_type == GFS2_METATYPE_DI) {
|
|
Packit |
6ef888 |
gfs2_dinode_in(&di, bh->b_data);
|
|
Packit |
6ef888 |
do_dinode_extended(&di, bh); /* get extended data, if any */
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
else if (gfs2_struct_type == GFS2_METATYPE_IN) { /* indirect block list */
|
|
Packit |
6ef888 |
if (blockhist) {
|
|
Packit |
6ef888 |
int i;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
for (i = 0; i < 512; i++)
|
|
Packit |
6ef888 |
memcpy(&indirect->ii[i].mp,
|
|
Packit |
6ef888 |
&blockstack[blockhist - 1].mp,
|
|
Packit |
6ef888 |
sizeof(struct metapath));
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
indirect_blocks = do_indirect_extended(bh->b_data, indirect);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
else if (gfs2_struct_type == GFS2_METATYPE_LF) { /* directory leaf */
|
|
Packit |
6ef888 |
do_leaf_extended(bh->b_data, indirect);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
last_entry_onscreen[dmode] = 0;
|
|
Packit |
6ef888 |
if (dmode == EXTENDED_MODE && !block_has_extended_info())
|
|
Packit |
6ef888 |
dmode = HEX_MODE;
|
|
Packit |
6ef888 |
if (termlines) {
|
|
Packit |
6ef888 |
move(termlines, 63);
|
|
Packit |
6ef888 |
if (dmode==HEX_MODE)
|
|
Packit |
6ef888 |
printw("Mode: Hex %s", (editing?"edit ":"view "));
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
printw("Mode: %s", (dmode==GFS2_MODE?"Structure":
|
|
Packit |
6ef888 |
"Pointers "));
|
|
Packit |
6ef888 |
move(line, 0);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
if (dmode == HEX_MODE) /* if hex display mode */
|
|
Packit |
6ef888 |
hexdump(dev_offset, (gfs2_struct_type == GFS2_METATYPE_DI)?
|
|
Packit |
6ef888 |
struct_len + di.di_size:sbd.bsize, trunc_zeros,
|
|
Packit |
6ef888 |
flagref, ref_blk);
|
|
Packit |
6ef888 |
else if (dmode == GFS2_MODE) { /* if structure display */
|
|
Packit |
6ef888 |
if (block != JOURNALS_DUMMY_BLOCK)
|
|
Packit |
6ef888 |
display_gfs2(bh); /* display the gfs2 structure */
|
|
Packit |
6ef888 |
} else
|
|
Packit |
6ef888 |
display_extended(); /* display extended blocks */
|
|
Packit |
6ef888 |
/* No else here because display_extended can switch back to hex mode */
|
|
Packit |
6ef888 |
if (termlines)
|
|
Packit |
6ef888 |
refresh();
|
|
Packit |
6ef888 |
return(0);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* push_block - push a block onto the block stack */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
static void push_block(uint64_t blk)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
int i, bhst;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
bhst = blockhist % BLOCK_STACK_SIZE;
|
|
Packit |
6ef888 |
if (blk) {
|
|
Packit |
6ef888 |
blockstack[bhst].dmode = dmode;
|
|
Packit |
6ef888 |
for (i = 0; i < DMODES; i++) {
|
|
Packit |
6ef888 |
blockstack[bhst].start_row[i] = start_row[i];
|
|
Packit |
6ef888 |
blockstack[bhst].end_row[i] = end_row[i];
|
|
Packit |
6ef888 |
blockstack[bhst].edit_row[i] = edit_row[i];
|
|
Packit |
6ef888 |
blockstack[bhst].edit_col[i] = edit_col[i];
|
|
Packit |
6ef888 |
blockstack[bhst].lines_per_row[i] = lines_per_row[i];
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
blockstack[bhst].gfs2_struct_type = gfs2_struct_type;
|
|
Packit |
6ef888 |
if (edit_row[dmode] >= 0 && !block_is_rindex(block))
|
|
Packit |
6ef888 |
memcpy(&blockstack[bhst].mp,
|
|
Packit |
6ef888 |
&indirect->ii[edit_row[dmode]].mp,
|
|
Packit |
6ef888 |
sizeof(struct metapath));
|
|
Packit |
6ef888 |
blockhist++;
|
|
Packit |
6ef888 |
blockstack[blockhist % BLOCK_STACK_SIZE].block = blk;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* pop_block - pop a block off the block stack */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
static uint64_t pop_block(void)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
int i, bhst;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (!blockhist)
|
|
Packit |
6ef888 |
return block;
|
|
Packit |
6ef888 |
blockhist--;
|
|
Packit |
6ef888 |
bhst = blockhist % BLOCK_STACK_SIZE;
|
|
Packit |
6ef888 |
dmode = blockstack[bhst].dmode;
|
|
Packit |
6ef888 |
for (i = 0; i < DMODES; i++) {
|
|
Packit |
6ef888 |
start_row[i] = blockstack[bhst].start_row[i];
|
|
Packit |
6ef888 |
end_row[i] = blockstack[bhst].end_row[i];
|
|
Packit |
6ef888 |
edit_row[i] = blockstack[bhst].edit_row[i];
|
|
Packit |
6ef888 |
edit_col[i] = blockstack[bhst].edit_col[i];
|
|
Packit |
6ef888 |
lines_per_row[i] = blockstack[bhst].lines_per_row[i];
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
gfs2_struct_type = blockstack[bhst].gfs2_struct_type;
|
|
Packit |
6ef888 |
return blockstack[bhst].block;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* Find next metadata block of a given type AFTER a given point in the fs */
|
|
Packit |
6ef888 |
/* */
|
|
Packit |
6ef888 |
/* This is used to find blocks that aren't represented in the bitmaps, such */
|
|
Packit |
6ef888 |
/* as the RGs and bitmaps or the superblock. */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
static uint64_t find_metablockoftype_slow(uint64_t startblk, int metatype, int print)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
uint64_t blk, last_fs_block;
|
|
Packit |
6ef888 |
int found = 0;
|
|
Packit |
6ef888 |
struct gfs2_buffer_head *lbh;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
last_fs_block = lseek(sbd.device_fd, 0, SEEK_END) / sbd.bsize;
|
|
Packit |
6ef888 |
for (blk = startblk + 1; blk < last_fs_block; blk++) {
|
|
Packit |
6ef888 |
lbh = bread(&sbd, blk);
|
|
Packit |
6ef888 |
/* Can't use get_block_type here (returns false "none") */
|
|
Packit |
6ef888 |
if (lbh->b_data[0] == 0x01 && lbh->b_data[1] == 0x16 &&
|
|
Packit |
6ef888 |
lbh->b_data[2] == 0x19 && lbh->b_data[3] == 0x70 &&
|
|
Packit |
6ef888 |
lbh->b_data[4] == 0x00 && lbh->b_data[5] == 0x00 &&
|
|
Packit |
6ef888 |
lbh->b_data[6] == 0x00 && lbh->b_data[7] == metatype) {
|
|
Packit |
6ef888 |
found = 1;
|
|
Packit |
6ef888 |
brelse(lbh);
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
brelse(lbh);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
if (!found)
|
|
Packit |
6ef888 |
blk = 0;
|
|
Packit |
6ef888 |
if (print) {
|
|
Packit |
6ef888 |
if (dmode == HEX_MODE)
|
|
Packit |
6ef888 |
printf("0x%llx\n", (unsigned long long)blk);
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
printf("%llu\n", (unsigned long long)blk);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
gfs2_rgrp_free(&sbd.rgtree);
|
|
Packit |
6ef888 |
if (print)
|
|
Packit |
6ef888 |
exit(0);
|
|
Packit |
6ef888 |
return blk;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
static int find_rg_metatype(struct rgrp_tree *rgd, uint64_t *blk, uint64_t startblk, int mtype)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
int found;
|
|
Packit |
6ef888 |
unsigned i, j, m;
|
|
Packit |
6ef888 |
struct gfs2_buffer_head *bhp = NULL;
|
|
Packit |
6ef888 |
uint64_t *ibuf = malloc(sbd.bsize * GFS2_NBBY * sizeof(uint64_t));
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
for (i = 0; i < rgd->ri.ri_length; i++) {
|
|
Packit |
6ef888 |
m = lgfs2_bm_scan(rgd, i, ibuf, GFS2_BLKST_DINODE);
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
for (j = 0; j < m; j++) {
|
|
Packit |
6ef888 |
*blk = ibuf[j];
|
|
Packit |
6ef888 |
bhp = bread(&sbd, *blk);
|
|
Packit |
6ef888 |
found = (*blk > startblk) && !gfs2_check_meta(bhp, mtype);
|
|
Packit |
6ef888 |
brelse(bhp);
|
|
Packit |
6ef888 |
if (found) {
|
|
Packit |
6ef888 |
free(ibuf);
|
|
Packit |
6ef888 |
return 0;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
free(ibuf);
|
|
Packit |
6ef888 |
return -1;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* Find next "metadata in use" block AFTER a given point in the fs */
|
|
Packit |
6ef888 |
/* */
|
|
Packit |
6ef888 |
/* This version does its magic by searching the bitmaps of the RG. After */
|
|
Packit |
6ef888 |
/* all, if we're searching for a dinode, we want a real allocated inode, */
|
|
Packit |
6ef888 |
/* not just some block that used to be an inode in a previous incarnation. */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
static uint64_t find_metablockoftype_rg(uint64_t startblk, int metatype, int print)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
struct osi_node *next = NULL;
|
|
Packit |
6ef888 |
uint64_t blk, errblk;
|
|
Packit |
6ef888 |
int first = 1, found = 0;
|
|
Packit |
6ef888 |
struct rgrp_tree *rgd = NULL;
|
|
Packit |
6ef888 |
struct gfs2_rindex *ri;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
blk = 0;
|
|
Packit |
6ef888 |
/* Skip the rgs prior to the block we've been given */
|
|
Packit |
6ef888 |
for (next = osi_first(&sbd.rgtree); next; next = osi_next(next)) {
|
|
Packit |
6ef888 |
rgd = (struct rgrp_tree *)next;
|
|
Packit |
6ef888 |
ri = &rgd->ri;
|
|
Packit |
6ef888 |
if (first && startblk <= ri->ri_data0) {
|
|
Packit |
6ef888 |
startblk = ri->ri_data0;
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
} else if (ri->ri_addr <= startblk &&
|
|
Packit |
6ef888 |
startblk < ri->ri_data0 + ri->ri_data)
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
rgd = NULL;
|
|
Packit |
6ef888 |
first = 0;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
if (!rgd) {
|
|
Packit |
6ef888 |
if (print)
|
|
Packit |
6ef888 |
printf("0\n");
|
|
Packit |
6ef888 |
gfs2_rgrp_free(&sbd.rgtree);
|
|
Packit |
6ef888 |
if (print)
|
|
Packit |
6ef888 |
exit(-1);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
for (; !found && next; next = osi_next(next)){
|
|
Packit |
6ef888 |
rgd = (struct rgrp_tree *)next;
|
|
Packit |
6ef888 |
errblk = gfs2_rgrp_read(&sbd, rgd);
|
|
Packit |
6ef888 |
if (errblk)
|
|
Packit |
6ef888 |
continue;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
found = !find_rg_metatype(rgd, &blk, startblk, metatype);
|
|
Packit |
6ef888 |
if (found)
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
gfs2_rgrp_relse(rgd);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (!found)
|
|
Packit |
6ef888 |
blk = 0;
|
|
Packit |
6ef888 |
if (print) {
|
|
Packit |
6ef888 |
if (dmode == HEX_MODE)
|
|
Packit |
6ef888 |
printf("0x%llx\n", (unsigned long long)blk);
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
printf("%llu\n", (unsigned long long)blk);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
gfs2_rgrp_free(&sbd.rgtree);
|
|
Packit |
6ef888 |
if (print)
|
|
Packit |
6ef888 |
exit(0);
|
|
Packit |
6ef888 |
return blk;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* Find next metadata block AFTER a given point in the fs */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
static uint64_t find_metablockoftype(const char *strtype, int print)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
int mtype = 0;
|
|
Packit |
6ef888 |
uint64_t startblk, blk = 0;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (print)
|
|
Packit |
6ef888 |
startblk = blockstack[blockhist % BLOCK_STACK_SIZE].block;
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
startblk = block;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
for (mtype = GFS2_METATYPE_NONE;
|
|
Packit |
6ef888 |
mtype <= GFS2_METATYPE_QC; mtype++)
|
|
Packit |
6ef888 |
if (!strcasecmp(strtype, mtypes[mtype]))
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
if (!strcmp(strtype, "dinode"))
|
|
Packit |
6ef888 |
mtype = GFS2_METATYPE_DI;
|
|
Packit |
6ef888 |
if (mtype >= GFS2_METATYPE_NONE && mtype <= GFS2_METATYPE_RB)
|
|
Packit |
6ef888 |
blk = find_metablockoftype_slow(startblk, mtype, print);
|
|
Packit |
6ef888 |
else if (mtype >= GFS2_METATYPE_DI && mtype <= GFS2_METATYPE_QC)
|
|
Packit |
6ef888 |
blk = find_metablockoftype_rg(startblk, mtype, print);
|
|
Packit |
6ef888 |
else if (print) {
|
|
Packit |
6ef888 |
fprintf(stderr, "Error: metadata type not "
|
|
Packit |
6ef888 |
"specified: must be one of:\n");
|
|
Packit |
6ef888 |
fprintf(stderr, "sb rg rb di in lf jd lh ld"
|
|
Packit |
6ef888 |
" ea ed lb 13 qc\n");
|
|
Packit |
6ef888 |
gfs2_rgrp_free(&sbd.rgtree);
|
|
Packit |
6ef888 |
exit(-1);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
return blk;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* Check if the word is a keyword such as "sb" or "rindex" */
|
|
Packit |
6ef888 |
/* Returns: block number if it is, else 0 */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
uint64_t check_keywords(const char *kword)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
unsigned long long blk = 0;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (!strcmp(kword, "sb") ||!strcmp(kword, "superblock"))
|
|
Packit |
6ef888 |
blk = 0x10 * (4096 / sbd.bsize); /* superblock */
|
|
Packit |
6ef888 |
else if (!strcmp(kword, "root") || !strcmp(kword, "rootdir"))
|
|
Packit |
6ef888 |
blk = sbd.sd_sb.sb_root_dir.no_addr;
|
|
Packit |
6ef888 |
else if (!strcmp(kword, "master")) {
|
|
Packit |
6ef888 |
if (sbd.gfs1)
|
|
Packit |
6ef888 |
fprintf(stderr, "This is GFS1; there's no master directory.\n");
|
|
Packit |
6ef888 |
else if (!sbd.sd_sb.sb_master_dir.no_addr) {
|
|
Packit |
6ef888 |
fprintf(stderr, "GFS2 master directory not found on %s\n", device);
|
|
Packit |
6ef888 |
exit(-1);
|
|
Packit |
6ef888 |
} else
|
|
Packit |
6ef888 |
blk = sbd.sd_sb.sb_master_dir.no_addr;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
else if (!strcmp(kword, "jindex")) {
|
|
Packit |
6ef888 |
if (sbd.gfs1)
|
|
Packit |
6ef888 |
blk = sbd1->sb_jindex_di.no_addr;
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
blk = masterblock("jindex"); /* journal index */
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
else if (!sbd.gfs1 && !strcmp(kword, "per_node"))
|
|
Packit |
6ef888 |
blk = masterblock("per_node");
|
|
Packit |
6ef888 |
else if (!sbd.gfs1 && !strcmp(kword, "inum"))
|
|
Packit |
6ef888 |
blk = masterblock("inum");
|
|
Packit |
6ef888 |
else if (!strcmp(kword, "statfs")) {
|
|
Packit |
6ef888 |
if (sbd.gfs1)
|
|
Packit |
6ef888 |
blk = gfs1_license_di.no_addr;
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
blk = masterblock("statfs");
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
else if (!strcmp(kword, "rindex") || !strcmp(kword, "rgindex")) {
|
|
Packit |
6ef888 |
if (sbd.gfs1)
|
|
Packit |
6ef888 |
blk = sbd1->sb_rindex_di.no_addr;
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
blk = masterblock("rindex");
|
|
Packit |
6ef888 |
} else if (!strcmp(kword, "rgs")) {
|
|
Packit |
6ef888 |
blk = RGLIST_DUMMY_BLOCK;
|
|
Packit |
6ef888 |
} else if (!strcmp(kword, "quota")) {
|
|
Packit |
6ef888 |
if (sbd.gfs1)
|
|
Packit |
6ef888 |
blk = gfs1_quota_di.no_addr;
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
blk = masterblock("quota");
|
|
Packit |
6ef888 |
} else if (!strncmp(kword, "rg ", 3)) {
|
|
Packit |
6ef888 |
int rgnum = 0;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
rgnum = atoi(kword + 3);
|
|
Packit |
6ef888 |
blk = get_rg_addr(rgnum);
|
|
Packit |
6ef888 |
} else if (!strncmp(kword, "journals", 8)) {
|
|
Packit |
6ef888 |
blk = JOURNALS_DUMMY_BLOCK;
|
|
Packit |
6ef888 |
} else if (strlen(kword) > 7 && !strncmp(kword, "journal", 7) && isdigit(kword[7])) {
|
|
Packit |
6ef888 |
uint64_t j_size;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
blk = find_journal_block(kword, &j_size);
|
|
Packit |
6ef888 |
} else if (kword[0]=='/') /* search */
|
|
Packit |
6ef888 |
blk = find_metablockoftype(&kword[1], 0);
|
|
Packit |
6ef888 |
else if (kword[0]=='0' && kword[1]=='x') /* hex addr */
|
|
Packit |
6ef888 |
sscanf(kword, "%llx", &blk);/* retrieve in hex */
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
sscanf(kword, "%llu", &blk); /* retrieve decimal */
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
return blk;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* goto_block - go to a desired block entered by the user */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
static uint64_t goto_block(void)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
char string[256];
|
|
Packit |
6ef888 |
int ch, delta;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
memset(string, 0, sizeof(string));
|
|
Packit |
6ef888 |
sprintf(string,"%lld", (long long)block);
|
|
Packit |
6ef888 |
if (bobgets(string, 1, 7, 16, &ch)) {
|
|
Packit |
6ef888 |
if (isalnum(string[0]) || string[0] == '/')
|
|
Packit |
6ef888 |
temp_blk = check_keywords(string);
|
|
Packit |
6ef888 |
else if (string[0] == '+' || string[0] == '-') {
|
|
Packit |
6ef888 |
if (string[1] == '0' && string[2] == 'x')
|
|
Packit |
6ef888 |
sscanf(string, "%x", &delta);
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
sscanf(string, "%d", &delta);
|
|
Packit |
6ef888 |
temp_blk = block + delta;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (temp_blk == RGLIST_DUMMY_BLOCK ||
|
|
Packit |
6ef888 |
temp_blk == JOURNALS_DUMMY_BLOCK || temp_blk < max_block) {
|
|
Packit |
6ef888 |
offset = 0;
|
|
Packit |
6ef888 |
block = temp_blk;
|
|
Packit |
6ef888 |
push_block(block);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
return block;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* init_colors */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
static void init_colors(void)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (color_scheme) {
|
|
Packit |
6ef888 |
init_pair(COLOR_TITLE, COLOR_BLACK, COLOR_CYAN);
|
|
Packit |
6ef888 |
init_pair(COLOR_NORMAL, COLOR_WHITE, COLOR_BLACK);
|
|
Packit |
6ef888 |
init_pair(COLOR_INVERSE, COLOR_BLACK, COLOR_WHITE);
|
|
Packit |
6ef888 |
init_pair(COLOR_SPECIAL, COLOR_RED, COLOR_BLACK);
|
|
Packit |
6ef888 |
init_pair(COLOR_HIGHLIGHT, COLOR_GREEN, COLOR_BLACK);
|
|
Packit |
6ef888 |
init_pair(COLOR_OFFSETS, COLOR_CYAN, COLOR_BLACK);
|
|
Packit |
6ef888 |
init_pair(COLOR_CONTENTS, COLOR_YELLOW, COLOR_BLACK);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
else {
|
|
Packit |
6ef888 |
init_pair(COLOR_TITLE, COLOR_BLACK, COLOR_CYAN);
|
|
Packit |
6ef888 |
init_pair(COLOR_NORMAL, COLOR_BLACK, COLOR_WHITE);
|
|
Packit |
6ef888 |
init_pair(COLOR_INVERSE, COLOR_WHITE, COLOR_BLACK);
|
|
Packit |
6ef888 |
init_pair(COLOR_SPECIAL, COLOR_MAGENTA, COLOR_WHITE);
|
|
Packit |
6ef888 |
init_pair(COLOR_HIGHLIGHT, COLOR_RED, COLOR_WHITE); /*cursor*/
|
|
Packit |
6ef888 |
init_pair(COLOR_OFFSETS, COLOR_CYAN, COLOR_WHITE);
|
|
Packit |
6ef888 |
init_pair(COLOR_CONTENTS, COLOR_BLUE, COLOR_WHITE);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* hex_edit - Allow the user to edit the page by entering hex digits */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
static void hex_edit(int *exitch)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
int left_off;
|
|
Packit |
6ef888 |
int ch;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
left_off = ((block * sbd.bsize) < 0xffffffff) ? 9 : 17;
|
|
Packit |
6ef888 |
/* 8 and 16 char addresses on screen */
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (bobgets(estring, edit_row[HEX_MODE] + 3,
|
|
Packit |
6ef888 |
(edit_col[HEX_MODE] * 2) + (edit_col[HEX_MODE] / 4) +
|
|
Packit |
6ef888 |
left_off, 2, exitch)) {
|
|
Packit |
6ef888 |
if (strstr(edit_fmt,"X") || strstr(edit_fmt,"x")) {
|
|
Packit |
6ef888 |
int hexoffset;
|
|
Packit |
6ef888 |
int i, sl = strlen(estring);
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
for (i = 0; i < sl; i+=2) {
|
|
Packit |
6ef888 |
hexoffset = (edit_row[HEX_MODE] * 16) +
|
|
Packit |
6ef888 |
edit_col[HEX_MODE] + (i / 2);
|
|
Packit |
6ef888 |
ch = 0x00;
|
|
Packit |
6ef888 |
if (isdigit(estring[i]))
|
|
Packit |
6ef888 |
ch = (estring[i] - '0') * 0x10;
|
|
Packit |
6ef888 |
else if (estring[i] >= 'a' &&
|
|
Packit |
6ef888 |
estring[i] <= 'f')
|
|
Packit |
6ef888 |
ch = (estring[i]-'a' + 0x0a)*0x10;
|
|
Packit |
6ef888 |
else if (estring[i] >= 'A' &&
|
|
Packit |
6ef888 |
estring[i] <= 'F')
|
|
Packit |
6ef888 |
ch = (estring[i] - 'A' + 0x0a) * 0x10;
|
|
Packit |
6ef888 |
if (isdigit(estring[i+1]))
|
|
Packit |
6ef888 |
ch += (estring[i+1] - '0');
|
|
Packit |
6ef888 |
else if (estring[i+1] >= 'a' &&
|
|
Packit |
6ef888 |
estring[i+1] <= 'f')
|
|
Packit |
6ef888 |
ch += (estring[i+1] - 'a' + 0x0a);
|
|
Packit |
6ef888 |
else if (estring[i+1] >= 'A' &&
|
|
Packit |
6ef888 |
estring[i+1] <= 'F')
|
|
Packit |
6ef888 |
ch += (estring[i+1] - 'A' + 0x0a);
|
|
Packit |
6ef888 |
bh->b_data[offset + hexoffset] = ch;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
if (pwrite(sbd.device_fd, bh->b_data, sbd.bsize, dev_offset) !=
|
|
Packit |
6ef888 |
sbd.bsize) {
|
|
Packit |
6ef888 |
fprintf(stderr, "write error: %s from %s:%d: "
|
|
Packit |
6ef888 |
"offset %lld (0x%llx)\n",
|
|
Packit |
6ef888 |
strerror(errno),
|
|
Packit |
6ef888 |
__FUNCTION__, __LINE__,
|
|
Packit |
6ef888 |
(unsigned long long)dev_offset,
|
|
Packit |
6ef888 |
(unsigned long long)dev_offset);
|
|
Packit |
6ef888 |
exit(-1);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
fsync(sbd.device_fd);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* page up */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
static void pageup(void)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
if (dmode == EXTENDED_MODE) {
|
|
Packit |
6ef888 |
if (edit_row[dmode] - (dsplines / lines_per_row[dmode]) > 0)
|
|
Packit |
6ef888 |
edit_row[dmode] -= (dsplines / lines_per_row[dmode]);
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
edit_row[dmode] = 0;
|
|
Packit |
6ef888 |
if (start_row[dmode] - (dsplines / lines_per_row[dmode]) > 0)
|
|
Packit |
6ef888 |
start_row[dmode] -= (dsplines / lines_per_row[dmode]);
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
start_row[dmode] = 0;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
else {
|
|
Packit |
6ef888 |
start_row[dmode] = edit_row[dmode] = 0;
|
|
Packit |
6ef888 |
if (dmode == GFS2_MODE || offset==0) {
|
|
Packit |
6ef888 |
block--;
|
|
Packit |
6ef888 |
if (dmode == HEX_MODE)
|
|
Packit |
6ef888 |
offset = (sbd.bsize % screen_chunk_size) > 0 ?
|
|
Packit |
6ef888 |
screen_chunk_size *
|
|
Packit |
6ef888 |
(sbd.bsize / screen_chunk_size) :
|
|
Packit |
6ef888 |
sbd.bsize - screen_chunk_size;
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
offset = 0;
|
|
Packit |
6ef888 |
} else
|
|
Packit |
6ef888 |
offset -= screen_chunk_size;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* page down */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
static void pagedn(void)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
if (dmode == EXTENDED_MODE) {
|
|
Packit |
6ef888 |
if ((edit_row[dmode] + dsplines) / lines_per_row[dmode] + 1 <=
|
|
Packit |
6ef888 |
end_row[dmode]) {
|
|
Packit |
6ef888 |
start_row[dmode] += dsplines / lines_per_row[dmode];
|
|
Packit |
6ef888 |
edit_row[dmode] += dsplines / lines_per_row[dmode];
|
|
Packit |
6ef888 |
} else {
|
|
Packit |
6ef888 |
edit_row[dmode] = end_row[dmode] - 1;
|
|
Packit |
6ef888 |
while (edit_row[dmode] - start_row[dmode]
|
|
Packit |
6ef888 |
+ 1 > last_entry_onscreen[dmode])
|
|
Packit |
6ef888 |
start_row[dmode]++;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
else {
|
|
Packit |
6ef888 |
start_row[dmode] = edit_row[dmode] = 0;
|
|
Packit |
6ef888 |
if (dmode == GFS2_MODE ||
|
|
Packit |
6ef888 |
offset + screen_chunk_size >= sbd.bsize) {
|
|
Packit |
6ef888 |
block++;
|
|
Packit |
6ef888 |
offset = 0;
|
|
Packit |
6ef888 |
} else
|
|
Packit |
6ef888 |
offset += screen_chunk_size;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* jump - jump to the address the cursor is on */
|
|
Packit |
6ef888 |
/* */
|
|
Packit |
6ef888 |
/* If the cursor is in a log descriptor, jump to the log-descriptor version */
|
|
Packit |
6ef888 |
/* of the block instead of the "real" block. */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
static void jump(void)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
if (dmode == HEX_MODE) {
|
|
Packit |
6ef888 |
unsigned int col2;
|
|
Packit |
6ef888 |
uint64_t *b;
|
|
Packit |
6ef888 |
const uint32_t block_type = get_block_type(bh, NULL);
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* special exception for log descriptors: jump the journaled
|
|
Packit |
6ef888 |
version of the block, not the "real" block */
|
|
Packit |
6ef888 |
if (block_type == GFS2_METATYPE_LD) {
|
|
Packit |
6ef888 |
int ptroffset = edit_row[dmode] * 16 + edit_col[dmode];
|
|
Packit |
6ef888 |
int pnum = get_pnum(ptroffset);
|
|
Packit |
6ef888 |
temp_blk = bh->b_blocknr + pnum + 1;
|
|
Packit |
6ef888 |
} else if (edit_row[dmode] >= 0) {
|
|
Packit |
6ef888 |
col2 = edit_col[dmode] & 0x08;/* thus 0-7->0, 8-15->8 */
|
|
Packit |
6ef888 |
b = (uint64_t *)&bh->b_data[edit_row[dmode]*16 +
|
|
Packit |
6ef888 |
offset + col2];
|
|
Packit |
6ef888 |
temp_blk = be64_to_cpu(*b);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
sscanf(estring, "%"SCNx64, &temp_blk);/* retrieve in hex */
|
|
Packit |
6ef888 |
if (temp_blk < max_block) { /* if the block number is valid */
|
|
Packit |
6ef888 |
int i;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
offset = 0;
|
|
Packit |
6ef888 |
push_block(temp_blk);
|
|
Packit |
6ef888 |
block = temp_blk;
|
|
Packit |
6ef888 |
for (i = 0; i < DMODES; i++) {
|
|
Packit |
6ef888 |
start_row[i] = end_row[i] = edit_row[i] = 0;
|
|
Packit |
6ef888 |
edit_col[i] = 0;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* print block type */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
static void print_block_type(uint64_t tblock, int type, const char *additional)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
if (type <= GFS2_METATYPE_QC)
|
|
Packit |
6ef888 |
printf("%d (Block %lld is type %d: %s%s)\n", type,
|
|
Packit |
6ef888 |
(unsigned long long)tblock, type, block_type_str[type],
|
|
Packit |
6ef888 |
additional);
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
printf("%d (Block %lld is type %d: unknown%s)\n", type,
|
|
Packit |
6ef888 |
(unsigned long long)tblock, type, additional);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* find_print block type */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
static void find_print_block_type(void)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
uint64_t tblock;
|
|
Packit |
6ef888 |
struct gfs2_buffer_head *lbh;
|
|
Packit |
6ef888 |
int type;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
tblock = blockstack[blockhist % BLOCK_STACK_SIZE].block;
|
|
Packit |
6ef888 |
lbh = bread(&sbd, tblock);
|
|
Packit |
6ef888 |
type = get_block_type(lbh, NULL);
|
|
Packit |
6ef888 |
print_block_type(tblock, type, "");
|
|
Packit |
6ef888 |
brelse(lbh);
|
|
Packit |
6ef888 |
gfs2_rgrp_free(&sbd.rgtree);
|
|
Packit |
6ef888 |
exit(0);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* Find and print the resource group associated with a given block */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
static void find_print_block_rg(int bitmap)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
uint64_t rblock, rgblock;
|
|
Packit |
6ef888 |
int i;
|
|
Packit |
6ef888 |
struct rgrp_tree *rgd;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
rblock = blockstack[blockhist % BLOCK_STACK_SIZE].block;
|
|
Packit |
6ef888 |
if (rblock == LGFS2_SB_ADDR(&sbd))
|
|
Packit |
6ef888 |
printf("0 (the superblock is not in the bitmap)\n");
|
|
Packit |
6ef888 |
else {
|
|
Packit |
6ef888 |
rgd = gfs2_blk2rgrpd(&sbd, rblock);
|
|
Packit |
6ef888 |
if (rgd) {
|
|
Packit |
6ef888 |
rgblock = rgd->ri.ri_addr;
|
|
Packit |
6ef888 |
if (bitmap) {
|
|
Packit |
6ef888 |
struct gfs2_bitmap *bits = NULL;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
for (i = 0; i < rgd->ri.ri_length; i++) {
|
|
Packit |
6ef888 |
bits = &(rgd->bits[i]);
|
|
Packit |
6ef888 |
if (rblock - rgd->ri.ri_data0 <
|
|
Packit |
6ef888 |
((bits->bi_start + bits->bi_len) *
|
|
Packit |
6ef888 |
GFS2_NBBY)) {
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
if (i < rgd->ri.ri_length)
|
|
Packit |
6ef888 |
rgblock += i;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
if (dmode == HEX_MODE)
|
|
Packit |
6ef888 |
printf("0x%llx\n",(unsigned long long)rgblock);
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
printf("%llu\n", (unsigned long long)rgblock);
|
|
Packit |
6ef888 |
} else {
|
|
Packit |
6ef888 |
printf("-1 (block invalid or part of an rgrp).\n");
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
gfs2_rgrp_free(&sbd.rgtree);
|
|
Packit |
6ef888 |
exit(0);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* find/change/print block allocation (what the bitmap says about block) */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
static void find_change_block_alloc(int *newval)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
uint64_t ablock;
|
|
Packit |
6ef888 |
int type;
|
|
Packit |
6ef888 |
struct rgrp_tree *rgd;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (newval &&
|
|
Packit |
6ef888 |
(*newval < GFS2_BLKST_FREE || *newval > GFS2_BLKST_DINODE)) {
|
|
Packit |
6ef888 |
int i;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
printf("Error: value %d is not valid.\nValid values are:\n",
|
|
Packit |
6ef888 |
*newval);
|
|
Packit |
6ef888 |
for (i = GFS2_BLKST_FREE; i <= GFS2_BLKST_DINODE; i++)
|
|
Packit |
6ef888 |
printf("%d - %s\n", i, allocdesc[sbd.gfs1][i]);
|
|
Packit |
6ef888 |
gfs2_rgrp_free(&sbd.rgtree);
|
|
Packit |
6ef888 |
exit(-1);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
ablock = blockstack[blockhist % BLOCK_STACK_SIZE].block;
|
|
Packit |
6ef888 |
if (ablock == LGFS2_SB_ADDR(&sbd))
|
|
Packit |
6ef888 |
printf("3 (the superblock is not in the bitmap)\n");
|
|
Packit |
6ef888 |
else {
|
|
Packit |
6ef888 |
rgd = gfs2_blk2rgrpd(&sbd, ablock);
|
|
Packit |
6ef888 |
if (rgd) {
|
|
Packit |
6ef888 |
gfs2_rgrp_read(&sbd, rgd);
|
|
Packit |
6ef888 |
if (newval) {
|
|
Packit |
6ef888 |
if (gfs2_set_bitmap(rgd, ablock, *newval))
|
|
Packit |
6ef888 |
printf("-1 (block invalid or part of an rgrp).\n");
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
printf("%d\n", *newval);
|
|
Packit |
6ef888 |
} else {
|
|
Packit |
6ef888 |
type = lgfs2_get_bitmap(&sbd, ablock, rgd);
|
|
Packit |
6ef888 |
if (type < 0) {
|
|
Packit |
6ef888 |
printf("-1 (block invalid or part of "
|
|
Packit |
6ef888 |
"an rgrp).\n");
|
|
Packit |
6ef888 |
exit(-1);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
printf("%d (%s)\n", type, allocdesc[sbd.gfs1][type]);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
gfs2_rgrp_relse(rgd);
|
|
Packit |
6ef888 |
} else {
|
|
Packit |
6ef888 |
gfs2_rgrp_free(&sbd.rgtree);
|
|
Packit |
6ef888 |
printf("-1 (block invalid or part of an rgrp).\n");
|
|
Packit |
6ef888 |
exit(-1);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
gfs2_rgrp_free(&sbd.rgtree);
|
|
Packit |
6ef888 |
if (newval)
|
|
Packit |
6ef888 |
fsync(sbd.device_fd);
|
|
Packit |
6ef888 |
exit(0);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/**
|
|
Packit |
6ef888 |
* process request to print a certain field from a previously pushed block
|
|
Packit |
6ef888 |
*/
|
|
Packit |
6ef888 |
static void process_field(const char *field, const char *nstr)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
uint64_t fblock;
|
|
Packit |
6ef888 |
struct gfs2_buffer_head *rbh;
|
|
Packit |
6ef888 |
int type;
|
|
Packit |
6ef888 |
const struct lgfs2_metadata *mtype;
|
|
Packit |
6ef888 |
const struct lgfs2_metafield *mfield;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
fblock = blockstack[blockhist % BLOCK_STACK_SIZE].block;
|
|
Packit |
6ef888 |
rbh = bread(&sbd, fblock);
|
|
Packit |
6ef888 |
type = get_block_type(rbh, NULL);
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
mtype = lgfs2_find_mtype(type, sbd.gfs1 ? LGFS2_MD_GFS1 : LGFS2_MD_GFS2);
|
|
Packit |
6ef888 |
if (mtype == NULL) {
|
|
Packit |
6ef888 |
fprintf(stderr, "Metadata type '%d' invalid\n", type);
|
|
Packit |
6ef888 |
exit(1);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
mfield = lgfs2_find_mfield_name(field, mtype);
|
|
Packit |
6ef888 |
if (mfield == NULL) {
|
|
Packit |
6ef888 |
fprintf(stderr, "No field '%s' in block type '%s'\n", field, mtype->name);
|
|
Packit |
6ef888 |
exit(1);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (nstr != device) {
|
|
Packit |
6ef888 |
int err = 0;
|
|
Packit |
6ef888 |
if (mfield->flags & (LGFS2_MFF_UUID|LGFS2_MFF_STRING)) {
|
|
Packit |
6ef888 |
err = lgfs2_field_assign(rbh->b_data, mfield, nstr);
|
|
Packit |
6ef888 |
} else {
|
|
Packit |
6ef888 |
uint64_t val = 0;
|
|
Packit |
6ef888 |
err = sscanf(nstr, "%"SCNi64, &val;;
|
|
Packit |
6ef888 |
if (err == 1)
|
|
Packit |
6ef888 |
err = lgfs2_field_assign(rbh->b_data, mfield, &val;;
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
err = -1;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
if (err != 0) {
|
|
Packit |
6ef888 |
fprintf(stderr, "Could not set '%s' to '%s': %s\n", field, nstr,
|
|
Packit |
6ef888 |
strerror(errno));
|
|
Packit |
6ef888 |
exit(1);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
bmodified(rbh);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (!termlines) {
|
|
Packit |
6ef888 |
char str[GFS2_LOCKNAME_LEN] = "";
|
|
Packit |
6ef888 |
lgfs2_field_str(str, GFS2_LOCKNAME_LEN, rbh->b_data, mfield, (dmode == HEX_MODE));
|
|
Packit |
6ef888 |
printf("%s\n", str);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
brelse(rbh);
|
|
Packit |
6ef888 |
fsync(sbd.device_fd);
|
|
Packit |
6ef888 |
exit(0);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* interactive_mode - accept keystrokes from user and display structures */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
static void interactive_mode(void)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
int ch = 0, Quit;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if ((wind = initscr()) == NULL) {
|
|
Packit |
6ef888 |
fprintf(stderr, "Error: unable to initialize screen.");
|
|
Packit |
6ef888 |
eol(0);
|
|
Packit |
6ef888 |
exit(-1);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
getmaxyx(stdscr, termlines, termcols);
|
|
Packit |
6ef888 |
termlines--;
|
|
Packit |
6ef888 |
/* Do our initial screen stuff: */
|
|
Packit |
6ef888 |
clear(); /* don't use Erase */
|
|
Packit |
6ef888 |
start_color();
|
|
Packit |
6ef888 |
noecho();
|
|
Packit |
6ef888 |
keypad(stdscr, TRUE);
|
|
Packit |
6ef888 |
raw();
|
|
Packit |
6ef888 |
curs_set(0);
|
|
Packit |
6ef888 |
init_colors();
|
|
Packit |
6ef888 |
/* Accept keystrokes and act on them accordingly */
|
|
Packit |
6ef888 |
Quit = FALSE;
|
|
Packit |
6ef888 |
editing = FALSE;
|
|
Packit |
6ef888 |
while (!Quit) {
|
|
Packit |
6ef888 |
display(FALSE, 0, 0, 0);
|
|
Packit |
6ef888 |
if (editing) {
|
|
Packit |
6ef888 |
if (edit_row[dmode] == -1)
|
|
Packit |
6ef888 |
block = goto_block();
|
|
Packit |
6ef888 |
else {
|
|
Packit |
6ef888 |
if (dmode == HEX_MODE)
|
|
Packit |
6ef888 |
hex_edit(&ch);
|
|
Packit |
6ef888 |
else if (dmode == GFS2_MODE) {
|
|
Packit |
6ef888 |
bobgets(estring, edit_row[dmode]+4, 24,
|
|
Packit |
6ef888 |
10, &ch);
|
|
Packit |
6ef888 |
process_field(efield, estring);
|
|
Packit |
6ef888 |
} else
|
|
Packit |
6ef888 |
bobgets(estring, edit_row[dmode]+6, 14,
|
|
Packit |
6ef888 |
edit_size[dmode], &ch);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
while ((ch=getch()) == 0); // wait for input
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
switch (ch)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
/* escape or 'q' */
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
case 0x1b:
|
|
Packit |
6ef888 |
case 0x03:
|
|
Packit |
6ef888 |
case 'q':
|
|
Packit |
6ef888 |
if (editing)
|
|
Packit |
6ef888 |
editing = FALSE;
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
Quit=TRUE;
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
/* home - return to the superblock */
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
case KEY_HOME:
|
|
Packit |
6ef888 |
if (dmode == EXTENDED_MODE) {
|
|
Packit |
6ef888 |
start_row[dmode] = end_row[dmode] = 0;
|
|
Packit |
6ef888 |
edit_row[dmode] = 0;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
else {
|
|
Packit |
6ef888 |
block = 0x10 * (4096 / sbd.bsize);
|
|
Packit |
6ef888 |
push_block(block);
|
|
Packit |
6ef888 |
offset = 0;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
/* backspace - return to the previous block on the stack */
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
case KEY_BACKSPACE:
|
|
Packit |
6ef888 |
case 0x7f:
|
|
Packit |
6ef888 |
block = pop_block();
|
|
Packit |
6ef888 |
offset = 0;
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
/* space - go down the block stack (opposite of backspace) */
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
case ' ':
|
|
Packit |
6ef888 |
blockhist++;
|
|
Packit |
6ef888 |
block = blockstack[blockhist % BLOCK_STACK_SIZE].block;
|
|
Packit |
6ef888 |
offset = 0;
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
/* arrow up */
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
case KEY_UP:
|
|
Packit |
6ef888 |
case '-':
|
|
Packit |
6ef888 |
if (dmode == EXTENDED_MODE) {
|
|
Packit |
6ef888 |
if (edit_row[dmode] > 0)
|
|
Packit |
6ef888 |
edit_row[dmode]--;
|
|
Packit |
6ef888 |
if (edit_row[dmode] < start_row[dmode])
|
|
Packit |
6ef888 |
start_row[dmode] = edit_row[dmode];
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
else {
|
|
Packit |
6ef888 |
if (edit_row[dmode] >= 0)
|
|
Packit |
6ef888 |
edit_row[dmode]--;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
/* arrow down */
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
case KEY_DOWN:
|
|
Packit |
6ef888 |
case '+':
|
|
Packit |
6ef888 |
if (dmode == EXTENDED_MODE) {
|
|
Packit |
6ef888 |
if (edit_row[dmode] + 1 < end_row[dmode]) {
|
|
Packit |
6ef888 |
if (edit_row[dmode] - start_row[dmode]
|
|
Packit |
6ef888 |
+ 1 > last_entry_onscreen[dmode])
|
|
Packit |
6ef888 |
start_row[dmode]++;
|
|
Packit |
6ef888 |
edit_row[dmode]++;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
else {
|
|
Packit |
6ef888 |
if (edit_row[dmode] < last_entry_onscreen[dmode])
|
|
Packit |
6ef888 |
edit_row[dmode]++;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
/* arrow left */
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
case KEY_LEFT:
|
|
Packit |
6ef888 |
if (dmode == HEX_MODE) {
|
|
Packit |
6ef888 |
if (edit_col[dmode] > 0)
|
|
Packit |
6ef888 |
edit_col[dmode]--;
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
edit_col[dmode] = 15;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
/* arrow right */
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
case KEY_RIGHT:
|
|
Packit |
6ef888 |
if (dmode == HEX_MODE) {
|
|
Packit |
6ef888 |
if (edit_col[dmode] < 15)
|
|
Packit |
6ef888 |
edit_col[dmode]++;
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
edit_col[dmode] = 0;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
/* m - change display mode key */
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
case 'm':
|
|
Packit |
6ef888 |
dmode = ((dmode + 1) % DMODES);
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
/* J - Jump to highlighted block number */
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
case 'j':
|
|
Packit |
6ef888 |
jump();
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
/* g - goto block */
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
case 'g':
|
|
Packit |
6ef888 |
block = goto_block();
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
/* h - help key */
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
case 'h':
|
|
Packit |
6ef888 |
print_usage();
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
/* e - change to extended mode */
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
case 'e':
|
|
Packit |
6ef888 |
dmode = EXTENDED_MODE;
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
/* b - Back one 4K block */
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
case 'b':
|
|
Packit |
6ef888 |
start_row[dmode] = end_row[dmode] = edit_row[dmode] = 0;
|
|
Packit |
6ef888 |
if (block > 0)
|
|
Packit |
6ef888 |
block--;
|
|
Packit |
6ef888 |
offset = 0;
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
/* c - Change color scheme */
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
case 'c':
|
|
Packit |
6ef888 |
color_scheme = !color_scheme;
|
|
Packit |
6ef888 |
init_colors();
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
/* page up key */
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
case 0x19: // ctrl-y for vt100
|
|
Packit |
6ef888 |
case KEY_PPAGE: // PgUp
|
|
Packit |
6ef888 |
case 0x15: // ctrl-u for vi compat.
|
|
Packit |
6ef888 |
case 0x02: // ctrl-b for less compat.
|
|
Packit |
6ef888 |
pageup();
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
/* end - Jump to the end of the list */
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
case 0x168:
|
|
Packit |
6ef888 |
if (dmode == EXTENDED_MODE) {
|
|
Packit |
6ef888 |
int ents_per_screen = dsplines /
|
|
Packit |
6ef888 |
lines_per_row[dmode];
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
edit_row[dmode] = end_row[dmode] - 1;
|
|
Packit |
6ef888 |
if ((edit_row[dmode] - ents_per_screen)+1 > 0)
|
|
Packit |
6ef888 |
start_row[dmode] = edit_row[dmode] -
|
|
Packit |
6ef888 |
ents_per_screen + 1;
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
start_row[dmode] = 0;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
/* TODO: Make end key work for other display modes. */
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
/* f - Forward one 4K block */
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
case 'f':
|
|
Packit |
6ef888 |
start_row[dmode]=end_row[dmode]=edit_row[dmode] = 0;
|
|
Packit |
6ef888 |
lines_per_row[dmode] = 1;
|
|
Packit |
6ef888 |
block++;
|
|
Packit |
6ef888 |
offset = 0;
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
/* page down key */
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
case 0x16: // ctrl-v for vt100
|
|
Packit |
6ef888 |
case KEY_NPAGE: // PgDown
|
|
Packit |
6ef888 |
case 0x04: // ctrl-d for vi compat.
|
|
Packit |
6ef888 |
pagedn();
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
/* enter key - change a value */
|
|
Packit |
6ef888 |
/* --------------------------------------------------------- */
|
|
Packit |
6ef888 |
case KEY_ENTER:
|
|
Packit |
6ef888 |
case('\n'):
|
|
Packit |
6ef888 |
case('\r'):
|
|
Packit |
6ef888 |
editing = !editing;
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
case KEY_RESIZE:
|
|
Packit |
6ef888 |
getmaxyx(stdscr, termlines, termcols);
|
|
Packit |
6ef888 |
termlines--;
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
default:
|
|
Packit |
6ef888 |
move(termlines - 1, 0);
|
|
Packit |
6ef888 |
printw("Keystroke not understood: 0x%03x",ch);
|
|
Packit |
6ef888 |
refresh();
|
|
Packit |
6ef888 |
usleep(50000);
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
} /* switch */
|
|
Packit |
6ef888 |
} /* while !Quit */
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
Erase();
|
|
Packit |
6ef888 |
refresh();
|
|
Packit |
6ef888 |
endwin();
|
|
Packit |
6ef888 |
}/* interactive_mode */
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* gfs_log_header_in - read in a gfs1-style log header */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
void gfs_log_header_in(struct gfs_log_header *head,
|
|
Packit |
6ef888 |
struct gfs2_buffer_head *lbh)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
struct gfs_log_header *str = lbh->iov.iov_base;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
gfs2_meta_header_in(&head->lh_header, lbh->b_data);
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
head->lh_flags = be32_to_cpu(str->lh_flags);
|
|
Packit |
6ef888 |
head->lh_pad = be32_to_cpu(str->lh_pad);
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
head->lh_first = be64_to_cpu(str->lh_first);
|
|
Packit |
6ef888 |
head->lh_sequence = be64_to_cpu(str->lh_sequence);
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
head->lh_tail = be64_to_cpu(str->lh_tail);
|
|
Packit |
6ef888 |
head->lh_last_dump = be64_to_cpu(str->lh_last_dump);
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
memcpy(head->lh_reserved, str->lh_reserved, 64);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* gfs_log_header_print - print a gfs1-style log header */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
void gfs_log_header_print(struct gfs_log_header *lh)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
gfs2_meta_header_print(&lh->lh_header);
|
|
Packit |
6ef888 |
pv(lh, lh_flags, "%u", "0x%.8x");
|
|
Packit |
6ef888 |
pv(lh, lh_pad, "%u", "%x");
|
|
Packit |
6ef888 |
pv((unsigned long long)lh, lh_first, "%llu", "%llx");
|
|
Packit |
6ef888 |
pv((unsigned long long)lh, lh_sequence, "%llu", "%llx");
|
|
Packit |
6ef888 |
pv((unsigned long long)lh, lh_tail, "%llu", "%llx");
|
|
Packit |
6ef888 |
pv((unsigned long long)lh, lh_last_dump, "%llu", "%llx");
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* usage - print command line usage */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
static void usage(void)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
fprintf(stderr,"\nFormat is: gfs2_edit [-c 1] [-V] [-x] [-h] [identify] [-z <0-9>] [-p structures|blocks][blocktype][blockalloc [val]][blockbits][blockrg][rgcount][rgflags][rgbitmaps][find sb|rg|rb|di|in|lf|jd|lh|ld|ea|ed|lb|13|qc][field <f>[val]] /dev/device\n\n");
|
|
Packit |
6ef888 |
fprintf(stderr,"If only the device is specified, it enters into hexedit mode.\n");
|
|
Packit |
6ef888 |
fprintf(stderr,"identify - prints out only the block type, not the details.\n");
|
|
Packit |
6ef888 |
fprintf(stderr,"printsavedmeta - prints out the saved metadata blocks from a savemeta file.\n");
|
|
Packit |
6ef888 |
fprintf(stderr,"savemeta <file_system> <file.gz> - save off your metadata for analysis and debugging.\n");
|
|
Packit |
6ef888 |
fprintf(stderr," (The intelligent way: assume bitmap is correct).\n");
|
|
Packit |
6ef888 |
fprintf(stderr,"savemetaslow - save off your metadata for analysis and debugging. The SLOW way (block by block).\n");
|
|
Packit |
6ef888 |
fprintf(stderr,"savergs - save off only the resource group information (rindex and rgs).\n");
|
|
Packit |
6ef888 |
fprintf(stderr,"restoremeta - restore metadata for debugging (DANGEROUS).\n");
|
|
Packit |
6ef888 |
fprintf(stderr,"rgcount - print how many RGs in the file system.\n");
|
|
Packit |
6ef888 |
fprintf(stderr,"rgflags rgnum [new flags] - print or modify flags for rg #rgnum (0 - X)\n");
|
|
Packit |
6ef888 |
fprintf(stderr,"rgbitmaps <rgnum> - print out the bitmaps for rgrp "
|
|
Packit |
6ef888 |
"rgnum.\n");
|
|
Packit |
6ef888 |
fprintf(stderr,"rgrepair - find and repair damaged rgrp.\n");
|
|
Packit |
6ef888 |
fprintf(stderr,"-V prints version number.\n");
|
|
Packit |
6ef888 |
fprintf(stderr,"-c 1 selects alternate color scheme 1\n");
|
|
Packit |
6ef888 |
fprintf(stderr,"-d prints details (for printing journals)\n");
|
|
Packit |
6ef888 |
fprintf(stderr,"-p prints GFS2 structures or blocks to stdout.\n");
|
|
Packit |
6ef888 |
fprintf(stderr," sb - prints the superblock.\n");
|
|
Packit |
6ef888 |
fprintf(stderr," size - prints the filesystem size.\n");
|
|
Packit |
6ef888 |
fprintf(stderr," master - prints the master directory.\n");
|
|
Packit |
6ef888 |
fprintf(stderr," root - prints the root directory.\n");
|
|
Packit |
6ef888 |
fprintf(stderr," jindex - prints the journal index directory.\n");
|
|
Packit |
6ef888 |
fprintf(stderr," journals - prints the journal status.\n");
|
|
Packit |
6ef888 |
fprintf(stderr," per_node - prints the per_node directory.\n");
|
|
Packit |
6ef888 |
fprintf(stderr," inum - prints the inum file.\n");
|
|
Packit |
6ef888 |
fprintf(stderr," statfs - prints the statfs file.\n");
|
|
Packit |
6ef888 |
fprintf(stderr," rindex - prints the rindex file.\n");
|
|
Packit |
6ef888 |
fprintf(stderr," rg X - print resource group X.\n");
|
|
Packit |
6ef888 |
fprintf(stderr," rgs - prints all the resource groups (rgs).\n");
|
|
Packit |
6ef888 |
fprintf(stderr," quota - prints the quota file.\n");
|
|
Packit |
6ef888 |
fprintf(stderr," 0x1234 - prints the specified block\n");
|
|
Packit |
6ef888 |
fprintf(stderr,"-p <block> blocktype - prints the type "
|
|
Packit |
6ef888 |
"of the specified block\n");
|
|
Packit |
6ef888 |
fprintf(stderr,"-p <block> blockrg - prints the resource group "
|
|
Packit |
6ef888 |
"block corresponding to the specified block\n");
|
|
Packit |
6ef888 |
fprintf(stderr,"-p <block> blockbits - prints the block with "
|
|
Packit |
6ef888 |
"the bitmap corresponding to the specified block\n");
|
|
Packit |
6ef888 |
fprintf(stderr,"-p <block> blockalloc [0|1|2|3] - print or change "
|
|
Packit |
6ef888 |
"the allocation type of the specified block\n");
|
|
Packit |
6ef888 |
fprintf(stderr,"-p <block> field [new_value] - prints or change the "
|
|
Packit |
6ef888 |
"structure field\n");
|
|
Packit |
6ef888 |
fprintf(stderr,"-p find sb|rg|rb|di|in|lf|jd|lh|ld|ea|ed|lb|"
|
|
Packit |
6ef888 |
"13|qc - find block of given type after block \n");
|
|
Packit |
6ef888 |
fprintf(stderr," specifies the starting block for search\n");
|
|
Packit |
6ef888 |
fprintf(stderr,"-z 1 use gzip compression level 1 for savemeta (default 9)\n");
|
|
Packit |
6ef888 |
fprintf(stderr,"-z 0 do not use compression\n");
|
|
Packit |
6ef888 |
fprintf(stderr,"-s specifies a starting block such as root, rindex, quota, inum.\n");
|
|
Packit |
6ef888 |
fprintf(stderr,"-x print in hexmode.\n");
|
|
Packit |
6ef888 |
fprintf(stderr,"-h prints this help.\n\n");
|
|
Packit |
6ef888 |
fprintf(stderr,"Examples:\n");
|
|
Packit |
6ef888 |
fprintf(stderr," To run in interactive mode:\n");
|
|
Packit |
6ef888 |
fprintf(stderr," gfs2_edit /dev/bobs_vg/lvol0\n");
|
|
Packit |
6ef888 |
fprintf(stderr," To print out the superblock and master directory:\n");
|
|
Packit |
6ef888 |
fprintf(stderr," gfs2_edit -p sb master /dev/bobs_vg/lvol0\n");
|
|
Packit |
6ef888 |
fprintf(stderr," To print out the master directory in hex:\n");
|
|
Packit |
6ef888 |
fprintf(stderr," gfs2_edit -x -p master /dev/bobs_vg/lvol0\n");
|
|
Packit |
6ef888 |
fprintf(stderr," To print out the block-type for block 0x27381:\n");
|
|
Packit |
6ef888 |
fprintf(stderr," gfs2_edit identify -p 0x27381 /dev/bobs_vg/lvol0\n");
|
|
Packit |
6ef888 |
fprintf(stderr," To print out the fourth Resource Group. (the first R is #0)\n");
|
|
Packit |
6ef888 |
fprintf(stderr," gfs2_edit -p rg 3 /dev/sdb1\n");
|
|
Packit |
6ef888 |
fprintf(stderr," To print out the metadata type of block 1234\n");
|
|
Packit |
6ef888 |
fprintf(stderr," gfs2_edit -p 1234 blocktype /dev/roth_vg/roth_lb\n");
|
|
Packit |
6ef888 |
fprintf(stderr," To print out the allocation type of block 2345\n");
|
|
Packit |
6ef888 |
fprintf(stderr," gfs2_edit -p 2345 blockalloc /dev/vg/lv\n");
|
|
Packit |
6ef888 |
fprintf(stderr," To change the allocation type of block 2345 to a 'free block'\n");
|
|
Packit |
6ef888 |
fprintf(stderr," gfs2_edit -p 2345 blockalloc 0 /dev/vg/lv\n");
|
|
Packit |
6ef888 |
fprintf(stderr," To print out the file size of the dinode at block 0x118\n");
|
|
Packit |
6ef888 |
fprintf(stderr," gfs2_edit -p 0x118 field di_size /dev/roth_vg/roth_lb\n");
|
|
Packit |
6ef888 |
fprintf(stderr," To find any dinode higher than the quota file dinode:\n");
|
|
Packit |
6ef888 |
fprintf(stderr," gfs2_edit -p quota find di /dev/x/y\n");
|
|
Packit |
6ef888 |
fprintf(stderr," To set the Resource Group flags for rg #7 to 3.\n");
|
|
Packit |
6ef888 |
fprintf(stderr," gfs2_edit rgflags 7 3 /dev/sdc2\n");
|
|
Packit |
6ef888 |
fprintf(stderr," To save off all metadata for /dev/vg/lv:\n");
|
|
Packit |
6ef888 |
fprintf(stderr," gfs2_edit savemeta /dev/vg/lv /tmp/metasave.gz\n");
|
|
Packit |
6ef888 |
}/* usage */
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/**
|
|
Packit |
6ef888 |
* getgziplevel - Process the -z parameter to savemeta operations
|
|
Packit |
6ef888 |
* argv - argv
|
|
Packit |
6ef888 |
* i - a pointer to the argv index at which to begin processing
|
|
Packit |
6ef888 |
* The index pointed to by i will be incremented past the -z option if found
|
|
Packit |
6ef888 |
*/
|
|
Packit |
6ef888 |
static void getgziplevel(char *argv[], int *i)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
char *opt, *arg;
|
|
Packit |
6ef888 |
char *endptr;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
arg = argv[1 + *i];
|
|
Packit |
6ef888 |
if (strncmp(arg, "-z", 2)) {
|
|
Packit |
6ef888 |
return;
|
|
Packit |
6ef888 |
} else if (arg[2] != '\0') {
|
|
Packit |
6ef888 |
opt = &arg[2];
|
|
Packit |
6ef888 |
} else {
|
|
Packit |
6ef888 |
(*i)++;
|
|
Packit |
6ef888 |
opt = argv[1 + *i];
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
errno = 0;
|
|
Packit |
6ef888 |
gziplevel = strtol(opt, &endptr, 10);
|
|
Packit |
6ef888 |
if (errno || endptr == opt || gziplevel < 0 || gziplevel > 9) {
|
|
Packit |
6ef888 |
fprintf(stderr, "Compression level out of range: %s\n", opt);
|
|
Packit |
6ef888 |
exit(-1);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
(*i)++;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
static int count_dinode_blks(struct rgrp_tree *rgd, int bitmap,
|
|
Packit |
6ef888 |
struct gfs2_buffer_head *rbh)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
struct gfs2_buffer_head *tbh;
|
|
Packit |
6ef888 |
uint64_t b;
|
|
Packit |
6ef888 |
int dinodes = 0;
|
|
Packit |
6ef888 |
char *byte, cur_state, new_state;
|
|
Packit |
6ef888 |
int bit, off;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (bitmap)
|
|
Packit |
6ef888 |
off = sizeof(struct gfs2_meta_header);
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
off = sizeof(struct gfs2_rgrp);
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
for (b = 0; b < rgd->bits[bitmap].bi_len << GFS2_BIT_SIZE; b++) {
|
|
Packit |
6ef888 |
tbh = bread(&sbd, rgd->ri.ri_data0 +
|
|
Packit |
6ef888 |
rgd->bits[bitmap].bi_start + b);
|
|
Packit |
6ef888 |
byte = rbh->b_data + off + (b / GFS2_NBBY);
|
|
Packit |
6ef888 |
bit = (b % GFS2_NBBY) * GFS2_BIT_SIZE;
|
|
Packit |
6ef888 |
if (gfs2_check_meta(tbh, GFS2_METATYPE_DI) == 0) {
|
|
Packit |
6ef888 |
dinodes++;
|
|
Packit |
6ef888 |
new_state = GFS2_BLKST_DINODE;
|
|
Packit |
6ef888 |
} else {
|
|
Packit |
6ef888 |
new_state = GFS2_BLKST_USED;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
cur_state = (*byte >> bit) & GFS2_BIT_MASK;
|
|
Packit |
6ef888 |
*byte ^= cur_state << bit;
|
|
Packit |
6ef888 |
*byte |= new_state << bit;
|
|
Packit |
6ef888 |
brelse(tbh);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
bmodified(rbh);
|
|
Packit |
6ef888 |
return dinodes;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
static int count_dinode_bits(struct gfs2_buffer_head *rbh)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
uint64_t blk;
|
|
Packit |
6ef888 |
struct gfs2_meta_header *mh = (struct gfs2_meta_header *)rbh->b_data;
|
|
Packit |
6ef888 |
char *byte;
|
|
Packit |
6ef888 |
int bit;
|
|
Packit |
6ef888 |
int dinodes = 0;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (be32_to_cpu(mh->mh_type) == GFS2_METATYPE_RG)
|
|
Packit |
6ef888 |
blk = sizeof(struct gfs2_rgrp);
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
blk = sizeof(struct gfs2_meta_header);
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
for (; blk < sbd.bsize; blk++) {
|
|
Packit |
6ef888 |
byte = rbh->b_data + (blk / GFS2_NBBY);
|
|
Packit |
6ef888 |
bit = (blk % GFS2_NBBY) * GFS2_BIT_SIZE;
|
|
Packit |
6ef888 |
if (((*byte >> bit) & GFS2_BIT_MASK) == GFS2_BLKST_DINODE)
|
|
Packit |
6ef888 |
dinodes++;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
return dinodes;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
static void rg_repair(void)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
struct gfs2_buffer_head *rbh;
|
|
Packit |
6ef888 |
struct rgrp_tree *rgd;
|
|
Packit |
6ef888 |
struct osi_node *n;
|
|
Packit |
6ef888 |
int b;
|
|
Packit |
6ef888 |
int rgs_fixed = 0;
|
|
Packit |
6ef888 |
int dinodes_found = 0, dinodes_total = 0;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* Walk through the resource groups saving everything within */
|
|
Packit |
6ef888 |
for (n = osi_first(&sbd.rgtree); n; n = osi_next(n)) {
|
|
Packit |
6ef888 |
rgd = (struct rgrp_tree *)n;
|
|
Packit |
6ef888 |
if (gfs2_rgrp_read(&sbd, rgd) == 0) { /* was read in okay */
|
|
Packit |
6ef888 |
gfs2_rgrp_relse(rgd);
|
|
Packit |
6ef888 |
continue; /* ignore it */
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
/* If we get here, it's because we have an rgrp in the rindex
|
|
Packit |
6ef888 |
file that can't be read in. So attempt to repair it.
|
|
Packit |
6ef888 |
If we find a damaged rgrp or bitmap, fix the metadata.
|
|
Packit |
6ef888 |
Then scan all its blocks: if we find a dinode, set the
|
|
Packit |
6ef888 |
repaired bitmap to GFS2_BLKST_DINODE. Set all others to
|
|
Packit |
6ef888 |
GFS2_BLKST_USED so fsck can sort it out. If we set them
|
|
Packit |
6ef888 |
to FREE, fsck would just nuke it all. */
|
|
Packit |
6ef888 |
printf("Resource group at block %llu (0x%llx) appears to be "
|
|
Packit |
6ef888 |
"damaged. Attempting to fix it (in reverse order).\n",
|
|
Packit |
6ef888 |
(unsigned long long)rgd->ri.ri_addr,
|
|
Packit |
6ef888 |
(unsigned long long)rgd->ri.ri_addr);
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
for (b = rgd->ri.ri_length - 1; b >= 0; b--) {
|
|
Packit |
6ef888 |
int mtype = (b ? GFS2_METATYPE_RB : GFS2_METATYPE_RG);
|
|
Packit |
6ef888 |
struct gfs2_meta_header *mh;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
printf("Bitmap #%d:", b);
|
|
Packit |
6ef888 |
rbh = bread(&sbd, rgd->ri.ri_addr + b);
|
|
Packit |
6ef888 |
if (gfs2_check_meta(rbh, mtype)) { /* wrong type */
|
|
Packit |
6ef888 |
printf("Damaged. Repairing...");
|
|
Packit |
6ef888 |
/* Fix the meta header */
|
|
Packit |
6ef888 |
memset(rbh->b_data, 0, sbd.bsize);
|
|
Packit |
6ef888 |
mh = (struct gfs2_meta_header *)rbh->b_data;
|
|
Packit |
6ef888 |
mh->mh_magic = cpu_to_be32(GFS2_MAGIC);
|
|
Packit |
6ef888 |
mh->mh_type = cpu_to_be32(mtype);
|
|
Packit |
6ef888 |
if (b)
|
|
Packit |
6ef888 |
mh->mh_format =
|
|
Packit |
6ef888 |
cpu_to_be32(GFS2_FORMAT_RB);
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
mh->mh_format =
|
|
Packit |
6ef888 |
cpu_to_be32(GFS2_FORMAT_RG);
|
|
Packit |
6ef888 |
bmodified(rbh);
|
|
Packit |
6ef888 |
/* Count the dinode blocks */
|
|
Packit |
6ef888 |
dinodes_found = count_dinode_blks(rgd, b, rbh);
|
|
Packit |
6ef888 |
} else { /* bitmap info is okay: tally it. */
|
|
Packit |
6ef888 |
printf("Undamaged. Analyzing...");
|
|
Packit |
6ef888 |
dinodes_found = count_dinode_bits(rbh);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
printf("Dinodes found: %d\n", dinodes_found);
|
|
Packit |
6ef888 |
dinodes_total += dinodes_found;
|
|
Packit |
6ef888 |
if (b == 0) { /* rgrp itself was damaged */
|
|
Packit |
6ef888 |
rgd->rg.rg_dinodes = dinodes_total;
|
|
Packit |
6ef888 |
rgd->rg.rg_free = 0;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
brelse(rbh);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
rgs_fixed++;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
if (rgs_fixed)
|
|
Packit |
6ef888 |
printf("%d resource groups fixed.\n"
|
|
Packit |
6ef888 |
"You should run fsck.gfs2 to reconcile the bitmaps.\n",
|
|
Packit |
6ef888 |
rgs_fixed);
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
printf("All resource groups are okay. No repairs needed.\n");
|
|
Packit |
6ef888 |
exit(0);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* parameterpass1 - pre-processing for command-line parameters */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
static void parameterpass1(int argc, char *argv[], int i)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
if (!strcasecmp(argv[i], "-V")) {
|
|
Packit |
6ef888 |
printf("%s version %s (built %s %s)\n",
|
|
Packit |
6ef888 |
argv[0], VERSION, __DATE__, __TIME__);
|
|
Packit |
6ef888 |
printf("%s\n", REDHAT_COPYRIGHT);
|
|
Packit |
6ef888 |
exit(0);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
else if (!strcasecmp(argv[i], "-h") ||
|
|
Packit |
6ef888 |
!strcasecmp(argv[i], "-help") ||
|
|
Packit |
6ef888 |
!strcasecmp(argv[i], "-usage")) {
|
|
Packit |
6ef888 |
usage();
|
|
Packit |
6ef888 |
exit(0);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
else if (!strcasecmp(argv[i], "-c")) {
|
|
Packit |
6ef888 |
i++;
|
|
Packit |
6ef888 |
color_scheme = atoi(argv[i]);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
else if (!strcasecmp(argv[i], "-p") ||
|
|
Packit |
6ef888 |
!strcasecmp(argv[i], "-print")) {
|
|
Packit |
6ef888 |
termlines = 0; /* initial value--we'll figure
|
|
Packit |
6ef888 |
it out later */
|
|
Packit |
6ef888 |
dmode = GFS2_MODE;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
else if (!strcasecmp(argv[i], "-d") ||
|
|
Packit |
6ef888 |
!strcasecmp(argv[i], "-details"))
|
|
Packit |
6ef888 |
details = 1;
|
|
Packit |
6ef888 |
else if (!strcasecmp(argv[i], "savemeta"))
|
|
Packit |
6ef888 |
termlines = 0;
|
|
Packit |
6ef888 |
else if (!strcasecmp(argv[i], "savemetaslow"))
|
|
Packit |
6ef888 |
termlines = 0;
|
|
Packit |
6ef888 |
else if (!strcasecmp(argv[i], "savergs"))
|
|
Packit |
6ef888 |
termlines = 0;
|
|
Packit |
6ef888 |
else if (!strcasecmp(argv[i], "printsavedmeta")) {
|
|
Packit |
6ef888 |
if (dmode == INIT_MODE)
|
|
Packit |
6ef888 |
dmode = GFS2_MODE;
|
|
Packit |
6ef888 |
restoremeta(argv[i+1], argv[i+2], TRUE);
|
|
Packit |
6ef888 |
} else if (!strcasecmp(argv[i], "restoremeta")) {
|
|
Packit |
6ef888 |
if (dmode == INIT_MODE)
|
|
Packit |
6ef888 |
dmode = HEX_MODE; /* hopefully not used */
|
|
Packit |
6ef888 |
restoremeta(argv[i+1], argv[i+2], FALSE);
|
|
Packit |
6ef888 |
} else if (!strcmp(argv[i], "rgcount"))
|
|
Packit |
6ef888 |
termlines = 0;
|
|
Packit |
6ef888 |
else if (!strcmp(argv[i], "rgflags"))
|
|
Packit |
6ef888 |
termlines = 0;
|
|
Packit |
6ef888 |
else if (!strcmp(argv[i], "rgrepair"))
|
|
Packit |
6ef888 |
termlines = 0;
|
|
Packit |
6ef888 |
else if (!strcmp(argv[i], "rg"))
|
|
Packit |
6ef888 |
termlines = 0;
|
|
Packit |
6ef888 |
else if (!strcasecmp(argv[i], "-x"))
|
|
Packit |
6ef888 |
dmode = HEX_MODE;
|
|
Packit |
6ef888 |
else if (device == NULL && strchr(argv[i],'/')) {
|
|
Packit |
6ef888 |
device = argv[i];
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
/* process_parameters - process commandline parameters */
|
|
Packit |
6ef888 |
/* pass - we make two passes through the parameters; the first pass gathers */
|
|
Packit |
6ef888 |
/* normals parameters, device name, etc. The second pass is for */
|
|
Packit |
6ef888 |
/* figuring out what structures to print out. */
|
|
Packit |
6ef888 |
/* ------------------------------------------------------------------------ */
|
|
Packit |
6ef888 |
static void process_parameters(int argc, char *argv[], int pass)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
int i;
|
|
Packit |
6ef888 |
uint64_t keyword_blk;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (argc < 2) {
|
|
Packit |
6ef888 |
usage();
|
|
Packit |
6ef888 |
die("no device specified\n");
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
for (i = 1; i < argc; i++) {
|
|
Packit |
6ef888 |
if (!pass) { /* first pass */
|
|
Packit |
6ef888 |
parameterpass1(argc, argv, i);
|
|
Packit |
6ef888 |
continue;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
/* second pass */
|
|
Packit |
6ef888 |
if (!strcasecmp(argv[i], "-s")) {
|
|
Packit |
6ef888 |
i++;
|
|
Packit |
6ef888 |
if (i >= argc - 1) {
|
|
Packit |
6ef888 |
printf("Error: starting block not specified "
|
|
Packit |
6ef888 |
"with -s.\n");
|
|
Packit |
6ef888 |
printf("%s -s [starting block | keyword] "
|
|
Packit |
6ef888 |
"<device>\n", argv[0]);
|
|
Packit |
6ef888 |
printf("For example: %s -s \"rg 3\" "
|
|
Packit |
6ef888 |
"/dev/exxon_vg/exxon_lv\n", argv[0]);
|
|
Packit |
6ef888 |
exit(EXIT_FAILURE);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
starting_blk = check_keywords(argv[i]);
|
|
Packit |
6ef888 |
continue;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
if (termlines || strchr(argv[i],'/')) /* if print or slash */
|
|
Packit |
6ef888 |
continue;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (!strncmp(argv[i], "journal", 7) && isdigit(argv[i][7]) &&
|
|
Packit |
6ef888 |
strcmp(argv[i+1], "field")) {
|
|
Packit |
6ef888 |
int blk = 0;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (i < argc - 1 && isdigit(argv[i + 1][0])) {
|
|
Packit |
6ef888 |
if (argv[i + 1][0]=='0' && argv[i + 1][1]=='x')
|
|
Packit |
6ef888 |
sscanf(argv[i + 1], "%x", &blk);
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
blk = atoi(argv[i + 1]);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
dump_journal(argv[i], blk);
|
|
Packit |
6ef888 |
continue;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
keyword_blk = check_keywords(argv[i]);
|
|
Packit |
6ef888 |
if (keyword_blk)
|
|
Packit |
6ef888 |
push_block(keyword_blk);
|
|
Packit |
6ef888 |
else if (!strcasecmp(argv[i], "-x"))
|
|
Packit |
6ef888 |
dmode = HEX_MODE;
|
|
Packit |
6ef888 |
else if (argv[i][0] == '-') /* if it starts with a dash */
|
|
Packit |
6ef888 |
; /* ignore it--meant for pass == 0 */
|
|
Packit |
6ef888 |
else if (!strcmp(argv[i], "identify"))
|
|
Packit |
6ef888 |
identify = TRUE;
|
|
Packit |
6ef888 |
else if (!strcmp(argv[i], "size")) {
|
|
Packit |
6ef888 |
printf("Device size: %llu (0x%llx)\n",
|
|
Packit |
6ef888 |
(unsigned long long)max_block,
|
|
Packit |
6ef888 |
(unsigned long long)max_block);
|
|
Packit |
6ef888 |
exit(EXIT_SUCCESS);
|
|
Packit |
6ef888 |
} else if (!strcmp(argv[i], "rgcount"))
|
|
Packit |
6ef888 |
rgcount();
|
|
Packit |
6ef888 |
else if (!strcmp(argv[i], "field")) {
|
|
Packit |
6ef888 |
i++;
|
|
Packit |
6ef888 |
if (i >= argc - 1) {
|
|
Packit |
6ef888 |
printf("Error: field not specified.\n");
|
|
Packit |
6ef888 |
printf("Format is: %s -p <block> field "
|
|
Packit |
6ef888 |
"<field> [newvalue]\n", argv[0]);
|
|
Packit |
6ef888 |
gfs2_rgrp_free(&sbd.rgtree);
|
|
Packit |
6ef888 |
exit(EXIT_FAILURE);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
process_field(argv[i], argv[i + 1]);
|
|
Packit |
6ef888 |
} else if (!strcmp(argv[i], "blocktype")) {
|
|
Packit |
6ef888 |
find_print_block_type();
|
|
Packit |
6ef888 |
} else if (!strcmp(argv[i], "blockrg")) {
|
|
Packit |
6ef888 |
find_print_block_rg(0);
|
|
Packit |
6ef888 |
} else if (!strcmp(argv[i], "blockbits")) {
|
|
Packit |
6ef888 |
find_print_block_rg(1);
|
|
Packit |
6ef888 |
} else if (!strcmp(argv[i], "blockalloc")) {
|
|
Packit |
6ef888 |
if (isdigit(argv[i + 1][0])) {
|
|
Packit |
6ef888 |
int newval;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (argv[i + 1][0]=='0' && argv[i + 1][1]=='x')
|
|
Packit |
6ef888 |
sscanf(argv[i + 1], "%x", &newval);
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
newval = (uint64_t)atoi(argv[i + 1]);
|
|
Packit |
6ef888 |
find_change_block_alloc(&newval);
|
|
Packit |
6ef888 |
} else {
|
|
Packit |
6ef888 |
find_change_block_alloc(NULL);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
} else if (!strcmp(argv[i], "find")) {
|
|
Packit |
6ef888 |
find_metablockoftype(argv[i + 1], 1);
|
|
Packit |
6ef888 |
} else if (!strcmp(argv[i], "rgflags")) {
|
|
Packit |
6ef888 |
int rg, set = FALSE;
|
|
Packit |
6ef888 |
uint32_t new_flags = 0;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
i++;
|
|
Packit |
6ef888 |
if (i >= argc - 1) {
|
|
Packit |
6ef888 |
printf("Error: rg # not specified.\n");
|
|
Packit |
6ef888 |
printf("Format is: %s rgflags rgnum"
|
|
Packit |
6ef888 |
"[newvalue]\n", argv[0]);
|
|
Packit |
6ef888 |
gfs2_rgrp_free(&sbd.rgtree);
|
|
Packit |
6ef888 |
exit(EXIT_FAILURE);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
if (argv[i][0]=='0' && argv[i][1]=='x')
|
|
Packit |
6ef888 |
sscanf(argv[i], "%"SCNx32, &rg;;
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
rg = atoi(argv[i]);
|
|
Packit |
6ef888 |
i++;
|
|
Packit |
6ef888 |
if (i < argc - 1 &&
|
|
Packit |
6ef888 |
isdigit(argv[i][0])) {
|
|
Packit |
6ef888 |
set = TRUE;
|
|
Packit |
6ef888 |
if (argv[i][0]=='0' && argv[i][1]=='x')
|
|
Packit |
6ef888 |
sscanf(argv[i], "%"SCNx32, &new_flags);
|
|
Packit |
6ef888 |
else
|
|
Packit |
6ef888 |
new_flags = atoi(argv[i]);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
set_rgrp_flags(rg, new_flags, set, FALSE);
|
|
Packit |
6ef888 |
gfs2_rgrp_free(&sbd.rgtree);
|
|
Packit |
6ef888 |
exit(EXIT_SUCCESS);
|
|
Packit |
6ef888 |
} else if (!strcmp(argv[i], "rg")) {
|
|
Packit |
6ef888 |
int rg;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
i++;
|
|
Packit |
6ef888 |
if (i >= argc - 1) {
|
|
Packit |
6ef888 |
printf("Error: rg # not specified.\n");
|
|
Packit |
6ef888 |
printf("Format is: %s rg rgnum\n", argv[0]);
|
|
Packit |
6ef888 |
gfs2_rgrp_free(&sbd.rgtree);
|
|
Packit |
6ef888 |
exit(EXIT_FAILURE);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
rg = atoi(argv[i]);
|
|
Packit |
6ef888 |
if (!strcasecmp(argv[i + 1], "find")) {
|
|
Packit |
6ef888 |
temp_blk = get_rg_addr(rg);
|
|
Packit |
6ef888 |
push_block(temp_blk);
|
|
Packit |
6ef888 |
} else {
|
|
Packit |
6ef888 |
set_rgrp_flags(rg, 0, FALSE, TRUE);
|
|
Packit |
6ef888 |
gfs2_rgrp_free(&sbd.rgtree);
|
|
Packit |
6ef888 |
exit(EXIT_SUCCESS);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
} else if (!strcmp(argv[i], "rgbitmaps")) {
|
|
Packit |
6ef888 |
int rg, bmap;
|
|
Packit |
6ef888 |
uint64_t rgblk;
|
|
Packit |
6ef888 |
struct rgrp_tree *rgd;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
i++;
|
|
Packit |
6ef888 |
if (i >= argc - 1) {
|
|
Packit |
6ef888 |
printf("Error: rg # not specified.\n");
|
|
Packit |
6ef888 |
printf("Format is: %s rgbitmaps rgnum\n",
|
|
Packit |
6ef888 |
argv[0]);
|
|
Packit |
6ef888 |
gfs2_rgrp_free(&sbd.rgtree);
|
|
Packit |
6ef888 |
exit(EXIT_FAILURE);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
rg = atoi(argv[i]);
|
|
Packit |
6ef888 |
rgblk = get_rg_addr(rg);
|
|
Packit |
6ef888 |
rgd = gfs2_blk2rgrpd(&sbd, rgblk);
|
|
Packit |
6ef888 |
if (rgd == NULL) {
|
|
Packit |
6ef888 |
printf("Error: rg # is invalid.\n");
|
|
Packit |
6ef888 |
gfs2_rgrp_free(&sbd.rgtree);
|
|
Packit |
6ef888 |
exit(EXIT_FAILURE);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
for (bmap = 0; bmap < rgd->ri.ri_length; bmap++)
|
|
Packit |
6ef888 |
push_block(rgblk + bmap);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
else if (!strcmp(argv[i], "rgrepair"))
|
|
Packit |
6ef888 |
rg_repair();
|
|
Packit |
6ef888 |
else if (!strcasecmp(argv[i], "savemeta")) {
|
|
Packit |
6ef888 |
getgziplevel(argv, &i);
|
|
Packit |
6ef888 |
savemeta(argv[i+2], 0, gziplevel);
|
|
Packit |
6ef888 |
} else if (!strcasecmp(argv[i], "savemetaslow")) {
|
|
Packit |
6ef888 |
getgziplevel(argv, &i);
|
|
Packit |
6ef888 |
savemeta(argv[i+2], 1, gziplevel);
|
|
Packit |
6ef888 |
} else if (!strcasecmp(argv[i], "savergs")) {
|
|
Packit |
6ef888 |
getgziplevel(argv, &i);
|
|
Packit |
6ef888 |
savemeta(argv[i+2], 2, gziplevel);
|
|
Packit |
6ef888 |
} else if (isdigit(argv[i][0])) { /* decimal addr */
|
|
Packit |
6ef888 |
sscanf(argv[i], "%"SCNd64, &temp_blk);
|
|
Packit |
6ef888 |
push_block(temp_blk);
|
|
Packit |
6ef888 |
} else {
|
|
Packit |
6ef888 |
fprintf(stderr,"I don't know what '%s' means.\n",
|
|
Packit |
6ef888 |
argv[i]);
|
|
Packit |
6ef888 |
usage();
|
|
Packit |
6ef888 |
exit(EXIT_FAILURE);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
} /* for */
|
|
Packit |
6ef888 |
}/* process_parameters */
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
int main(int argc, char *argv[])
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
int i, j, fd;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
indirect = malloc(sizeof(struct iinfo));
|
|
Packit |
6ef888 |
if (!indirect)
|
|
Packit |
6ef888 |
die("Out of memory.");
|
|
Packit |
6ef888 |
memset(indirect, 0, sizeof(struct iinfo));
|
|
Packit |
6ef888 |
memset(start_row, 0, sizeof(start_row));
|
|
Packit |
6ef888 |
memset(lines_per_row, 0, sizeof(lines_per_row));
|
|
Packit |
6ef888 |
memset(end_row, 0, sizeof(end_row));
|
|
Packit |
6ef888 |
memset(edit_row, 0, sizeof(edit_row));
|
|
Packit |
6ef888 |
memset(edit_col, 0, sizeof(edit_col));
|
|
Packit |
6ef888 |
memset(edit_size, 0, sizeof(edit_size));
|
|
Packit |
6ef888 |
memset(last_entry_onscreen, 0, sizeof(last_entry_onscreen));
|
|
Packit |
6ef888 |
dmode = INIT_MODE;
|
|
Packit |
6ef888 |
sbd.bsize = 4096;
|
|
Packit |
6ef888 |
block = starting_blk = 0x10;
|
|
Packit |
6ef888 |
for (i = 0; i < BLOCK_STACK_SIZE; i++) {
|
|
Packit |
6ef888 |
blockstack[i].dmode = HEX_MODE;
|
|
Packit |
6ef888 |
blockstack[i].block = block;
|
|
Packit |
6ef888 |
for (j = 0; j < DMODES; j++) {
|
|
Packit |
6ef888 |
blockstack[i].start_row[j] = 0;
|
|
Packit |
6ef888 |
blockstack[i].end_row[j] = 0;
|
|
Packit |
6ef888 |
blockstack[i].edit_row[j] = 0;
|
|
Packit |
6ef888 |
blockstack[i].edit_col[j] = 0;
|
|
Packit |
6ef888 |
blockstack[i].lines_per_row[j] = 0;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
edit_row[GFS2_MODE] = 10; /* Start off at root inode
|
|
Packit |
6ef888 |
pointer in superblock */
|
|
Packit |
6ef888 |
termlines = 30; /* assume interactive mode until we find -p */
|
|
Packit |
6ef888 |
process_parameters(argc, argv, 0);
|
|
Packit |
6ef888 |
if (dmode == INIT_MODE)
|
|
Packit |
6ef888 |
dmode = HEX_MODE;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
fd = open(device, O_RDWR);
|
|
Packit |
6ef888 |
if (fd < 0)
|
|
Packit |
6ef888 |
die("can't open %s: %s\n", device, strerror(errno));
|
|
Packit |
6ef888 |
max_block = lseek(fd, 0, SEEK_END) / sbd.bsize;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
read_superblock(fd);
|
|
Packit |
6ef888 |
if (read_rindex())
|
|
Packit |
6ef888 |
exit(-1);
|
|
Packit |
6ef888 |
max_block = lseek(fd, 0, SEEK_END) / sbd.bsize;
|
|
Packit |
6ef888 |
if (sbd.gfs1)
|
|
Packit |
6ef888 |
edit_row[GFS2_MODE]++;
|
|
Packit |
6ef888 |
else if (read_master_dir() != 0)
|
|
Packit |
6ef888 |
exit(-1);
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
process_parameters(argc, argv, 1); /* get what to print from cmdline */
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
block = blockstack[0].block = starting_blk * (4096 / sbd.bsize);
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (termlines)
|
|
Packit |
6ef888 |
interactive_mode();
|
|
Packit |
6ef888 |
else { /* print all the structures requested */
|
|
Packit |
6ef888 |
i = 0;
|
|
Packit |
6ef888 |
while (blockhist > 0) {
|
|
Packit |
6ef888 |
block = blockstack[i + 1].block;
|
|
Packit |
6ef888 |
if (!block)
|
|
Packit |
6ef888 |
break;
|
|
Packit |
6ef888 |
display(identify, 0, 0, 0);
|
|
Packit |
6ef888 |
if (!identify) {
|
|
Packit |
6ef888 |
display_extended();
|
|
Packit |
6ef888 |
printf("-------------------------------------" \
|
|
Packit |
6ef888 |
"-----------------");
|
|
Packit |
6ef888 |
eol(0);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
block = pop_block();
|
|
Packit |
6ef888 |
i++;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
close(fd);
|
|
Packit |
6ef888 |
if (indirect)
|
|
Packit |
6ef888 |
free(indirect);
|
|
Packit |
6ef888 |
gfs2_rgrp_free(&sbd.rgtree);
|
|
Packit |
6ef888 |
exit(EXIT_SUCCESS);
|
|
Packit |
6ef888 |
}
|