* [Cluster-devel] cluster/gfs2/edit gfs2hex.c hexedit.c hexedit. ...
@ 2007-07-16 23:16 rpeterso
0 siblings, 0 replies; only message in thread
From: rpeterso @ 2007-07-16 23:16 UTC (permalink / raw)
To: cluster-devel.redhat.com
CVSROOT: /cvs/cluster
Module name: cluster
Changes by: rpeterso at sourceware.org 2007-07-16 23:16:35
Modified files:
gfs2/edit : gfs2hex.c hexedit.c hexedit.h savemeta.c
Log message:
I added the ability to recurse indirect blocks. That means
that you can now print a list of all blocks associated with a file.
For example, you could print all block numbers associated with
journal0 by doing something like:
gfs2_edit -p 0x19 /dev/roth_vg/roth_lv
assuming, of course, that you know that block 0x19 contains journal0.
(You can use gfs2_edit -p jindex <dev> to get that information though).
I fixed some bugs with restoremeta where it was dying if the
metadata to be restored was bigger than the destination file system
could hold.
I made restoremeta do some "warm fuzzy stuff" to report its
progress of the restore operation so the user doesn't think the
restoremeta is permanently hung.
I renamed some long variable names to short ones to make the
code less wordy.
I fixed a minor segfault if you hit "j" when your cursor is
on the block number of the hex view.
I probably should have committed these changes earlier rather than
save them up, but some of my changes had serious regressions and I
didn't have time to sort it out and fix it until just now (I didn't
want to commit a broken version to cvs.)
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/edit/gfs2hex.c.diff?cvsroot=cluster&r1=1.10&r2=1.11
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/edit/hexedit.c.diff?cvsroot=cluster&r1=1.16&r2=1.17
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/edit/hexedit.h.diff?cvsroot=cluster&r1=1.9&r2=1.10
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/edit/savemeta.c.diff?cvsroot=cluster&r1=1.1&r2=1.2
--- cluster/gfs2/edit/gfs2hex.c 2007/02/28 21:58:46 1.10
+++ cluster/gfs2/edit/gfs2hex.c 2007/07/16 23:16:35 1.11
@@ -192,6 +192,7 @@
memcpy(&indir->dirent[d].dirent, &de, sizeof(struct gfs2_dirent));
memcpy(&indir->dirent[d].filename,
ptr + sizeof(struct gfs2_dirent), de.de_name_len);
+ indir->dirent[d].filename[de.de_name_len] = '\0';
indir->dirent[d].block = de.de_inum.no_addr;
indir->is_dir = TRUE;
indir->dirents++;
@@ -222,7 +223,7 @@
(gfs1 && di->__pad1 == GFS_FILE_DIR);
indirect_blocks = 0;
- memset(&indirect, 0, sizeof(indirect));
+ memset(indirect, 0, sizeof(indirect));
if (di->di_height > 0) {
/* Indirect pointers */
for (x = sizeof(struct gfs2_dinode), y = 0;
@@ -230,21 +231,23 @@
x += sizeof(uint64_t), y++) {
p = be64_to_cpu(*(uint64_t *)(buf + x));
if (p) {
- indirect[indirect_blocks].block = p;
- indirect[indirect_blocks].is_dir = FALSE;
+ indirect->ii[indirect_blocks].block = p;
+ indirect->ii[indirect_blocks].is_dir = FALSE;
indirect_blocks++;
}
}
}
- else if (isdir &&
- !(di->di_flags & GFS2_DIF_EXHASH)) {
+ else if (isdir && !(di->di_flags & GFS2_DIF_EXHASH)) {
int skip = 0;
+
/* Directory Entries: */
- indirect[0].dirents = 0;
- indirect[0].block = block;
- indirect[0].is_dir = TRUE;
+ indirect->ii[0].dirents = 0;
+ indirect->ii[0].block = block;
+ indirect->ii[0].is_dir = TRUE;
for (x = sizeof(struct gfs2_dinode); x < bufsize; x += skip) {
- skip = indirect_dirent(&indirect[0], buf + x, indirect[0].dirents);
+ skip = indirect_dirent(indirect->ii,
+ buf + x,
+ indirect->ii[0].dirents);
if (skip <= 0)
break;
}
@@ -267,20 +270,22 @@
struct gfs2_leaf leaf;
unsigned int bufoffset;
+ if (last >= max_block)
+ break;
tmp_bh = bread(&sbd, last);
gfs2_leaf_in(&leaf, tmp_bh->b_data);
- indirect[indirect_blocks].dirents = 0;
+ indirect->ii[indirect_blocks].dirents = 0;
for (direntcount = 0, bufoffset = sizeof(struct gfs2_leaf);
bufoffset < bufsize;
direntcount++, bufoffset += skip) {
- skip = indirect_dirent(&indirect[indirect_blocks],
+ skip = indirect_dirent(&indirect->ii[indirect_blocks],
tmp_bh->b_data + bufoffset,
direntcount);
if (skip <= 0)
break;
}
brelse(tmp_bh, not_updated);
- indirect[indirect_blocks].block = last;
+ indirect->ii[indirect_blocks].block = last;
indirect_blocks++;
last = p;
} /* if not duplicate pointer */
@@ -303,24 +308,26 @@
**
*******************************************************************************
******************************************************************************/
-void do_indirect_extended(char *buf)
+int do_indirect_extended(char *buf, struct iinfo *iinf)
{
unsigned int x, y;
uint64_t p;
+ int i_blocks;
- indirect_blocks = 0;
- memset(&indirect, 0, sizeof(indirect));
+ i_blocks = 0;
+ memset(iinf, 0, sizeof(struct iinfo));
for (x = (gfs1 ? sizeof(struct gfs_indirect):
sizeof(struct gfs2_meta_header)), y = 0;
x < bufsize;
x += sizeof(uint64_t), y++) {
p = be64_to_cpu(*(uint64_t *)(buf + x));
if (p) {
- indirect[indirect_blocks].block = p;
- indirect[indirect_blocks].is_dir = FALSE;
- indirect_blocks++;
+ iinf->ii[i_blocks].block = p;
+ iinf->ii[i_blocks].is_dir = FALSE;
+ i_blocks++;
}
}
+ return i_blocks;
}
/******************************************************************************
--- cluster/gfs2/edit/hexedit.c 2007/06/26 01:25:33 1.16
+++ cluster/gfs2/edit/hexedit.c 2007/07/16 23:16:35 1.17
@@ -46,7 +46,7 @@
int display(int identify_only);
extern void eol(int col);
-extern void do_indirect_extended(char *buf);
+extern int do_indirect_extended(char *buf, struct iinfo *ii);
extern void savemeta(const char *in_fn, const char *out_fn, int slow);
extern void restoremeta(const char *in_fn, const char *out_device);
@@ -822,49 +822,51 @@
/* ------------------------------------------------------------------------ */
/* display_indirect */
/* ------------------------------------------------------------------------ */
-int display_indirect(void)
+int display_indirect(struct iinfo *ind, int indblocks, int level, uint64_t startoff)
{
int start_line, total_dirents, indir_blocks;
- int i, cur_height = -1;
+ int i, cur_height = -1, pndx;
uint64_t factor[5]={0,0,0,0,0};
int offsets[5];
last_entry_onscreen[dmode] = 0;
- eol(0);
+ if (!level)
+ eol(0);
start_line = line;
if (!has_indirect_blocks())
return -1;
- indir_blocks = indirect_blocks;
- if (!indirect_blocks) {
- if (gfs2_struct_type == GFS2_METATYPE_SB)
- print_gfs2("The superblock has 2 directories");
- else
- print_gfs2("This directory contains %d directory entries.",
- indirect[0].dirents);
- indir_blocks = 1; /* not really an indirect block, but treat it as one */
- }
- else {
- if (gfs2_struct_type == GFS2_METATYPE_DI) {
- if (S_ISDIR(di.di_mode))
- print_gfs2("This directory contains %d indirect blocks",
- indirect_blocks);
+ indir_blocks = indblocks;
+ if (!level) {
+ if (!indblocks) {
+ if (gfs2_struct_type == GFS2_METATYPE_SB)
+ print_gfs2("The superblock has 2 directories");
else
- print_gfs2("This inode contains %d indirect blocks",
- indirect_blocks);
+ print_gfs2("This directory contains %d directory entries.",
+ ind->ii[0].dirents);
+ indir_blocks = 1; /* not really an indirect block, but treat it as one */
+ }
+ else {
+ if (gfs2_struct_type == GFS2_METATYPE_DI) {
+ if (S_ISDIR(di.di_mode))
+ print_gfs2("This directory contains %d indirect blocks",
+ indblocks);
+ else
+ print_gfs2("This inode contains %d indirect blocks",
+ indblocks);
+ }
+ else
+ print_gfs2("This indirect block contains %d indirect blocks",
+ indblocks);
}
- else
- print_gfs2("This indirect block contains %d indirect blocks",
- indirect_blocks);
}
total_dirents = 0;
/* Figure out multiplication factors for indirect pointers. */
- if ((indir_blocks == indirect_blocks) && !S_ISDIR(di.di_mode)) {
+ if ((indir_blocks == indblocks) && !S_ISDIR(di.di_mode)) {
memset(&offsets, 0, sizeof(offsets));
/* See if we are on an inode or have one in history. */
- cur_height = 0;
- if (gfs2_struct_type != GFS2_METATYPE_DI) {
- cur_height = 0;
+ cur_height = level;
+ if (!level && gfs2_struct_type != GFS2_METATYPE_DI) {
for (i = 0; i <= blockhist && i < 5; i++) {
offsets[i] = blockstack[(blockhist - i) % BLOCK_STACK_SIZE].edit_row[dmode];
if (blockstack[(blockhist - i) % BLOCK_STACK_SIZE].gfs2_struct_type == GFS2_METATYPE_DI)
@@ -890,17 +892,19 @@
for (i = 0; i < di.di_height; i++)
factor[i + 1] = factor[i] * inptrs;
}
- print_gfs2(" (at height=%d)", cur_height);
- }
- if (indirect_blocks) {
+ if (!level)
+ print_gfs2(" (at height=%d)", cur_height);
eol(0);
+ }
+ if (!level && indblocks) {
print_gfs2("Indirect blocks:");
+ eol(0);
}
- eol(0);
- for (print_entry_ndx = start_row[dmode];
- (!termlines || print_entry_ndx < termlines - start_line - 2
- + start_row[dmode]) && print_entry_ndx < indir_blocks;
- print_entry_ndx++) {
+ for (pndx = start_row[dmode];
+ (!termlines || pndx < termlines - start_line - 2
+ + start_row[dmode]) && pndx < indir_blocks;
+ pndx++) {
+ print_entry_ndx = pndx;
if (termlines) {
if (edit_row[dmode] >= 0 &&
line - start_line - 2 == edit_row[dmode] -
@@ -908,18 +912,24 @@
COLORS_HIGHLIGHT;
move(line, 1);
}
- if (indir_blocks == indirect_blocks) {
- print_gfs2("%d => ", print_entry_ndx);
+ if (indir_blocks == indblocks) {
+ if (!termlines) {
+ int h;
+
+ for (h = 0; h < level; h++)
+ print_gfs2(" ");
+ }
+ print_gfs2("%d => ", pndx);
if (termlines)
move(line,9);
- print_gfs2("0x%llx / %lld", indirect[print_entry_ndx].block,
- indirect[print_entry_ndx].block);
+ print_gfs2("0x%llx / %lld", ind->ii[pndx].block,
+ ind->ii[pndx].block);
if (termlines) {
if (edit_row[dmode] >= 0 &&
line - start_line - 2 == edit_row[dmode] -
start_row[dmode]) {
sprintf(estring, "%"PRIx64,
- indirect[print_entry_ndx].block);
+ ind->ii[print_entry_ndx].block);
strcpy(edit_fmt, "%"PRIx64);
edit_size[dmode] = strlen(estring);
COLORS_NORMAL;
@@ -927,14 +937,14 @@
}
if (!S_ISDIR(di.di_mode)) {
int hgt;
- uint64_t file_offset = 0ull;
+ uint64_t file_offset = startoff;
float human_off;
char h;
/* Now divide by how deep we are at the moment. */
/* This is how much data is represented by each */
/* indirect pointer for each height we've traversed. */
- offsets[0] = print_entry_ndx;
+ offsets[0] = pndx;
for (hgt = cur_height; hgt >= 0; hgt--)
file_offset += offsets[cur_height - hgt] *
factor[di.di_height - hgt - 1] * bufsize;
@@ -949,18 +959,40 @@
print_gfs2("(data offset 0x%llx / %lld / %6.2f%c)",
file_offset, file_offset, human_off, h);
print_gfs2(" ");
+ if (!termlines && level + 1 < di.di_height) {
+ struct iinfo *more_indir;
+ int more_ind;
+ char *tmpbuf;
+
+ more_indir = malloc(sizeof(struct iinfo));
+ tmpbuf = malloc(bufsize);
+ if (tmpbuf) {
+ do_lseek(fd,
+ ind->ii[pndx].block * bufsize);
+ do_read(fd, tmpbuf,
+ bufsize); /* read in the desired block */
+ memset(more_indir, 0, sizeof(struct iinfo));
+ more_ind = do_indirect_extended(tmpbuf,
+ more_indir);
+ display_indirect(more_indir,
+ more_ind, level + 1, file_offset);
+ free(tmpbuf);
+ }
+ free(more_indir);
+ }
+ print_entry_ndx = pndx; /* restore after recursion */
}
}
- if (indirect[print_entry_ndx].is_dir) {
+ if (ind->ii[pndx].is_dir) {
int d;
- if (indirect[print_entry_ndx].dirents > 1 &&
- indir_blocks == indirect_blocks)
+ if (ind->ii[pndx].dirents > 1 &&
+ indir_blocks == indblocks)
print_gfs2("(directory leaf with %d entries)",
- indirect[print_entry_ndx].dirents);
- for (d = 0; d < indirect[print_entry_ndx].dirents; d++) {
+ ind->ii[pndx].dirents);
+ for (d = 0; d < ind->ii[pndx].dirents; d++) {
total_dirents++;
- if (indirect[print_entry_ndx].dirents > 1) {
+ if (ind->ii[pndx].dirents > 1) {
eol(5);
if (termlines) {
if (edit_row[dmode] >=0 &&
@@ -969,19 +1001,19 @@
start_row[dmode]) {
COLORS_HIGHLIGHT;
sprintf(estring, "%"PRIx64,
- indirect[print_entry_ndx].dirent[d].block);
+ ind->ii[pndx].dirent[d].block);
strcpy(edit_fmt, "%"PRIx64);
}
}
print_gfs2("%d. (%d). %lld (0x%llx) / %lld (0x%llx): ",
total_dirents, d + 1,
- indirect[print_entry_ndx].dirent[d].dirent.de_inum.no_formal_ino,
- indirect[print_entry_ndx].dirent[d].dirent.de_inum.no_formal_ino,
- indirect[print_entry_ndx].dirent[d].block,
- indirect[print_entry_ndx].dirent[d].block);
+ ind->ii[pndx].dirent[d].dirent.de_inum.no_formal_ino,
+ ind->ii[pndx].dirent[d].dirent.de_inum.no_formal_ino,
+ ind->ii[pndx].dirent[d].block,
+ ind->ii[pndx].dirent[d].block);
}
- print_inode_type(indirect[print_entry_ndx].dirent[d].dirent.de_type);
- print_gfs2(" %s", indirect[print_entry_ndx].dirent[d].filename);
+ print_inode_type(ind->ii[pndx].dirent[d].dirent.de_type);
+ print_gfs2(" %s", ind->ii[pndx].dirent[d].filename);
if (termlines) {
if (edit_row[dmode] >= 0 &&
line - start_line - 2 == edit_row[dmode] -
@@ -995,7 +1027,7 @@
if (line >= 7) /* 7 because it was bumped at the end */
last_entry_onscreen[dmode] = line - 7;
eol(0);
- end_row[dmode] = (indirect_blocks ? indirect_blocks:indirect[0].dirents);
+ end_row[dmode] = (indblocks ? indblocks:ind->ii[0].dirents);
if (end_row[dmode] < last_entry_onscreen[dmode])
end_row[dmode] = last_entry_onscreen[dmode];
lines_per_row[dmode] = 1;
@@ -1091,14 +1123,14 @@
struct gfs2_buffer_head *tmp_bh;
/* Display any indirect pointers that we have. */
- if (display_indirect() == 0)
- return -1;
- else if (block_is_rindex()) {
+ if (block_is_rindex()) {
tmp_bh = bread(&sbd, block);
tmp_inode = inode_get(&sbd, tmp_bh);
parse_rindex(tmp_inode, TRUE);
brelse(tmp_bh, not_updated);
}
+ else if (display_indirect(indirect, indirect_blocks, 0, 0) == 0)
+ return -1;
else if (block_is_rglist()) {
tmp_bh = bread(&sbd, masterblock("rindex"));
tmp_inode = inode_get(&sbd, tmp_bh);
@@ -1218,53 +1250,54 @@
lines_per_row[dmode] = 1;
if (gfs2_struct_type == GFS2_METATYPE_SB || blk == 0x10 * (4096 / bufsize)) {
gfs2_sb_in(&sbd.sd_sb, buf); /* parse it out into the sb structure */
- memset(&indirect, 0, sizeof(indirect));
- indirect[0].block = sbd.sd_sb.sb_master_dir.no_addr;
- indirect[0].is_dir = TRUE;
- indirect[0].dirents = 2;
+ memset(indirect, 0, sizeof(indirect));
+ indirect->ii[0].block = sbd.sd_sb.sb_master_dir.no_addr;
+ indirect->ii[0].is_dir = TRUE;
+ indirect->ii[0].dirents = 2;
- memcpy(&indirect[0].dirent[0].filename, "root", 4);
- indirect[0].dirent[0].dirent.de_inum.no_formal_ino =
+ memcpy(&indirect->ii[0].dirent[0].filename, "root", 4);
+ indirect->ii[0].dirent[0].dirent.de_inum.no_formal_ino =
sbd.sd_sb.sb_root_dir.no_formal_ino;
- indirect[0].dirent[0].dirent.de_inum.no_addr =
+ indirect->ii[0].dirent[0].dirent.de_inum.no_addr =
sbd.sd_sb.sb_root_dir.no_addr;
- indirect[0].dirent[0].block = sbd.sd_sb.sb_root_dir.no_addr;
- indirect[0].dirent[0].dirent.de_type = DT_DIR;
+ indirect->ii[0].dirent[0].block = sbd.sd_sb.sb_root_dir.no_addr;
+ indirect->ii[0].dirent[0].dirent.de_type = DT_DIR;
- memcpy(&indirect[0].dirent[1].filename, "master", 7);
- indirect[0].dirent[1].dirent.de_inum.no_formal_ino =
+ memcpy(&indirect->ii[0].dirent[1].filename, "master", 7);
+ indirect->ii[0].dirent[1].dirent.de_inum.no_formal_ino =
sbd.sd_sb.sb_master_dir.no_formal_ino;
- indirect[0].dirent[1].dirent.de_inum.no_addr =
+ indirect->ii[0].dirent[1].dirent.de_inum.no_addr =
sbd.sd_sb.sb_master_dir.no_addr;
- indirect[0].dirent[1].block = sbd.sd_sb.sb_master_dir.no_addr;
- indirect[0].dirent[1].dirent.de_type = DT_DIR;
+ indirect->ii[0].dirent[1].block = sbd.sd_sb.sb_master_dir.no_addr;
+ indirect->ii[0].dirent[1].dirent.de_type = DT_DIR;
}
else if (gfs2_struct_type == GFS2_METATYPE_DI) {
gfs2_dinode_in(&di, buf); /* parse disk inode into structure */
do_dinode_extended(&di, buf); /* get extended data, if any */
}
else if (gfs2_struct_type == GFS2_METATYPE_IN) { /* indirect block list */
- do_indirect_extended(buf);
+ do_indirect_extended(buf, indirect);
}
else if (gfs2_struct_type == GFS2_METATYPE_LF) { /* directory leaf */
int x;
struct gfs2_dirent de;
indirect_blocks = 1;
- memset(&indirect, 0, sizeof(indirect));
+ memset(indirect, 0, sizeof(indirect));
/* Directory Entries: */
for (x = sizeof(struct gfs2_leaf); x < bufsize;
x += de.de_rec_len) {
gfs2_dirent_in(&de, buf + x);
if (de.de_inum.no_addr) {
- indirect[indirect_blocks].block = de.de_inum.no_addr;
- indirect[indirect_blocks].dirent[x].block = de.de_inum.no_addr;
- memcpy(&indirect[indirect_blocks].dirent[x].dirent, &de,
+ indirect->ii[indirect_blocks].block = de.de_inum.no_addr;
+ indirect->ii[indirect_blocks].dirent[x].block = de.de_inum.no_addr;
+ memcpy(&indirect->ii[indirect_blocks].dirent[x].dirent, &de,
sizeof(struct gfs2_dirent));
- memcpy(&indirect[indirect_blocks].dirent[x].filename,
+ memcpy(&indirect->ii[indirect_blocks].dirent[x].filename,
buf + x + sizeof(struct gfs2_dirent), de.de_name_len);
- indirect[indirect_blocks].is_dir = TRUE;
- indirect[indirect_blocks].dirents++;
+ indirect->ii[indirect_blocks].dirent[x].filename[de.de_name_len] = '\0';
+ indirect->ii[indirect_blocks].is_dir = TRUE;
+ indirect->ii[indirect_blocks].dirents++;
}
if (de.de_rec_len <= sizeof(struct gfs2_dirent))
break;
@@ -1535,9 +1568,11 @@
unsigned int col2;
uint64_t *b;
- col2 = edit_col[dmode] & 0x08;/* thus 0-7->0, 8-15->8 */
- b = (uint64_t *)&buf[edit_row[dmode]*16 + offset + col2];
- temp_blk=be64_to_cpu(*b);
+ if (edit_row[dmode] >= 0) {
+ col2 = edit_col[dmode] & 0x08;/* thus 0-7->0, 8-15->8 */
+ b = (uint64_t *)&buf[edit_row[dmode]*16 + offset + col2];
+ temp_blk=be64_to_cpu(*b);
+ }
}
else
sscanf(estring, "%"SCNx64, &temp_blk);/* retrieve in hex */
@@ -1977,6 +2012,10 @@
prog_name = argv[0];
+ indirect = malloc(sizeof(struct iinfo));
+ if (!indirect)
+ die("Out of memory.");
+ memset(indirect, 0, sizeof(struct iinfo));
memset(start_row, 0, sizeof(start_row));
memset(lines_per_row, 0, sizeof(lines_per_row));
memset(end_row, 0, sizeof(end_row));
@@ -2005,7 +2044,7 @@
fd = open(device, O_RDWR);
if (fd < 0)
- die("can't open %s: %s\n", argv[1], strerror(errno));
+ die("can't open %s: %s\n", device, strerror(errno));
max_block = lseek(fd, 0, SEEK_END) / bufsize;
read_superblock();
@@ -2033,5 +2072,7 @@
close(fd);
if (buf)
free(buf);
+ if (indirect)
+ free(indirect);
exit(EXIT_SUCCESS);
}
--- cluster/gfs2/edit/hexedit.h 2007/02/28 21:58:46 1.9
+++ cluster/gfs2/edit/hexedit.h 2007/07/16 23:16:35 1.10
@@ -109,6 +109,10 @@
struct gfs2_dirents dirent[64];
};
+struct iinfo {
+ struct indirect_info ii[512];
+};
+
struct gfs_indirect {
struct gfs2_meta_header in_header;
@@ -168,9 +172,8 @@
};
EXTERN struct blkstack_info blockstack[BLOCK_STACK_SIZE];
-EXTERN struct indirect_info indirect[512]; /* more than the most indirect
- pointers possible for any given
- 4K block */
+EXTERN struct iinfo *indirect; /* more than the most indirect
+ pointers possible for any given 4K block */
EXTERN struct indirect_info masterdir; /* Master directory info */
EXTERN int indirect_blocks INIT(0); /* count of indirect blocks */
EXTERN enum dsp_mode dmode INIT(HEX_MODE);
--- cluster/gfs2/edit/savemeta.c 2007/06/26 01:25:33 1.1
+++ cluster/gfs2/edit/savemeta.c 2007/07/16 23:16:35 1.2
@@ -434,7 +434,7 @@
/* checking every block kills performance. We only report */
/* every second because we don't need 100 extra messages in */
/* logs made from verbose mode. */
-void warm_fuzzy_stuff(uint64_t block, int force)
+void warm_fuzzy_stuff(uint64_t block, int force, int save)
{
static struct timeval tv;
static uint32_t seconds = 0;
@@ -451,8 +451,9 @@
percent = (block * 100) / last_fs_block;
printf("\r%" PRIu64 " blocks (%"
PRIu64 "%%) processed, ", block, percent);
- printf("%" PRIu64 " blocks (%" PRIu64 "MB) saved ",
- blks_saved, total_out / (1024*1024));
+ printf("%" PRIu64 " blocks (%" PRIu64 "MB) %s ",
+ blks_saved, total_out / (1024*1024),
+ save?"saved":"restored");
fflush(stdout);
}
}
@@ -464,7 +465,7 @@
uint16_t trailing0;
char *p;
- warm_fuzzy_stuff(blk, FALSE);
+ warm_fuzzy_stuff(blk, FALSE, TRUE);
memset(savedata, 0, sizeof(struct saved_metablock));
do_lseek(fd, blk * bufsize);
do_read(fd, savedata->buf, bufsize); /* read in the block */
@@ -605,7 +606,7 @@
/* There may be a gap between end of file system and end of device */
/* so we tell the user that we've processed everything. */
blk = last_fs_block;
- warm_fuzzy_stuff(blk, TRUE);
+ warm_fuzzy_stuff(blk, TRUE, TRUE);
printf("\nMetadata saved to file %s.\n", out_fn);
free(savedata);
close(out_fd);
@@ -622,6 +623,8 @@
uint64_t max_fs_size;
do_lseek(fd, 0);
+ blks_saved = 0;
+ total_out = 0;
while (TRUE) {
memset(savedata, 0, sizeof(struct saved_metablock));
rs = read(in_fd, &buf64, sizeof(uint64_t));
@@ -643,12 +646,22 @@
}
rs = read(in_fd, &buf16, sizeof(uint16_t));
savedata->siglen = be16_to_cpu(buf16);
+ total_out += rs + savedata->siglen;
if (savedata->siglen > 0 &&
savedata->siglen <= sizeof(savedata->buf)) {
do_read(in_fd, savedata->buf, savedata->siglen);
if (first) {
gfs2_sb_in(&sbd.sd_sb, savedata->buf);
- if (check_sb(&sbd.sd_sb)) {
+ sbd1 = (struct gfs_sb *)&sbd.sd_sb;
+ if (sbd1->sb_fs_format == GFS_FORMAT_FS &&
+ sbd1->sb_header.mh_type ==
+ GFS_METATYPE_SB &&
+ sbd1->sb_header.mh_format ==
+ GFS_FORMAT_SB &&
+ sbd1->sb_multihost_format ==
+ GFS_FORMAT_MULTI)
+ ;
+ else if (check_sb(&sbd.sd_sb)) {
fprintf(stderr,"Error: Invalid superblock data.\n");
return -1;
}
@@ -656,19 +669,28 @@
last_fs_block =
lseek(fd, 0, SEEK_END) / bufsize;
printf("There are %" PRIu64 " blocks of %" \
- PRIu64 "bytes in the destination file" \
- " system.\n\n", last_fs_block, bufsize);
+ PRIu64 " bytes in the destination" \
+ " file system.\n\n",
+ last_fs_block, bufsize);
first = 0;
}
+ warm_fuzzy_stuff(savedata->blk, FALSE, FALSE);
+ if (savedata->blk >= last_fs_block) {
+ printf("Out of space on the destination "
+ "device; quitting.\n");
+ break;
+ }
do_lseek(fd, savedata->blk * bufsize);
do_write(fd, savedata->buf, bufsize);
writes++;
+ blks_saved++;
} else {
fprintf(stderr, "Bad record length: %d for #%"
PRIu64".\n", savedata->siglen, savedata->blk);
return -1;
}
}
+ warm_fuzzy_stuff(savedata->blk, TRUE, FALSE);
printf("%" PRIu64 " blocks restored.\n", writes);
return 0;
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2007-07-16 23:16 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-07-16 23:16 [Cluster-devel] cluster/gfs2/edit gfs2hex.c hexedit.c hexedit. rpeterso
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.