[Cluster-devel] cluster/gfs2/edit gfs2hex.c hexedit.c hexedit. ...
rpeterso at sourceware.org
rpeterso at sourceware.org
Mon Jul 16 23:16:36 UTC 2007
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;
}
More information about the Cluster-devel
mailing list