Blame gfs2/edit/extended.c

Packit Service 360c39
#include "clusterautoconfig.h"
Packit Service 360c39
Packit Service 360c39
#include <stdio.h>
Packit Service 360c39
#include <stdlib.h>
Packit Service 360c39
#include <ctype.h>
Packit Service 360c39
#include <string.h>
Packit Service 360c39
#include <inttypes.h>
Packit Service 360c39
#include <sys/types.h>
Packit Service 360c39
#include <linux/types.h>
Packit Service 360c39
#include <sys/stat.h>
Packit Service 360c39
#include <fcntl.h>
Packit Service 360c39
#include <unistd.h>
Packit Service 360c39
#include <errno.h>
Packit Service 360c39
#include <curses.h>
Packit Service 360c39
#include <term.h>
Packit Service 360c39
#include <time.h>
Packit Service 360c39
#include <signal.h>
Packit Service 360c39
#include <sys/ioctl.h>
Packit Service 360c39
#include <sys/mount.h>
Packit Service 360c39
#include <dirent.h>
Packit Service 360c39
Packit Service 360c39
#include <linux/gfs2_ondisk.h>
Packit Service 360c39
#include "copyright.cf"
Packit Service 360c39
Packit Service 360c39
#include "hexedit.h"
Packit Service 360c39
#include "libgfs2.h"
Packit Service 360c39
#include "extended.h"
Packit Service 360c39
#include "gfs2hex.h"
Packit Service 360c39
Packit Service 360c39
extern uint64_t block;
Packit Service 360c39
Packit Service 360c39
static void print_block_details(struct iinfo *ind, int level, int cur_height,
Packit Service 360c39
				int pndx, uint64_t file_offset);
Packit Service 360c39
Packit Service 360c39
static int get_height(void)
Packit Service 360c39
{
Packit Service 360c39
	int cur_height = 0, i;
Packit Service 360c39
Packit Service 360c39
	if (gfs2_struct_type != GFS2_METATYPE_DI) {
Packit Service 360c39
		for (i = 0; i <= blockhist && i < 5; i++) {
Packit Service 360c39
			if (blockstack[(blockhist - i) %
Packit Service 360c39
				       BLOCK_STACK_SIZE].gfs2_struct_type ==
Packit Service 360c39
			    GFS2_METATYPE_DI)
Packit Service 360c39
				break;
Packit Service 360c39
			cur_height++;
Packit Service 360c39
		}
Packit Service 360c39
	}
Packit Service 360c39
	return cur_height;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static int _do_indirect_extended(char *diebuf, struct iinfo *iinf, int hgt)
Packit Service 360c39
{
Packit Service 360c39
	unsigned int x, y;
Packit Service 360c39
	off_t headoff;
Packit Service 360c39
	uint64_t p;
Packit Service 360c39
	int i_blocks;
Packit Service 360c39
Packit Service 360c39
	i_blocks = 0;
Packit Service 360c39
	for (x = 0; x < 512; x++) {
Packit Service 360c39
		iinf->ii[x].is_dir = 0;
Packit Service 360c39
		iinf->ii[x].height = 0;
Packit Service 360c39
		iinf->ii[x].block = 0;
Packit Service 360c39
		iinf->ii[x].dirents = 0;
Packit Service 360c39
		memset(&iinf->ii[x].dirent, 0, sizeof(struct gfs2_dirents));
Packit Service 360c39
	}
Packit Service 360c39
	headoff = sbd.gfs1 ? sizeof(struct gfs_indirect) : sizeof(struct gfs2_meta_header);
Packit Service 360c39
	for (x = headoff, y = 0; x < sbd.bsize; x += sizeof(uint64_t), y++) {
Packit Service 360c39
		p = be64_to_cpu(*(uint64_t *)(diebuf + x));
Packit Service 360c39
		if (p) {
Packit Service 360c39
			iinf->ii[i_blocks].block = p;
Packit Service 360c39
			iinf->ii[i_blocks].mp.mp_list[hgt] = i_blocks;
Packit Service 360c39
			iinf->ii[i_blocks].is_dir = FALSE;
Packit Service 360c39
			iinf->ii[i_blocks].ptroff = (x - headoff) / sizeof(uint64_t);
Packit Service 360c39
			i_blocks++;
Packit Service 360c39
		}
Packit Service 360c39
	}
Packit Service 360c39
	return i_blocks;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
int do_indirect_extended(char *diebuf, struct iinfo *iinf)
Packit Service 360c39
{
Packit Service 360c39
	return _do_indirect_extended(diebuf, iinf, get_height());
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* dinode_valid - check if we have a dinode in recent history               */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
static int dinode_valid(void)
Packit Service 360c39
{
Packit Service 360c39
	int i;
Packit Service 360c39
Packit Service 360c39
	if (gfs2_struct_type == GFS2_METATYPE_DI)
Packit Service 360c39
		return 1;
Packit Service 360c39
	for (i = 0; i <= blockhist && i < 5; i++) {
Packit Service 360c39
		if (blockstack[(blockhist - i) %
Packit Service 360c39
			       BLOCK_STACK_SIZE].gfs2_struct_type ==
Packit Service 360c39
		    GFS2_METATYPE_DI)
Packit Service 360c39
			return 1;
Packit Service 360c39
	}
Packit Service 360c39
	return 0;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static uint64_t metapath_to_lblock(struct metapath *mp, int hgt)
Packit Service 360c39
{
Packit Service 360c39
	int h;
Packit Service 360c39
	uint64_t lblock = 0;
Packit Service 360c39
	uint64_t factor[GFS2_MAX_META_HEIGHT];
Packit Service 360c39
Packit Service 360c39
	if (di.di_height < 2)
Packit Service 360c39
		return mp->mp_list[0];
Packit Service 360c39
	/* figure out multiplication factors for each height */
Packit Service 360c39
	memset(&factor, 0, sizeof(factor));
Packit Service 360c39
	factor[di.di_height - 1] = 1ull;
Packit Service 360c39
	for (h = di.di_height - 2; h >= 0; h--)
Packit Service 360c39
		factor[h] = factor[h + 1] * sbd.sd_inptrs;
Packit Service 360c39
	for (h = 0; h <= hgt; h++)
Packit Service 360c39
		lblock += (mp->mp_list[h] * factor[h]);
Packit Service 360c39
	return lblock;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static int display_indirect(struct iinfo *ind, int indblocks, int level,
Packit Service 360c39
			    uint64_t startoff)
Packit Service 360c39
{
Packit Service 360c39
	int start_line;
Packit Service 360c39
	int cur_height = -1, pndx;
Packit Service 360c39
Packit Service 360c39
	last_entry_onscreen[dmode] = 0;
Packit Service 360c39
	if (!has_indirect_blocks())
Packit Service 360c39
		return -1;
Packit Service 360c39
	if (!level) {
Packit Service 360c39
		if (gfs2_struct_type == GFS2_METATYPE_DI) {
Packit Service 360c39
			if (S_ISDIR(di.di_mode))
Packit Service 360c39
				print_gfs2("This directory contains %d indirect blocks",
Packit Service 360c39
					   indblocks);
Packit Service 360c39
			else
Packit Service 360c39
				print_gfs2("This inode contains %d indirect blocks",
Packit Service 360c39
					   indblocks);
Packit Service 360c39
		} else
Packit Service 360c39
			print_gfs2("This indirect block contains %d indirect blocks",
Packit Service 360c39
				   indblocks);
Packit Service 360c39
	}
Packit Service 360c39
	if (dinode_valid() && !S_ISDIR(di.di_mode)) {
Packit Service 360c39
		/* See if we are on an inode or have one in history. */
Packit Service 360c39
		if (level)
Packit Service 360c39
			cur_height = level;
Packit Service 360c39
		else {
Packit Service 360c39
			cur_height = get_height();
Packit Service 360c39
			print_gfs2("  (at height %d of %d)",
Packit Service 360c39
				   cur_height, di.di_height);
Packit Service 360c39
		}
Packit Service 360c39
	}
Packit Service 360c39
	eol(0);
Packit Service 360c39
	if (!level && indblocks) {
Packit Service 360c39
		print_gfs2("Indirect blocks:");
Packit Service 360c39
		eol(0);
Packit Service 360c39
	}
Packit Service 360c39
	start_line = line;
Packit Service 360c39
	for (pndx = start_row[dmode];
Packit Service 360c39
		 (!termlines || pndx < termlines - start_line - 1
Packit Service 360c39
		  + start_row[dmode]) && pndx < indblocks;
Packit Service 360c39
		 pndx++) {
Packit Service 360c39
		uint64_t file_offset;
Packit Service 360c39
Packit Service 360c39
		if (pndx && ind->ii[pndx].block == ind->ii[pndx - 1].block)
Packit Service 360c39
			continue;
Packit Service 360c39
		print_entry_ndx = pndx;
Packit Service 360c39
		if (termlines) {
Packit Service 360c39
			if (edit_row[dmode] >= 0 &&
Packit Service 360c39
			    line - start_line ==
Packit Service 360c39
			    edit_row[dmode] - start_row[dmode])
Packit Service 360c39
				COLORS_HIGHLIGHT;
Packit Service 360c39
			move(line, 1);
Packit Service 360c39
		}
Packit Service 360c39
		if (!termlines) {
Packit Service 360c39
			int h;
Packit Service 360c39
Packit Service 360c39
			for (h = 0; h < level; h++)
Packit Service 360c39
				print_gfs2("   ");
Packit Service 360c39
		}
Packit Service 360c39
		print_gfs2("%d: 0x%"PRIx64" => ", pndx, ind->ii[pndx].ptroff);
Packit Service 360c39
		if (termlines)
Packit Service 360c39
			move(line,9);
Packit Service 360c39
		print_gfs2("0x%"PRIx64" / %"PRId64, ind->ii[pndx].block,
Packit Service 360c39
			   ind->ii[pndx].block);
Packit Service 360c39
		if (termlines) {
Packit Service 360c39
			if (edit_row[dmode] >= 0 &&
Packit Service 360c39
			    line - start_line ==
Packit Service 360c39
			    edit_row[dmode] - start_row[dmode]) { 
Packit Service 360c39
				sprintf(estring, "%llx",
Packit Service 360c39
					(unsigned long long)ind->ii[print_entry_ndx].block);
Packit Service 360c39
				strcpy(edit_fmt, "%llx");
Packit Service 360c39
				edit_size[dmode] = strlen(estring);
Packit Service 360c39
				COLORS_NORMAL;
Packit Service 360c39
			}
Packit Service 360c39
		}
Packit Service 360c39
		if (dinode_valid() && !S_ISDIR(di.di_mode)) {
Packit Service 360c39
			float human_off;
Packit Service 360c39
			char h;
Packit Service 360c39
Packit Service 360c39
			file_offset = metapath_to_lblock(&ind->ii[pndx].mp,
Packit Service 360c39
							 cur_height) *
Packit Service 360c39
				sbd.bsize;
Packit Service 360c39
			print_gfs2("     ");
Packit Service 360c39
			h = 'K';
Packit Service 360c39
			human_off = (file_offset / 1024.0);
Packit Service 360c39
			if (human_off > 1024.0) { h = 'M'; human_off /= 1024.0; }
Packit Service 360c39
			if (human_off > 1024.0) { h = 'G'; human_off /= 1024.0; }
Packit Service 360c39
			if (human_off > 1024.0) { h = 'T'; human_off /= 1024.0; }
Packit Service 360c39
			if (human_off > 1024.0) { h = 'P'; human_off /= 1024.0; }
Packit Service 360c39
			if (human_off > 1024.0) { h = 'E'; human_off /= 1024.0; }
Packit Service 360c39
			print_gfs2("(data offset 0x%"PRIx64" / %"PRId64" / %6.2f%c)",
Packit Service 360c39
				   file_offset, file_offset, human_off, h);
Packit Service 360c39
			print_gfs2("   ");
Packit Service 360c39
		}
Packit Service 360c39
		else
Packit Service 360c39
			file_offset = 0;
Packit Service 360c39
		if (dinode_valid() && !termlines &&
Packit Service 360c39
		    ((level + 1 < di.di_height) ||
Packit Service 360c39
		     (S_ISDIR(di.di_mode) && level <= di.di_height))) {
Packit Service 360c39
			print_block_details(ind, level, cur_height, pndx,
Packit Service 360c39
					    file_offset);
Packit Service 360c39
		}
Packit Service 360c39
		print_entry_ndx = pndx; /* restore after recursion */
Packit Service 360c39
		eol(0);
Packit Service 360c39
	} /* for each display row */
Packit Service 360c39
	if (line >= 7) /* 7 because it was bumped at the end */
Packit Service 360c39
		last_entry_onscreen[dmode] = line - 7;
Packit Service 360c39
	eol(0);
Packit Service 360c39
	end_row[dmode] = indblocks;
Packit Service 360c39
	if (end_row[dmode] < last_entry_onscreen[dmode])
Packit Service 360c39
		end_row[dmode] = last_entry_onscreen[dmode];
Packit Service 360c39
	lines_per_row[dmode] = 1;
Packit Service 360c39
	return 0;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static void print_inode_type(__be16 de_type)
Packit Service 360c39
{
Packit Service 360c39
	if (sbd.gfs1) {
Packit Service 360c39
		switch(de_type) {
Packit Service 360c39
		case GFS_FILE_NON:
Packit Service 360c39
			print_gfs2("Unknown");
Packit Service 360c39
			break;
Packit Service 360c39
		case GFS_FILE_REG:
Packit Service 360c39
			print_gfs2("File   ");
Packit Service 360c39
			break;
Packit Service 360c39
		case GFS_FILE_DIR:
Packit Service 360c39
			print_gfs2("Dir    ");
Packit Service 360c39
			break;
Packit Service 360c39
		case GFS_FILE_LNK:
Packit Service 360c39
			print_gfs2("Symlink");
Packit Service 360c39
			break;
Packit Service 360c39
		case GFS_FILE_BLK:
Packit Service 360c39
			print_gfs2("BlkDev ");
Packit Service 360c39
			break;
Packit Service 360c39
		case GFS_FILE_CHR:
Packit Service 360c39
			print_gfs2("ChrDev ");
Packit Service 360c39
			break;
Packit Service 360c39
		case GFS_FILE_FIFO:
Packit Service 360c39
			print_gfs2("Fifo   ");
Packit Service 360c39
			break;
Packit Service 360c39
		case GFS_FILE_SOCK:
Packit Service 360c39
			print_gfs2("Socket ");
Packit Service 360c39
			break;
Packit Service 360c39
		default:
Packit Service 360c39
			print_gfs2("%04x   ", de_type);
Packit Service 360c39
			break;
Packit Service 360c39
		}
Packit Service 360c39
		return;
Packit Service 360c39
	}
Packit Service 360c39
	switch(de_type) {
Packit Service 360c39
	case DT_UNKNOWN:
Packit Service 360c39
		print_gfs2("Unknown");
Packit Service 360c39
		break;
Packit Service 360c39
	case DT_REG:
Packit Service 360c39
		print_gfs2("File   ");
Packit Service 360c39
		break;
Packit Service 360c39
	case DT_DIR:
Packit Service 360c39
		print_gfs2("Dir    ");
Packit Service 360c39
		break;
Packit Service 360c39
	case DT_LNK:
Packit Service 360c39
		print_gfs2("Symlink");
Packit Service 360c39
		break;
Packit Service 360c39
	case DT_BLK:
Packit Service 360c39
		print_gfs2("BlkDev ");
Packit Service 360c39
		break;
Packit Service 360c39
	case DT_CHR:
Packit Service 360c39
		print_gfs2("ChrDev ");
Packit Service 360c39
		break;
Packit Service 360c39
	case DT_FIFO:
Packit Service 360c39
		print_gfs2("Fifo   ");
Packit Service 360c39
		break;
Packit Service 360c39
	case DT_SOCK:
Packit Service 360c39
		print_gfs2("Socket ");
Packit Service 360c39
		break;
Packit Service 360c39
	default:
Packit Service 360c39
		print_gfs2("%04x   ", de_type);
Packit Service 360c39
		break;
Packit Service 360c39
	}
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
#ifdef GFS2_HAS_LEAF_HINTS
Packit Service 360c39
#define LEAF_HINT_FMTS "lf_inode: 0x%llx, lf_dist: %u, " \
Packit Service 360c39
                       "lf_nsec: %u, lf_sec: %llu, "
Packit Service 360c39
#define LEAF_HINT_FIELDS(lp) lp->lf_inode, lp->lf_dist, lp->lf_nsec, lp->lf_sec,
Packit Service 360c39
#else
Packit Service 360c39
#define LEAF_HINT_FMTS
Packit Service 360c39
#define LEAF_HINT_FIELDS(lp)
Packit Service 360c39
#endif
Packit Service 360c39
Packit Service 360c39
static int display_leaf(struct iinfo *ind)
Packit Service 360c39
{
Packit Service 360c39
	struct gfs2_leaf *leaf = &ind->ii[0].lf;
Packit Service 360c39
	int start_line, total_dirents = start_row[dmode];
Packit Service 360c39
	int d;
Packit Service 360c39
Packit Service 360c39
	eol(0);
Packit Service 360c39
	if (gfs2_struct_type == GFS2_METATYPE_SB)
Packit Service 360c39
		print_gfs2("The superblock has 2 directories");
Packit Service 360c39
	else
Packit Service 360c39
		print_gfs2("Directory block: lf_depth:%d, lf_entries:%d, "
Packit Service 360c39
		           LEAF_HINT_FMTS
Packit Service 360c39
			   "fmt:%d next=0x%llx (%d dirents).",
Packit Service 360c39
			   leaf->lf_depth, leaf->lf_entries,
Packit Service 360c39
		           LEAF_HINT_FIELDS(leaf)
Packit Service 360c39
			   leaf->lf_dirent_format,
Packit Service 360c39
			   leaf->lf_next,
Packit Service 360c39
			   ind->ii[0].dirents);
Packit Service 360c39
Packit Service 360c39
	start_line = line;
Packit Service 360c39
	for (d = start_row[dmode]; d < ind->ii[0].dirents; d++) {
Packit Service 360c39
		if (termlines && d >= termlines - start_line - 2
Packit Service 360c39
		    + start_row[dmode])
Packit Service 360c39
			break;
Packit Service 360c39
		total_dirents++;
Packit Service 360c39
		if (ind->ii[0].dirents >= 1) {
Packit Service 360c39
			eol(3);
Packit Service 360c39
			if (termlines) {
Packit Service 360c39
				if (edit_row[dmode] >=0 &&
Packit Service 360c39
				    line - start_line - 1 ==
Packit Service 360c39
				    edit_row[dmode] - start_row[dmode]) {
Packit Service 360c39
					COLORS_HIGHLIGHT;
Packit Service 360c39
					sprintf(estring, "%llx",
Packit Service 360c39
						(unsigned long long)ind->ii[0].dirent[d].block);
Packit Service 360c39
					strcpy(edit_fmt, "%llx");
Packit Service 360c39
				}
Packit Service 360c39
			}
Packit Service 360c39
			print_gfs2("%d/%d [%08x] %lld/%"PRId64" (0x%llx/0x%"PRIx64") +%u: ",
Packit Service 360c39
				   total_dirents, d + 1,
Packit Service 360c39
				   ind->ii[0].dirent[d].dirent.de_hash,
Packit Service 360c39
				   ind->ii[0].dirent[d].dirent.de_inum.no_formal_ino,
Packit Service 360c39
				   ind->ii[0].dirent[d].block,
Packit Service 360c39
				   ind->ii[0].dirent[d].dirent.de_inum.no_formal_ino,
Packit Service 360c39
				   ind->ii[0].dirent[d].block,
Packit Service 360c39
#ifdef GFS2_HAS_DE_RAHEAD
Packit Service 360c39
				   (unsigned int)ind->ii[0].dirent[d].dirent.de_rahead
Packit Service 360c39
#else
Packit Service 360c39
				   0
Packit Service 360c39
#endif
Packit Service 360c39
			);
Packit Service 360c39
		}
Packit Service 360c39
		print_inode_type(ind->ii[0].dirent[d].dirent.de_type);
Packit Service 360c39
		print_gfs2(" %s", ind->ii[0].dirent[d].filename);
Packit Service 360c39
		if (termlines) {
Packit Service 360c39
			if (edit_row[dmode] >= 0 &&
Packit Service 360c39
			    line - start_line - 1 == edit_row[dmode] -
Packit Service 360c39
			    start_row[dmode])
Packit Service 360c39
				COLORS_NORMAL;
Packit Service 360c39
		}
Packit Service 360c39
	}
Packit Service 360c39
	if (line >= 4)
Packit Service 360c39
		last_entry_onscreen[dmode] = line - 4;
Packit Service 360c39
	eol(0);
Packit Service 360c39
	end_row[dmode] = ind->ii[0].dirents;
Packit Service 360c39
	if (end_row[dmode] < last_entry_onscreen[dmode])
Packit Service 360c39
		end_row[dmode] = last_entry_onscreen[dmode];
Packit Service 360c39
	return 0;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static void print_block_details(struct iinfo *ind, int level, int cur_height,
Packit Service 360c39
				int pndx, uint64_t file_offset)
Packit Service 360c39
{
Packit Service 360c39
	struct iinfo *more_indir;
Packit Service 360c39
	int more_ind;
Packit Service 360c39
	char *tmpbuf;
Packit Service 360c39
	uint64_t thisblk;
Packit Service 360c39
Packit Service 360c39
	thisblk = ind->ii[pndx].block;
Packit Service 360c39
	more_indir = malloc(sizeof(struct iinfo));
Packit Service 360c39
	if (!more_indir) {
Packit Service 360c39
		fprintf(stderr, "Out of memory in function "
Packit Service 360c39
			"display_indirect\n");
Packit Service 360c39
		return;
Packit Service 360c39
	}
Packit Service 360c39
	tmpbuf = malloc(sbd.bsize);
Packit Service 360c39
	if (!tmpbuf) {
Packit Service 360c39
		fprintf(stderr, "Out of memory in function "
Packit Service 360c39
			"display_indirect\n");
Packit Service 360c39
		free(more_indir);
Packit Service 360c39
		return;
Packit Service 360c39
	}
Packit Service 360c39
	while (thisblk) {
Packit Service 360c39
		/* read in the desired block */
Packit Service 360c39
		if (pread(sbd.device_fd, tmpbuf, sbd.bsize, thisblk * sbd.bsize) != sbd.bsize) {
Packit Service 360c39
			fprintf(stderr, "bad read: %s from %s:%d: block %lld "
Packit Service 360c39
				"(0x%llx)\n", strerror(errno), __FUNCTION__,
Packit Service 360c39
				__LINE__,
Packit Service 360c39
				(unsigned long long)ind->ii[pndx].block,
Packit Service 360c39
				(unsigned long long)ind->ii[pndx].block);
Packit Service 360c39
			exit(-1);
Packit Service 360c39
		}
Packit Service 360c39
		thisblk = 0;
Packit Service 360c39
		memset(more_indir, 0, sizeof(struct iinfo));
Packit Service 360c39
		if (S_ISDIR(di.di_mode) && level == di.di_height) {
Packit Service 360c39
			thisblk = do_leaf_extended(tmpbuf, more_indir);
Packit Service 360c39
			display_leaf(more_indir);
Packit Service 360c39
		} else {
Packit Service 360c39
			int x;
Packit Service 360c39
Packit Service 360c39
			for (x = 0; x < 512; x++) {
Packit Service 360c39
				memcpy(&more_indir->ii[x].mp,
Packit Service 360c39
				       &ind->ii[pndx].mp,
Packit Service 360c39
				       sizeof(struct metapath));
Packit Service 360c39
				more_indir->ii[x].mp.mp_list[cur_height+1] = x;
Packit Service 360c39
			}
Packit Service 360c39
			more_ind = _do_indirect_extended(tmpbuf, more_indir,
Packit Service 360c39
							 cur_height + 1);
Packit Service 360c39
			display_indirect(more_indir, more_ind, level + 1,
Packit Service 360c39
					 file_offset);
Packit Service 360c39
		}
Packit Service 360c39
		if (thisblk) {
Packit Service 360c39
			eol(0);
Packit Service 360c39
			if (termlines)
Packit Service 360c39
				move(line,9);
Packit Service 360c39
			print_gfs2("Continuation block 0x%"PRIx64" / %"PRId64,
Packit Service 360c39
				   thisblk, thisblk);
Packit Service 360c39
		}
Packit Service 360c39
	}
Packit Service 360c39
	free(tmpbuf);
Packit Service 360c39
	free(more_indir);
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static void gfs_jindex_print(struct gfs_jindex *ji)
Packit Service 360c39
{
Packit Service 360c39
        pv((unsigned long long)ji, ji_addr, "%llu", "0x%llx");
Packit Service 360c39
        pv(ji, ji_nsegment, "%u", "0x%x");
Packit Service 360c39
        pv(ji, ji_pad, "%u", "0x%x");
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static int print_gfs_jindex(struct gfs2_inode *dij)
Packit Service 360c39
{
Packit Service 360c39
	int error, start_line;
Packit Service 360c39
	struct gfs_jindex ji;
Packit Service 360c39
	char jbuf[sizeof(struct gfs_jindex)];
Packit Service 360c39
Packit Service 360c39
	start_line = line;
Packit Service 360c39
	print_gfs2("Journal index entries found: %lld.",
Packit Service 360c39
		   dij->i_di.di_size / sizeof(struct gfs_jindex));
Packit Service 360c39
	eol(0);
Packit Service 360c39
	lines_per_row[dmode] = 4;
Packit Service 360c39
	for (print_entry_ndx=0; ; print_entry_ndx++) {
Packit Service 360c39
		error = gfs2_readi(dij, (void *)&jbuf,
Packit Service 360c39
				   print_entry_ndx*sizeof(struct gfs_jindex),
Packit Service 360c39
				   sizeof(struct gfs_jindex));
Packit Service 360c39
		gfs_jindex_in(&ji, jbuf);
Packit Service 360c39
		if (!error) /* end of file */
Packit Service 360c39
			break;
Packit Service 360c39
		if (!termlines ||
Packit Service 360c39
		    (print_entry_ndx >= start_row[dmode] &&
Packit Service 360c39
		     ((print_entry_ndx - start_row[dmode])+1) *
Packit Service 360c39
		     lines_per_row[dmode] <= termlines - start_line - 2)) {
Packit Service 360c39
			if (edit_row[dmode] == print_entry_ndx) {
Packit Service 360c39
				COLORS_HIGHLIGHT;
Packit Service 360c39
				strcpy(efield, "ji_addr");
Packit Service 360c39
				sprintf(estring, "%llx", (unsigned long long)ji.ji_addr);
Packit Service 360c39
			}
Packit Service 360c39
			print_gfs2("Journal #%d", print_entry_ndx);
Packit Service 360c39
			eol(0);
Packit Service 360c39
			if (edit_row[dmode] == print_entry_ndx)
Packit Service 360c39
				COLORS_NORMAL;
Packit Service 360c39
			gfs_jindex_print(&ji;;
Packit Service 360c39
			last_entry_onscreen[dmode] = print_entry_ndx;
Packit Service 360c39
		}
Packit Service 360c39
	}
Packit Service 360c39
	end_row[dmode] = print_entry_ndx;
Packit Service 360c39
	return error;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static int print_gfs2_jindex(void)
Packit Service 360c39
{
Packit Service 360c39
	int d, error;
Packit Service 360c39
	struct gfs2_log_header head;
Packit Service 360c39
	struct gfs2_inode *ip;
Packit Service 360c39
Packit Service 360c39
	for (d = 0; d < indirect->ii[0].dirents; d++) {
Packit Service 360c39
		if (strncmp(indirect->ii[0].dirent[d].filename, "journal", 7))
Packit Service 360c39
			continue;
Packit Service 360c39
		ip = lgfs2_inode_read(&sbd, indirect->ii[0].dirent[d].block);
Packit Service 360c39
		print_gfs2("%s: 0x%-5"PRIx64" %lldMB ",
Packit Service 360c39
			   indirect->ii[0].dirent[d].filename,
Packit Service 360c39
			   indirect->ii[0].dirent[d].block,
Packit Service 360c39
			   ip->i_di.di_size / 1048576);
Packit Service 360c39
		error = gfs2_find_jhead(ip, &head;;
Packit Service 360c39
		if (error) {
Packit Service 360c39
			print_gfs2("corrupt.");
Packit Service 360c39
		} else {
Packit Service 360c39
			if (head.lh_flags & GFS2_LOG_HEAD_UNMOUNT)
Packit Service 360c39
				print_gfs2("clean.");
Packit Service 360c39
			else
Packit Service 360c39
				print_gfs2("dirty.");
Packit Service 360c39
		}
Packit Service 360c39
		eol(0);
Packit Service 360c39
		inode_put(&ip);
Packit Service 360c39
	}
Packit Service 360c39
	return 0;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static int parse_rindex(struct gfs2_inode *dip, int print_rindex)
Packit Service 360c39
{
Packit Service 360c39
	int error, start_line;
Packit Service 360c39
	struct gfs2_rindex ri;
Packit Service 360c39
	char rbuf[sizeof(struct gfs2_rindex)];
Packit Service 360c39
	char highlighted_addr[32];
Packit Service 360c39
Packit Service 360c39
	start_line = line;
Packit Service 360c39
	print_gfs2("RG index entries found: %lld.", dip->i_di.di_size /
Packit Service 360c39
		   sizeof(struct gfs2_rindex));
Packit Service 360c39
	eol(0);
Packit Service 360c39
	lines_per_row[dmode] = 6;
Packit Service 360c39
	memset(highlighted_addr, 0, sizeof(highlighted_addr));
Packit Service 360c39
Packit Service 360c39
	for (print_entry_ndx=0; ; print_entry_ndx++) {
Packit Service 360c39
		uint64_t roff;
Packit Service 360c39
Packit Service 360c39
		roff = print_entry_ndx * sizeof(struct gfs2_rindex);
Packit Service 360c39
Packit Service 360c39
		error = gfs2_readi(dip, (void *)&rbuf, roff,
Packit Service 360c39
				   sizeof(struct gfs2_rindex));
Packit Service 360c39
		if (!error) /* end of file */
Packit Service 360c39
			break;
Packit Service 360c39
		gfs2_rindex_in(&ri, rbuf);
Packit Service 360c39
		if (!termlines ||
Packit Service 360c39
			(print_entry_ndx >= start_row[dmode] &&
Packit Service 360c39
			 ((print_entry_ndx - start_row[dmode])+1) * lines_per_row[dmode] <=
Packit Service 360c39
			 termlines - start_line - 2)) {
Packit Service 360c39
			if (edit_row[dmode] == print_entry_ndx) {
Packit Service 360c39
				COLORS_HIGHLIGHT;
Packit Service 360c39
				sprintf(highlighted_addr, "%llx", (unsigned long long)ri.ri_addr);
Packit Service 360c39
			}
Packit Service 360c39
			print_gfs2("RG #%d", print_entry_ndx);
Packit Service 360c39
			if (!print_rindex)
Packit Service 360c39
				print_gfs2(" located at: %llu (0x%llx)",
Packit Service 360c39
					   ri.ri_addr, ri.ri_addr);
Packit Service 360c39
			eol(0);
Packit Service 360c39
			if (edit_row[dmode] == print_entry_ndx)
Packit Service 360c39
				COLORS_NORMAL;
Packit Service 360c39
			if(print_rindex)
Packit Service 360c39
				gfs2_rindex_print(&ri);
Packit Service 360c39
			else {
Packit Service 360c39
				struct gfs2_buffer_head *tmp_bh;
Packit Service 360c39
Packit Service 360c39
				tmp_bh = bread(&sbd, ri.ri_addr);
Packit Service 360c39
				if (sbd.gfs1) {
Packit Service 360c39
					struct gfs_rgrp rg1;
Packit Service 360c39
					gfs_rgrp_in(&rg1, tmp_bh);
Packit Service 360c39
					gfs_rgrp_print(&rg1);
Packit Service 360c39
				} else {
Packit Service 360c39
					struct gfs2_rgrp rg;
Packit Service 360c39
					gfs2_rgrp_in(&rg, tmp_bh->b_data);
Packit Service 360c39
					gfs2_rgrp_print(&rg;;
Packit Service 360c39
				}
Packit Service 360c39
				brelse(tmp_bh);
Packit Service 360c39
			}
Packit Service 360c39
			last_entry_onscreen[dmode] = print_entry_ndx;
Packit Service 360c39
		}
Packit Service 360c39
	}
Packit Service 360c39
	strcpy(estring, highlighted_addr);
Packit Service 360c39
	end_row[dmode] = print_entry_ndx;
Packit Service 360c39
	return error;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static int print_inum(struct gfs2_inode *dii)
Packit Service 360c39
{
Packit Service 360c39
	uint64_t inum, inodenum;
Packit Service 360c39
	int rc;
Packit Service 360c39
	
Packit Service 360c39
	rc = gfs2_readi(dii, (void *)&inum, 0, sizeof(inum));
Packit Service 360c39
	if (!rc) {
Packit Service 360c39
		print_gfs2("The inum file is empty.");
Packit Service 360c39
		eol(0);
Packit Service 360c39
		return 0;
Packit Service 360c39
	}
Packit Service 360c39
	if (rc != sizeof(inum)) {
Packit Service 360c39
		print_gfs2("Error reading inum file.");
Packit Service 360c39
		eol(0);
Packit Service 360c39
		return -1;
Packit Service 360c39
	}
Packit Service 360c39
	inodenum = be64_to_cpu(inum);
Packit Service 360c39
	print_gfs2("Next inode num = %"PRId64" (0x%"PRIx64")", inodenum, inodenum);
Packit Service 360c39
	eol(0);
Packit Service 360c39
	return 0;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static int print_statfs(struct gfs2_inode *dis)
Packit Service 360c39
{
Packit Service 360c39
	struct gfs2_statfs_change sfb, sfc;
Packit Service 360c39
	int rc;
Packit Service 360c39
	
Packit Service 360c39
	rc = gfs2_readi(dis, (void *)&sfb, 0, sizeof(sfb));
Packit Service 360c39
	if (!rc) {
Packit Service 360c39
		print_gfs2("The statfs file is empty.");
Packit Service 360c39
		eol(0);
Packit Service 360c39
		return 0;
Packit Service 360c39
	}
Packit Service 360c39
	if (rc != sizeof(sfb)) {
Packit Service 360c39
		print_gfs2("Error reading statfs file.");
Packit Service 360c39
		eol(0);
Packit Service 360c39
		return -1;
Packit Service 360c39
	}
Packit Service 360c39
	gfs2_statfs_change_in(&sfc, (char *)&sfb;;
Packit Service 360c39
	print_gfs2("statfs file contents:");
Packit Service 360c39
	eol(0);
Packit Service 360c39
	gfs2_statfs_change_print(&sfc;;
Packit Service 360c39
	return 0;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static int print_quota(struct gfs2_inode *diq)
Packit Service 360c39
{
Packit Service 360c39
	struct gfs2_quota qbuf, q;
Packit Service 360c39
	int i, error;
Packit Service 360c39
	
Packit Service 360c39
	print_gfs2("quota file contents:");
Packit Service 360c39
	eol(0);
Packit Service 360c39
	print_gfs2("quota entries found: %lld.", diq->i_di.di_size / sizeof(q));
Packit Service 360c39
	eol(0);
Packit Service 360c39
	for (i=0; ; i++) {
Packit Service 360c39
		error = gfs2_readi(diq, (void *)&qbuf, i * sizeof(q), sizeof(qbuf));
Packit Service 360c39
		if (!error)
Packit Service 360c39
			break;
Packit Service 360c39
		if (error != sizeof(qbuf)) {
Packit Service 360c39
			print_gfs2("Error reading quota file.");
Packit Service 360c39
			eol(0);
Packit Service 360c39
			return -1;
Packit Service 360c39
		}
Packit Service 360c39
		gfs2_quota_in(&q, (char *)&qbuf);
Packit Service 360c39
		print_gfs2("Entry #%d", i + 1);
Packit Service 360c39
		eol(0);
Packit Service 360c39
		gfs2_quota_print(&q);
Packit Service 360c39
	}
Packit Service 360c39
	return 0;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
int display_extended(void)
Packit Service 360c39
{
Packit Service 360c39
	struct gfs2_inode *tmp_inode;
Packit Service 360c39
	struct gfs2_buffer_head *tmp_bh;
Packit Service 360c39
Packit Service 360c39
	dsplines = termlines - line - 1;
Packit Service 360c39
	/* Display any indirect pointers that we have. */
Packit Service 360c39
	if (block_is_rindex(block)) {
Packit Service 360c39
		tmp_bh = bread(&sbd, block);
Packit Service 360c39
		tmp_inode = lgfs2_inode_get(&sbd, tmp_bh);
Packit Service 360c39
		if (tmp_inode == NULL)
Packit Service 360c39
			return -1;
Packit Service 360c39
		parse_rindex(tmp_inode, TRUE);
Packit Service 360c39
		inode_put(&tmp_inode);
Packit Service 360c39
		brelse(tmp_bh);
Packit Service 360c39
	} else if (block_is_journals(block)) {
Packit Service 360c39
		if (sbd.gfs1)
Packit Service 360c39
			block = sbd1->sb_jindex_di.no_addr;
Packit Service 360c39
		else
Packit Service 360c39
			block = masterblock("jindex");
Packit Service 360c39
		print_gfs2_jindex();
Packit Service 360c39
	} else if (has_indirect_blocks() && !indirect_blocks &&
Packit Service 360c39
		 !display_leaf(indirect))
Packit Service 360c39
		return -1;
Packit Service 360c39
	else if (display_indirect(indirect, indirect_blocks, 0, 0) == 0)
Packit Service 360c39
		return -1;
Packit Service 360c39
	else if (block_is_rgtree(block)) {
Packit Service 360c39
		if (sbd.gfs1)
Packit Service 360c39
			tmp_bh = bread(&sbd, sbd1->sb_rindex_di.no_addr);
Packit Service 360c39
		else
Packit Service 360c39
			tmp_bh = bread(&sbd, masterblock("rindex"));
Packit Service 360c39
		tmp_inode = lgfs2_inode_get(&sbd, tmp_bh);
Packit Service 360c39
		if (tmp_inode == NULL)
Packit Service 360c39
			return -1;
Packit Service 360c39
		parse_rindex(tmp_inode, FALSE);
Packit Service 360c39
		inode_put(&tmp_inode);
Packit Service 360c39
		brelse(tmp_bh);
Packit Service 360c39
	} else if (block_is_jindex(block)) {
Packit Service 360c39
		tmp_bh = bread(&sbd, block);
Packit Service 360c39
		tmp_inode = lgfs2_inode_get(&sbd, tmp_bh);
Packit Service 360c39
		if (tmp_inode == NULL)
Packit Service 360c39
			return -1;
Packit Service 360c39
		print_gfs_jindex(tmp_inode);
Packit Service 360c39
		inode_put(&tmp_inode);
Packit Service 360c39
		brelse(tmp_bh);
Packit Service 360c39
	}
Packit Service 360c39
	else if (block_is_inum_file(block)) {
Packit Service 360c39
		tmp_bh = bread(&sbd, block);
Packit Service 360c39
		tmp_inode = lgfs2_inode_get(&sbd, tmp_bh);
Packit Service 360c39
		if (tmp_inode == NULL)
Packit Service 360c39
			return -1;
Packit Service 360c39
		print_inum(tmp_inode);
Packit Service 360c39
		inode_put(&tmp_inode);
Packit Service 360c39
		brelse(tmp_bh);
Packit Service 360c39
	}
Packit Service 360c39
	else if (block_is_statfs_file(block)) {
Packit Service 360c39
		tmp_bh = bread(&sbd, block);
Packit Service 360c39
		tmp_inode = lgfs2_inode_get(&sbd, tmp_bh);
Packit Service 360c39
		if (tmp_inode == NULL)
Packit Service 360c39
			return -1;
Packit Service 360c39
		print_statfs(tmp_inode);
Packit Service 360c39
		inode_put(&tmp_inode);
Packit Service 360c39
		brelse(tmp_bh);
Packit Service 360c39
	}
Packit Service 360c39
	else if (block_is_quota_file(block)) {
Packit Service 360c39
		tmp_bh = bread(&sbd, block);
Packit Service 360c39
		tmp_inode = lgfs2_inode_get(&sbd, tmp_bh);
Packit Service 360c39
		if (tmp_inode == NULL)
Packit Service 360c39
			return -1;
Packit Service 360c39
		print_quota(tmp_inode);
Packit Service 360c39
		inode_put(&tmp_inode);
Packit Service 360c39
		brelse(tmp_bh);
Packit Service 360c39
	}
Packit Service 360c39
	return 0;
Packit Service 360c39
}
Packit Service 360c39