[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