cluster-devel.redhat.com archive mirror
 help / color / mirror / Atom feed
* [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems
@ 2012-01-20 15:09 rpeterso
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 01/66] fsck.gfs2: Make functions use sdp rather than sbp rpeterso
                   ` (65 more replies)
  0 siblings, 66 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:09 UTC (permalink / raw)
  To: cluster-devel.redhat.com

This big set of 66 patches are cross-written from upstream to RHEL6.
It allows RHEL6's fsck.gfs2 to operate on GFS1 file systems.
There are many reasons to do that. This is for bugzilla #675723.

Regards,

Bob Peterson
Red Hat File Systems

[PATCH 01/66] fsck.gfs2: Make functions use sdp rather than sbp
[PATCH 02/66] fsck.gfs2: Change "if(" to "if ("
[PATCH 03/66] libgfs1: Add gfs1 variable to superblock structure
[PATCH 04/66] libgfs2: Make check_sb and read_sb operate on gfs1
[PATCH 05/66] libgfs2: move gfs1 structures to libgfs2
[PATCH 06/66] fsck.gfs2: Check for blocks wrongly inside resource
[PATCH 07/66] fsck.gfs2: Rename check_leaf to check_ealeaf_block
[PATCH 08/66] fsck.gfs2: fsck.gfs2: Delete vestigial buffer_head in
[PATCH 09/66] fsck.gfs2: fsck.gfs2: Rename nlink functions to be
[PATCH 10/66] fsck.gfs2: fsck.gfs2: Sync di_nlink adding links for
[PATCH 11/66] fsck.gfs2: fsck.gfs2: Make dir entry count 32 bits
[PATCH 12/66] fsck.gfs2: get rid of triple negative logic
[PATCH 13/66] dirent_repair needs to mark the buffer as modified
[PATCH 14/66] fsck.gfs2: fsck.gfs2: Ask to reclaim unlinked meta
[PATCH 15/66] fsck.gfs2: fsck.gfs2: Refactor add_dotdot function in
[PATCH 16/66] libgfs2: libgfs2: Use __FUNCTION__ rather than
[PATCH 17/66] fsck.gfs2: fsck.gfs2: Don't stop invalidating blocks
[PATCH 18/66] fsck.gfs2: fsck.gfs2: Find and clear duplicate leaf
[PATCH 19/66] fsck.gfs2: fsck.gfs2: Move check_num_ptrs from
[PATCH 20/66] fsck.gfs2: fsck.gfs2: Duplicate ref processing for
[PATCH 21/66] fsck.gfs2: fsck.gfs2: split check_leaf_blks to be more
[PATCH 22/66] fsck.gfs2: Shorten output
[PATCH 23/66] fsck.gfs2: Make output messages more sensible
[PATCH 24/66] fsck.gfs pass2: Refactor function set_dotdot_dir
[PATCH 25/66] fsck.gfs2 pass2: Delete extended attributes with inode
[PATCH 26/66] fsck.gfs2 pass2: Don't delete invalid inode metadata
[PATCH 27/66] fsck.gfs2 pass3: Refactor mark_and_return_parent
[PATCH 28/66] fsck.gfs2: misc cosmetic changes
[PATCH 29/66] fsck.gfs2: Don't use old_leaf if it was a duplicate
[PATCH 30/66] fsck.gfs2: Add find_remove_dup, free_block_if_notdup
[PATCH 31/66] fsck.gfs2: don't free prev rgrp list repairing rgrps
[PATCH 32/66] libgfs2: eliminate gfs1_readi in favor of gfs2_readi
[PATCH 33/66] libgfs2: Mark buffer modified adding a new GFS1 block
[PATCH 34/66] libgfs2: Use dinode buffer to map gfs1 dinode blocks
[PATCH 35/66] libgfs2: move block_map functions to fsck.gfs2
[PATCH 36/66] libgfs2: eliminate gfs1_rindex_read
[PATCH 37/66] libgfs2: combine ri_update and gfs1_ri_update
[PATCH 38/66] libgfs2: combine gfs_inode_read and gfs_inode_get
[PATCH 39/66] libgfs2: move gfs1 functions from edit to libgfs2
[PATCH 40/66] gfs2_edit savemeta: save_inode_data backward for gfs1
[PATCH 41/66] libgfs2: expand capabilities to operate on gfs1
[PATCH 42/66] fsck.gfs2: Combine block and char device inode types
[PATCH 43/66] fsck.gfs2: four-step duplicate elimination process
[PATCH 44/66] fsck.gfs2: Add ability to check gfs1 file systems
[PATCH 45/66] fsck.gfs2: Remove bad inodes from duplicate tree
[PATCH 46/66] fsck.gfs2: Handle duplicate reference to dinode blocks
[PATCH 47/66] fsck.gfs2: Bad extended attributes not deleted
[PATCH 48/66] libgfs2: Make rebuild functions not re-read ip
[PATCH 49/66] fsck.gfs2: Shorten debug output
[PATCH 50/66] fsck.gfs2: Increment link count reporting wrong dinode
[PATCH 51/66] fsck.gfs2: system dinodes take priority over user
[PATCH 52/66] fsck.gfs2: Recognize partially gfs2-converted dinodes
[PATCH 53/66] fsck.gfs2: Print step 2 duplicate debug msg first
[PATCH 54/66] fsck.gfs2: pass1c counts percentage backward
[PATCH 55/66] fsck.gfs2: Speed up rangecheck functions
[PATCH 56/66] libgfs2: Make in-core rgrps use rbtree
[PATCH 57/66] fsck.gfs2: Fix memory leaks
[PATCH 58/66] Change man pages and gfs2_convert messages to include
[PATCH 59/66] gfs2_edit: Fix memory leaks
[PATCH 60/66] fsck.gfs2: Journals not properly checked
[PATCH 61/66] fsck.gfs2: Rearrange block types to group all inode
[PATCH 62/66] fsck.gfs2: Fix initialization error return codes
[PATCH 63/66] fsck.gfs2: Don't use strerror for libgfs2 errors
[PATCH 64/66] fsck.gfs2: Fix memory leak in initialize.c
[PATCH 65/66] fsck.gfs2: Add return code checks and initializations
[PATCH 66/66] libgfs2: Fix null pointer dereference in



^ permalink raw reply	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 01/66] fsck.gfs2: Make functions use sdp rather than sbp
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
@ 2012-01-20 15:09 ` rpeterso
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 02/66] fsck.gfs2: Change "if(" to "if (" rpeterso
                   ` (64 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:09 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

For years, the fsck.gfs2 tool used two different variable names to refer to the
same structure: sdp and sbp.  This patch changes them all to sdp so they are now
consistent with the kernel code.

rhbz#675723
---
 gfs2/fsck/fsck.h       |   20 ++++++------
 gfs2/fsck/initialize.c |   84 ++++++++++++++++++++++++------------------------
 gfs2/fsck/main.c       |   50 ++++++++++++++--------------
 gfs2/fsck/metawalk.c   |   30 +++++++++--------
 gfs2/fsck/metawalk.h   |    4 +-
 gfs2/fsck/pass1.c      |   18 +++++-----
 gfs2/fsck/pass1b.c     |   37 ++++++++++-----------
 gfs2/fsck/pass1c.c     |   31 +++++++++--------
 gfs2/fsck/pass2.c      |   68 ++++++++++++++++++++-------------------
 gfs2/fsck/pass3.c      |   50 +++++++++++++++-------------
 gfs2/fsck/pass4.c      |   21 ++++++------
 gfs2/fsck/pass5.c      |   22 ++++++------
 12 files changed, 221 insertions(+), 214 deletions(-)

diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h
index bc14b88..25bc3b9 100644
--- a/gfs2/fsck/fsck.h
+++ b/gfs2/fsck/fsck.h
@@ -92,21 +92,21 @@ enum rgindex_trust_level { /* how far can we trust our RG index? */
 			   must have been converted from gfs2_convert. */
 };
 
-extern struct gfs2_inode *fsck_load_inode(struct gfs2_sbd *sbp, uint64_t block);
+extern struct gfs2_inode *fsck_load_inode(struct gfs2_sbd *sdp, uint64_t block);
 extern struct gfs2_inode *fsck_inode_get(struct gfs2_sbd *sdp,
 				  struct gfs2_buffer_head *bh);
 extern void fsck_inode_put(struct gfs2_inode **ip);
 
-extern int initialize(struct gfs2_sbd *sbp, int force_check, int preen,
+extern int initialize(struct gfs2_sbd *sdp, int force_check, int preen,
 		      int *all_clean);
-extern void destroy(struct gfs2_sbd *sbp);
-extern int pass1(struct gfs2_sbd *sbp);
-extern int pass1b(struct gfs2_sbd *sbp);
-extern int pass1c(struct gfs2_sbd *sbp);
-extern int pass2(struct gfs2_sbd *sbp);
-extern int pass3(struct gfs2_sbd *sbp);
-extern int pass4(struct gfs2_sbd *sbp);
-extern int pass5(struct gfs2_sbd *sbp);
+extern void destroy(struct gfs2_sbd *sdp);
+extern int pass1(struct gfs2_sbd *sdp);
+extern int pass1b(struct gfs2_sbd *sdp);
+extern int pass1c(struct gfs2_sbd *sdp);
+extern int pass2(struct gfs2_sbd *sdp);
+extern int pass3(struct gfs2_sbd *sdp);
+extern int pass4(struct gfs2_sbd *sdp);
+extern int pass5(struct gfs2_sbd *sdp);
 extern int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count,
 		     int *sane);
 extern void gfs2_dup_free(void);
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 5a6fc6e..ff620c0 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -36,26 +36,26 @@ static struct master_dir fix_md;
  * Change the lock protocol so nobody can mount the fs
  *
  */
-static int block_mounters(struct gfs2_sbd *sbp, int block_em)
+static int block_mounters(struct gfs2_sbd *sdp, int block_em)
 {
 	if(block_em) {
 		/* verify it starts with lock_ */
-		if(!strncmp(sbp->sd_sb.sb_lockproto, "lock_", 5)) {
+		if(!strncmp(sdp->sd_sb.sb_lockproto, "lock_", 5)) {
 			/* Change lock_ to fsck_ */
-			memcpy(sbp->sd_sb.sb_lockproto, "fsck_", 5);
+			memcpy(sdp->sd_sb.sb_lockproto, "fsck_", 5);
 		}
 		/* FIXME: Need to do other verification in the else
 		 * case */
 	} else {
 		/* verify it starts with fsck_ */
 		/* verify it starts with lock_ */
-		if(!strncmp(sbp->sd_sb.sb_lockproto, "fsck_", 5)) {
+		if(!strncmp(sdp->sd_sb.sb_lockproto, "fsck_", 5)) {
 			/* Change fsck_ to lock_ */
-			memcpy(sbp->sd_sb.sb_lockproto, "lock_", 5);
+			memcpy(sdp->sd_sb.sb_lockproto, "lock_", 5);
 		}
 	}
 
-	if(write_sb(sbp)) {
+	if(write_sb(sdp)) {
 		stack;
 		return -1;
 	}
@@ -1093,7 +1093,7 @@ static int fill_super_block(struct gfs2_sbd *sdp)
  * initialize - initialize superblock pointer
  *
  */
-int initialize(struct gfs2_sbd *sbp, int force_check, int preen,
+int initialize(struct gfs2_sbd *sdp, int force_check, int preen,
 	       int *all_clean)
 {
 	int clean_journals = 0, open_flag;
@@ -1105,8 +1105,8 @@ int initialize(struct gfs2_sbd *sbp, int force_check, int preen,
 	else
 		open_flag = O_RDWR | O_EXCL;
 
-	sbp->device_fd = open(opts.device, open_flag);
-	if (sbp->device_fd < 0) {
+	sdp->device_fd = open(opts.device, open_flag);
+	if (sdp->device_fd < 0) {
 		int is_mounted, ro;
 
 		if (open_flag == O_RDONLY || errno != EBUSY) {
@@ -1120,10 +1120,10 @@ int initialize(struct gfs2_sbd *sbp, int force_check, int preen,
 		   allow it.)  We use is_pathname_mounted here even though
 		   we're specifying a device name, not a path name.  The
 		   function checks for device as well. */
-		strncpy(sbp->device_name, opts.device,
-			sizeof(sbp->device_name));
-		sbp->path_name = sbp->device_name; /* This gets overwritten */
-		is_mounted = is_pathname_mounted(sbp, &ro);
+		strncpy(sdp->device_name, opts.device,
+			sizeof(sdp->device_name));
+		sdp->path_name = sdp->device_name; /* This gets overwritten */
+		is_mounted = is_pathname_mounted(sdp, &ro);
 		/* If the device is busy, but not because it's mounted, fail.
 		   This protects against cases where the file system is LVM
 		   and perhaps mounted on a different node. */
@@ -1138,49 +1138,49 @@ int initialize(struct gfs2_sbd *sbp, int force_check, int preen,
 		/* The device is mounted RO, so it's likely our own root
 		   file system.  We can only do so much to protect the users
 		   from themselves.  Try opening without O_EXCL. */
-		if ((sbp->device_fd = open(opts.device, O_RDWR)) < 0)
+		if ((sdp->device_fd = open(opts.device, O_RDWR)) < 0)
 			goto mount_fail;
 
 		was_mounted_ro = 1;
 	}
 
 	/* read in sb from disk */
-	if (fill_super_block(sbp))
+	if (fill_super_block(sdp))
 		return FSCK_ERROR;
 
 	/* Change lock protocol to be fsck_* instead of lock_* */
-	if(!opts.no && preen_is_safe(sbp, preen, force_check)) {
-		if(block_mounters(sbp, 1)) {
+	if(!opts.no && preen_is_safe(sdp, preen, force_check)) {
+		if(block_mounters(sdp, 1)) {
 			log_err( _("Unable to block other mounters\n"));
 			return FSCK_USAGE;
 		}
 	}
 
 	/* Get master dinode */
-	sbp->master_dir = inode_read(sbp, sbp->sd_sb.sb_master_dir.no_addr);
-	if (sbp->master_dir->i_di.di_header.mh_magic != GFS2_MAGIC ||
-	    sbp->master_dir->i_di.di_header.mh_type != GFS2_METATYPE_DI ||
-	    !sbp->master_dir->i_di.di_size) {
-		inode_put(&sbp->master_dir);
-		rebuild_master(sbp);
-		sbp->master_dir = inode_read(sbp,
-					     sbp->sd_sb.sb_master_dir.no_addr);
+	sdp->master_dir = inode_read(sdp, sdp->sd_sb.sb_master_dir.no_addr);
+	if (sdp->master_dir->i_di.di_header.mh_magic != GFS2_MAGIC ||
+	    sdp->master_dir->i_di.di_header.mh_type != GFS2_METATYPE_DI ||
+	    !sdp->master_dir->i_di.di_size) {
+		inode_put(&sdp->master_dir);
+		rebuild_master(sdp);
+		sdp->master_dir = inode_read(sdp,
+					     sdp->sd_sb.sb_master_dir.no_addr);
 	}
 
 	/* Look up the "per_node" inode.  If there are journals missing, we
 	   need to figure out what's missing from per_node. And we need all
 	   our journals to be there before we can replay them. */
-	lookup_per_node(sbp, 0);
+	lookup_per_node(sdp, 0);
 
 	/* verify various things */
 
-	if(replay_journals(sbp, preen, force_check, &clean_journals)) {
-		if(!opts.no && preen_is_safe(sbp, preen, force_check))
-			block_mounters(sbp, 0);
+	if(replay_journals(sdp, preen, force_check, &clean_journals)) {
+		if(!opts.no && preen_is_safe(sdp, preen, force_check))
+			block_mounters(sdp, 0);
 		stack;
 		return FSCK_ERROR;
 	}
-	if (sbp->md.journals == clean_journals)
+	if (sdp->md.journals == clean_journals)
 		*all_clean = 1;
 	else {
 		if (force_check || !preen)
@@ -1190,7 +1190,7 @@ int initialize(struct gfs2_sbd *sbp, int force_check, int preen,
 	if (!force_check && *all_clean && preen)
 		return FSCK_OK;
 
-	if (init_system_inodes(sbp))
+	if (init_system_inodes(sdp))
 		return FSCK_ERROR;
 
 	return FSCK_OK;
@@ -1200,30 +1200,30 @@ mount_fail:
 	return FSCK_USAGE;
 }
 
-static void destroy_sbp(struct gfs2_sbd *sbp)
+static void destroy_sdp(struct gfs2_sbd *sdp)
 {
 	if(!opts.no) {
-		if(block_mounters(sbp, 0)) {
+		if(block_mounters(sdp, 0)) {
 			log_warn( _("Unable to unblock other mounters - manual intervention required\n"));
 			log_warn( _("Use 'gfs2_tool sb <device> proto' to fix\n"));
 		}
 		log_info( _("Syncing the device.\n"));
-		fsync(sbp->device_fd);
+		fsync(sdp->device_fd);
 	}
-	empty_super_block(sbp);
-	close(sbp->device_fd);
+	empty_super_block(sdp);
+	close(sdp->device_fd);
 	if (was_mounted_ro && errors_corrected) {
-		sbp->device_fd = open("/proc/sys/vm/drop_caches", O_WRONLY);
-		if (sbp->device_fd >= 0) {
-			write(sbp->device_fd, "2", 1);
-			close(sbp->device_fd);
+		sdp->device_fd = open("/proc/sys/vm/drop_caches", O_WRONLY);
+		if (sdp->device_fd >= 0) {
+			write(sdp->device_fd, "2", 1);
+			close(sdp->device_fd);
 		} else
 			log_err( _("fsck.gfs2: Non-fatal error dropping "
 				   "caches.\n"));
 	}
 }
 
-void destroy(struct gfs2_sbd *sbp)
+void destroy(struct gfs2_sbd *sdp)
 {
-	destroy_sbp(sbp);
+	destroy_sdp(sdp);
 }
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index c68e3da..a50a0d7 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -216,7 +216,7 @@ static void check_statfs(struct gfs2_sbd *sdp)
 int main(int argc, char **argv)
 {
 	struct gfs2_sbd sb;
-	struct gfs2_sbd *sbp = &sb;
+	struct gfs2_sbd *sdp = &sb;
 	int j;
 	int error = 0;
 	int all_clean = 0;
@@ -224,18 +224,18 @@ int main(int argc, char **argv)
 	setlocale(LC_ALL, "");
 	textdomain("gfs2-utils");
 
-	memset(sbp, 0, sizeof(*sbp));
+	memset(sdp, 0, sizeof(*sdp));
 
 	if((error = read_cmdline(argc, argv, &opts)))
 		exit(error);
 	setbuf(stdout, NULL);
 	log_notice( _("Initializing fsck\n"));
-	if ((error = initialize(sbp, force_check, preen, &all_clean)))
+	if ((error = initialize(sdp, force_check, preen, &all_clean)))
 		exit(error);
 
 	if (!force_check && all_clean && preen) {
 		log_err( _("%s: clean.\n"), opts.device);
-		destroy(sbp);
+		destroy(sdp);
 		exit(FSCK_OK);
 	}
 
@@ -243,7 +243,7 @@ int main(int argc, char **argv)
 	log_notice( _("Starting pass1\n"));
 	pass = "pass 1";
 	last_reported_block = 0;
-	if ((error = pass1(sbp)))
+	if ((error = pass1(sdp)))
 		exit(error);
 	if (skip_this_pass || fsck_abort) {
 		skip_this_pass = FALSE;
@@ -256,7 +256,7 @@ int main(int argc, char **argv)
 		last_reported_block = 0;
 		pass = "pass 1b";
 		log_notice( _("Starting pass1b\n"));
-		if((error = pass1b(sbp)))
+		if((error = pass1b(sdp)))
 			exit(error);
 		if (skip_this_pass || fsck_abort) {
 			skip_this_pass = FALSE;
@@ -269,7 +269,7 @@ int main(int argc, char **argv)
 		last_reported_block = 0;
 		pass = "pass 1c";
 		log_notice( _("Starting pass1c\n"));
-		if((error = pass1c(sbp)))
+		if((error = pass1c(sdp)))
 			exit(error);
 		if (skip_this_pass || fsck_abort) {
 			skip_this_pass = FALSE;
@@ -282,7 +282,7 @@ int main(int argc, char **argv)
 		last_reported_block = 0;
 		pass = "pass 2";
 		log_notice( _("Starting pass2\n"));
-		if ((error = pass2(sbp)))
+		if ((error = pass2(sdp)))
 			exit(error);
 		if (skip_this_pass || fsck_abort) {
 			skip_this_pass = FALSE;
@@ -295,7 +295,7 @@ int main(int argc, char **argv)
 		last_reported_block = 0;
 		pass = "pass 3";
 		log_notice( _("Starting pass3\n"));
-		if ((error = pass3(sbp)))
+		if ((error = pass3(sdp)))
 			exit(error);
 		if (skip_this_pass || fsck_abort) {
 			skip_this_pass = FALSE;
@@ -308,7 +308,7 @@ int main(int argc, char **argv)
 		last_reported_block = 0;
 		pass = "pass 4";
 		log_notice( _("Starting pass4\n"));
-		if ((error = pass4(sbp)))
+		if ((error = pass4(sdp)))
 			exit(error);
 		if (skip_this_pass || fsck_abort) {
 			skip_this_pass = FALSE;
@@ -321,7 +321,7 @@ int main(int argc, char **argv)
 		last_reported_block = 0;
 		pass = "pass 5";
 		log_notice( _("Starting pass5\n"));
-		if ((error = pass5(sbp)))
+		if ((error = pass5(sdp)))
 			exit(error);
 		if (skip_this_pass || fsck_abort) {
 			skip_this_pass = FALSE;
@@ -335,27 +335,27 @@ int main(int argc, char **argv)
 	}
 
 	if (!fsck_abort)
-		check_statfs(sbp);
+		check_statfs(sdp);
 
 	/* Free up our system inodes */
-	inode_put(&sbp->md.inum);
-	inode_put(&sbp->md.statfs);
-	for (j = 0; j < sbp->md.journals; j++)
-		inode_put(&sbp->md.journal[j]);
-	inode_put(&sbp->md.jiinode);
-	inode_put(&sbp->md.riinode);
-	inode_put(&sbp->md.qinode);
-	inode_put(&sbp->md.pinode);
-	inode_put(&sbp->md.rooti);
-	inode_put(&sbp->master_dir);
+	inode_put(&sdp->md.inum);
+	inode_put(&sdp->md.statfs);
+	for (j = 0; j < sdp->md.journals; j++)
+		inode_put(&sdp->md.journal[j]);
+	inode_put(&sdp->md.jiinode);
+	inode_put(&sdp->md.riinode);
+	inode_put(&sdp->md.qinode);
+	inode_put(&sdp->md.pinode);
+	inode_put(&sdp->md.rooti);
+	inode_put(&sdp->master_dir);
 	if (lf_dip)
 		inode_put(&lf_dip);
 
 	if (!opts.no && errors_corrected)
 		log_notice( _("Writing changes to disk\n"));
-	fsync(sbp->device_fd);
-	destroy(sbp);
-	log_notice( _("gfs2_fsck complete    \n"));
+	fsync(sdp->device_fd);
+	destroy(sdp);
+	log_notice( _("gfs2_fsck complete\n"));
 
 	if (!error) {
 		if (!errors_found)
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index cffff8a..0e443fa 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -181,14 +181,14 @@ struct gfs2_inode *fsck_system_inode(struct gfs2_sbd *sdp, uint64_t block)
 
 /* fsck_load_inode - same as gfs2_load_inode() in libgfs2 but system inodes
    get special treatment. */
-struct gfs2_inode *fsck_load_inode(struct gfs2_sbd *sbp, uint64_t block)
+struct gfs2_inode *fsck_load_inode(struct gfs2_sbd *sdp, uint64_t block)
 {
 	struct gfs2_inode *ip = NULL;
 
-	ip = fsck_system_inode(sbp, block);
+	ip = fsck_system_inode(sdp, block);
 	if (ip)
 		return ip;
-	return inode_read(sbp, block);
+	return inode_read(sdp, block);
 }
 
 /* fsck_inode_get - same as inode_get() in libgfs2 but system inodes
@@ -596,7 +596,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 	uint64_t first_ok_leaf;
 	struct gfs2_buffer_head *lbh;
 	int lindex;
-	struct gfs2_sbd *sbp = ip->i_sbd;
+	struct gfs2_sbd *sdp = ip->i_sbd;
 	uint16_t count;
 	int ref_count = 0, exp_count = 0;
 
@@ -607,7 +607,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 	for(lindex = 0; lindex < (1 << ip->i_di.di_depth); lindex++) {
 		gfs2_get_leaf_nr(ip, lindex, &leaf_no);
 		if (gfs2_check_range(ip->i_sbd, leaf_no) == 0) {
-			lbh = bread(sbp, leaf_no);
+			lbh = bread(sdp, leaf_no);
 			/* Make sure it's really a valid leaf block. */
 			if (gfs2_check_meta(lbh, GFS2_METATYPE_LF) == 0) {
 				brelse(lbh);
@@ -674,7 +674,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 			}
 
 			/* Try to read in the leaf block. */
-			lbh = bread(sbp, leaf_no);
+			lbh = bread(sdp, leaf_no);
 			/* Make sure it's really a valid leaf block. */
 			if (gfs2_check_meta(lbh, GFS2_METATYPE_LF)) {
 				warn_and_patch(ip, &leaf_no, &bad_leaf,
@@ -738,7 +738,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 
 				if(count != leaf.lf_entries) {
 					brelse(lbh);
-					lbh = bread(sbp, leaf_no);
+					lbh = bread(sdp, leaf_no);
 					gfs2_leaf_in(&leaf, lbh);
 
 					log_err( _("Leaf %llu (0x%llx) entry "
@@ -1383,12 +1383,12 @@ int check_linear_dir(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
 	return error;
 }
 
-int check_dir(struct gfs2_sbd *sbp, uint64_t block, struct metawalk_fxns *pass)
+int check_dir(struct gfs2_sbd *sdp, uint64_t block, struct metawalk_fxns *pass)
 {
 	struct gfs2_inode *ip;
 	int error = 0;
 
-	ip = fsck_load_inode(sbp, block);
+	ip = fsck_load_inode(sdp, block);
 
 	if(ip->i_di.di_flags & GFS2_DIF_EXHASH)
 		error = check_leaf_blks(ip, pass);
@@ -1425,16 +1425,18 @@ static int remove_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 
 }
 
-int remove_dentry_from_dir(struct gfs2_sbd *sbp, uint64_t dir,
+int remove_dentry_from_dir(struct gfs2_sbd *sdp, uint64_t dir,
 			   uint64_t dentryblock)
 {
 	struct metawalk_fxns remove_dentry_fxns = {0};
 	uint8_t q;
 	int error;
 
-	log_debug( _("Removing dentry %" PRIu64 " (0x%" PRIx64 ") from directory %"
-			  PRIu64" (0x%" PRIx64 ")\n"), dentryblock, dentryblock, dir, dir);
-	if(gfs2_check_range(sbp, dir)) {
+	log_debug( _("Removing dentry %llu (0x%llx) from directory %llu"
+		     " (0x%llx)\n"), (unsigned long long)dentryblock,
+		  (unsigned long long)dentryblock,
+		  (unsigned long long)dir, (unsigned long long)dir);
+	if(gfs2_check_range(sdp, dir)) {
 		log_err( _("Parent directory out of range\n"));
 		return 1;
 	}
@@ -1448,7 +1450,7 @@ int remove_dentry_from_dir(struct gfs2_sbd *sbp, uint64_t dir,
 	}
 	/* Need to run check_dir with a private var of dentryblock,
 	 * and fxns that remove that dentry if found */
-	error = check_dir(sbp, dir, &remove_dentry_fxns);
+	error = check_dir(sdp, dir, &remove_dentry_fxns);
 
 	return error;
 }
diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h
index 3ee12fe..c1e61fb 100644
--- a/gfs2/fsck/metawalk.h
+++ b/gfs2/fsck/metawalk.h
@@ -9,11 +9,11 @@ struct metawalk_fxns;
 extern int check_inode_eattr(struct gfs2_inode *ip,
 			     struct metawalk_fxns *pass);
 extern int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass);
-extern int check_dir(struct gfs2_sbd *sbp, uint64_t block,
+extern int check_dir(struct gfs2_sbd *sdp, uint64_t block,
 		     struct metawalk_fxns *pass);
 extern int check_linear_dir(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
 			    struct metawalk_fxns *pass);
-extern int remove_dentry_from_dir(struct gfs2_sbd *sbp, uint64_t dir,
+extern int remove_dentry_from_dir(struct gfs2_sbd *sdp, uint64_t dir,
 						   uint64_t dentryblock);
 extern int delete_block(struct gfs2_inode *ip, uint64_t block,
 		 struct gfs2_buffer_head **bh, const char *btype,
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index a7eb96d..ef2714f 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -1187,7 +1187,7 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh)
 static int check_system_inode(struct gfs2_sbd *sdp,
 			      struct gfs2_inode **sysinode,
 			      const char *filename,
-			      int builder(struct gfs2_sbd *sbp),
+			      int builder(struct gfs2_sbd *sdp),
 			      enum gfs2_mark_block mark)
 {
 	uint64_t iblock = 0;
@@ -1375,7 +1375,7 @@ static int check_system_inodes(struct gfs2_sbd *sdp)
  * inodes size
  * dir info
  */
-int pass1(struct gfs2_sbd *sbp)
+int pass1(struct gfs2_sbd *sdp)
 {
 	struct gfs2_buffer_head *bh;
 	osi_list_t *tmp;
@@ -1394,7 +1394,7 @@ int pass1(struct gfs2_sbd *sbp)
 	 * the sweeps start that we won't find otherwise? */
 
 	/* Make sure the system inodes are okay & represented in the bitmap. */
-	check_system_inodes(sbp);
+	check_system_inodes(sdp);
 
 	/* So, do we do a depth first search starting at the root
 	 * inode, or use the rg bitmaps, or just read every fs block
@@ -1405,7 +1405,7 @@ int pass1(struct gfs2_sbd *sbp)
 	 * uses the rg bitmaps, so maybe that's the best way to start
 	 * things - we can change the method later if necessary.
 	 */
-	for (tmp = sbp->rglist.next; tmp != &sbp->rglist;
+	for (tmp = sdp->rglist.next; tmp != &sdp->rglist;
 	     tmp = tmp->next, rg_count++) {
 		log_debug( _("Checking metadata in Resource Group #%" PRIu64 "\n"),
 				 rg_count);
@@ -1421,7 +1421,7 @@ int pass1(struct gfs2_sbd *sbp)
 			}
 			/* rgrps and bitmaps don't have bits to represent
 			   their blocks, so don't do this:
-			check_n_fix_bitmap(sbp, rgd->ri.ri_addr + i,
+			check_n_fix_bitmap(sdp, rgd->ri.ri_addr + i,
 			gfs2_meta_rgrp);*/
 		}
 
@@ -1444,7 +1444,7 @@ int pass1(struct gfs2_sbd *sbp)
 				skip_this_pass = FALSE;
 				fflush(stdout);
 			}
-			if (fsck_system_inode(sbp, block)) {
+			if (fsck_system_inode(sdp, block)) {
 				log_debug(_("Already processed system inode "
 					    "%lld (0x%llx)\n"),
 					  (unsigned long long)block,
@@ -1452,7 +1452,7 @@ int pass1(struct gfs2_sbd *sbp)
 				first = 0;
 				continue;
 			}
-			bh = bread(sbp, block);
+			bh = bread(sdp, block);
 
 			/*log_debug( _("Checking metadata block #%" PRIu64
 			  " (0x%" PRIx64 ")\n"), block, block);*/
@@ -1468,9 +1468,9 @@ int pass1(struct gfs2_sbd *sbp)
 					brelse(bh);
 					return FSCK_ERROR;
 				}
-				check_n_fix_bitmap(sbp, block,
+				check_n_fix_bitmap(sdp, block,
 						   gfs2_block_free);
-			} else if (handle_di(sbp, bh) < 0) {
+			} else if (handle_di(sdp, bh) < 0) {
 				stack;
 				brelse(bh);
 				return FSCK_ERROR;
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index 7f79783..01d479c 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -88,12 +88,12 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block,
 			     uint64_t parent, struct gfs2_buffer_head **bh,
 			     void *private)
 {
-	struct gfs2_sbd *sbp = ip->i_sbd;
+	struct gfs2_sbd *sdp = ip->i_sbd;
 	int error;
 
 	error = add_duplicate_ref(ip, block, ref_as_ea, 1, INODE_VALID);
 	if (!error)
-		*bh = bread(sbp, block);
+		*bh = bread(sdp, block);
 
 	return error;
 }
@@ -102,12 +102,12 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
 			    uint64_t parent, struct gfs2_buffer_head **bh,
 			    void *private)
 {
-	struct gfs2_sbd *sbp = ip->i_sbd;
+	struct gfs2_sbd *sdp = ip->i_sbd;
 	int error;
 
 	error = add_duplicate_ref(ip, block, ref_as_ea, 1, INODE_VALID);
 	if (!error)
-		*bh = bread(sbp, block);
+		*bh = bread(sdp, block);
 	return error;
 }
 
@@ -318,15 +318,12 @@ static int clear_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr,
 }
 
 /* Finds all references to duplicate blocks in the metadata */
-static int find_block_ref(struct gfs2_sbd *sbp, uint64_t inode)
+static int find_block_ref(struct gfs2_sbd *sdp, uint64_t inode)
 {
 	struct gfs2_inode *ip;
 	int error = 0;
 
-	ip = fsck_load_inode(sbp, inode); /* bread, inode_get */
-	/*log_debug( _("Checking inode %" PRIu64 " (0x%" PRIx64 ")'s "
-		     "metatree for references to duplicate blocks)\n"),
-		     inode, inode);*/
+	ip = fsck_load_inode(sdp, inode); /* bread, inode_get */
 	/* double-check the meta header just to be sure it's metadata */
 	if (ip->i_di.di_header.mh_magic != GFS2_MAGIC ||
 	    ip->i_di.di_header.mh_type != GFS2_METATYPE_DI) {
@@ -386,7 +383,7 @@ static void log_inode_reference(struct duptree *b, osi_list_t *tmp, int inval)
 		  (unsigned long long)b->block, reftypestring);
 }
 
-static int clear_a_reference(struct gfs2_sbd *sbp, struct duptree *b,
+static int clear_a_reference(struct gfs2_sbd *sdp, struct duptree *b,
 			     osi_list_t *ref_list, struct dup_handler *dh,
 			     int inval)
 {
@@ -423,7 +420,7 @@ static int clear_a_reference(struct gfs2_sbd *sbp, struct duptree *b,
 			  (unsigned long long)id->block_no);
 		clear_dup_fxns.private = (void *) dh;
 		/* Clear the EAs for the inode first */
-		ip = fsck_load_inode(sbp, id->block_no);
+		ip = fsck_load_inode(sdp, id->block_no);
 		check_inode_eattr(ip, &clear_dup_fxns);
 		/* If the dup wasn't only in the EA, clear the inode */
 		if (id->reftypecount[ref_as_data] ||
@@ -444,7 +441,7 @@ static int clear_a_reference(struct gfs2_sbd *sbp, struct duptree *b,
 	return 0;
 }
 
-static int handle_dup_blk(struct gfs2_sbd *sbp, struct duptree *b)
+static int handle_dup_blk(struct gfs2_sbd *sdp, struct duptree *b)
 {
 	struct gfs2_inode *ip;
 	osi_list_t *tmp;
@@ -480,7 +477,7 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct duptree *b)
 		struct gfs2_buffer_head *bh;
 		uint32_t cmagic;
 
-		bh = bread(sbp, b->block);
+		bh = bread(sdp, b->block);
 		cmagic = ((struct gfs2_meta_header *)(bh->b_data))->mh_magic;
 		brelse(bh);
 		if (be32_to_cpu(cmagic) == GFS2_MAGIC) {
@@ -502,7 +499,7 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct duptree *b)
 				log_warn( _("Clearing inode %lld (0x%llx)...\n"),
 					 (unsigned long long)id->block_no,
 					 (unsigned long long)id->block_no);
-				ip = fsck_load_inode(sbp, id->block_no);
+				ip = fsck_load_inode(sdp, id->block_no);
 				ii = inodetree_find(ip->i_di.di_num.no_addr);
 				if (ii)
 					inodetree_delete(ii);
@@ -536,10 +533,10 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct duptree *b)
 	osi_list_foreach(tmp, &b->ref_inode_list)
 		log_inode_reference(b, tmp, 0);
 
-	last_reference = clear_a_reference(sbp, b, &b->ref_invinode_list,
+	last_reference = clear_a_reference(sdp, b, &b->ref_invinode_list,
 					   &dh, 1);
 	if (!last_reference)
-		last_reference = clear_a_reference(sbp, b, &b->ref_inode_list,
+		last_reference = clear_a_reference(sdp, b, &b->ref_inode_list,
 						   &dh, 0);
 
 	if (last_reference && !osi_list_empty(&b->ref_inode_list)) {
@@ -556,7 +553,7 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct duptree *b)
 			     "reference in inode %lld (0x%llx).\n"),
 			   (unsigned long long)id->block_no,
 			   (unsigned long long)id->block_no);
-		ip = fsck_load_inode(sbp, id->block_no);
+		ip = fsck_load_inode(sdp, id->block_no);
 
 		q = block_type(id->block_no);
 		if (q == gfs2_inode_invalid) {
@@ -597,7 +594,7 @@ static int handle_dup_blk(struct gfs2_sbd *sbp, struct duptree *b)
 /* Pass 1b handles finding the previous inode for a duplicate block
  * When found, store the inodes pointing to the duplicate block for
  * use in pass2 */
-int pass1b(struct gfs2_sbd *sbp)
+int pass1b(struct gfs2_sbd *sdp)
 {
 	struct duptree *b;
 	uint64_t i;
@@ -641,7 +638,7 @@ int pass1b(struct gfs2_sbd *sbp)
 				   (unsigned long long)i);
 
 		warm_fuzzy_stuff(i);
-		if (find_block_ref(sbp, i) < 0) {
+		if (find_block_ref(sdp, i) < 0) {
 			stack;
 			rc = FSCK_ERROR;
 			goto out;
@@ -656,7 +653,7 @@ out:
 		next = osi_next(n);
                 b = (struct duptree *)n;
 		if (!skip_this_pass && !rc) /* no error & not asked to skip the rest */
-			handle_dup_blk(sbp, b);
+			handle_dup_blk(sdp, b);
 		/* Do not attempt to free the dup_blocks list or its parts
 		   here because any func that calls check_metatree needs
 		   to check duplicate status based on this linked list.
diff --git a/gfs2/fsck/pass1c.c b/gfs2/fsck/pass1c.c
index 10b92ed..2a86e14 100644
--- a/gfs2/fsck/pass1c.c
+++ b/gfs2/fsck/pass1c.c
@@ -71,11 +71,11 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block,
 		      uint64_t parent, struct gfs2_buffer_head **bh,
 		      void *private)
 {
-	struct gfs2_sbd *sbp = ip->i_sbd;
+	struct gfs2_sbd *sdp = ip->i_sbd;
 	uint8_t q;
 	struct gfs2_buffer_head *indir_bh = NULL;
 
-	if(gfs2_check_range(sbp, block)) {
+	if(gfs2_check_range(sdp, block)) {
 		log_err( _("Extended attributes indirect block #%llu"
 			" (0x%llx) for inode #%llu"
 			" (0x%llx) out of range...removing\n"),
@@ -97,7 +97,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block,
 		return ask_remove_eattr(ip);
 	}
 	else
-		indir_bh = bread(sbp, block);
+		indir_bh = bread(sdp, block);
 
 	*bh = indir_bh;
 	return 0;
@@ -107,10 +107,10 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
 		     uint64_t parent, struct gfs2_buffer_head **bh,
 		     void *private)
 {
-	struct gfs2_sbd *sbp = ip->i_sbd;
+	struct gfs2_sbd *sdp = ip->i_sbd;
 	uint8_t q;
 
-	if(gfs2_check_range(sbp, block)) {
+	if(gfs2_check_range(sdp, block)) {
 		log_err( _("Extended attributes block for inode #%llu"
 			" (0x%llx) out of range.\n"),
 			(unsigned long long)ip->i_di.di_num.no_addr,
@@ -126,7 +126,7 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
 		return ask_remove_eattr(ip);
 	}
 	else 
-		*bh = bread(sbp, block);
+		*bh = bread(sdp, block);
 
 	return 0;
 }
@@ -204,11 +204,11 @@ static int check_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_ptr,
 			 struct gfs2_ea_header *ea_hdr_prev, void *private)
 {
 	uint8_t q;
-	struct gfs2_sbd *sbp = ip->i_sbd;
+	struct gfs2_sbd *sdp = ip->i_sbd;
 
 	q = block_type(be64_to_cpu(*ea_ptr));
 	if(q != gfs2_meta_eattr) {
-		if(remove_eattr_entry(sbp, leaf_bh, ea_hdr, ea_hdr_prev)){
+		if(remove_eattr_entry(sdp, leaf_bh, ea_hdr, ea_hdr_prev)){
 			stack;
 			return -1;
 		}
@@ -219,7 +219,7 @@ static int check_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_ptr,
 
 /* Go over all inodes with extended attributes and verify the EAs are
  * valid */
-int pass1c(struct gfs2_sbd *sbp)
+int pass1c(struct gfs2_sbd *sdp)
 {
 	uint64_t block_no = 0;
 	struct gfs2_buffer_head *bh;
@@ -236,19 +236,20 @@ int pass1c(struct gfs2_sbd *sbp)
 	pass1c_fxns.private = NULL;
 
 	log_info( _("Looking for inodes containing ea blocks...\n"));
-	osi_list_foreach_safe(tmp, &sbp->eattr_blocks.list, x) {
+	osi_list_foreach_safe(tmp, &sdp->eattr_blocks.list, x) {
 		ea_block = osi_list_entry(tmp, struct special_blocks, list);
 		block_no = ea_block->block;
 		warm_fuzzy_stuff(block_no);
 
 		if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
 			return FSCK_OK;
-		bh = bread(sbp, block_no);
+		bh = bread(sdp, block_no);
 		if (!gfs2_check_meta(bh, GFS2_METATYPE_DI)) { /* if a dinode */
-			log_info( _("EA in inode %"PRIu64" (0x%" PRIx64 ")\n"),
-				 block_no, block_no);
-			gfs2_special_clear(&sbp->eattr_blocks, block_no);
-			ip = fsck_inode_get(sbp, bh);
+			log_info( _("EA in inode %llu (0x%llx)\n"),
+				 (unsigned long long)block_no,
+				 (unsigned long long)block_no);
+			gfs2_special_clear(&sdp->eattr_blocks, block_no);
+			ip = fsck_inode_get(sdp, bh);
 			ip->bh_owned = 1;
 
 			log_debug( _("Found eattr at %llu (0x%llx)\n"),
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 90c6940..0993d2a 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -18,7 +18,7 @@
 
 /* Set children's parent inode in dir_info structure - ext2 does not set
  * dotdot inode here, but instead in pass3 - should we? */
-static int set_parent_dir(struct gfs2_sbd *sbp, uint64_t childblock,
+static int set_parent_dir(struct gfs2_sbd *sdp, uint64_t childblock,
 			  uint64_t parentblock)
 {
 	struct dir_info *di;
@@ -54,7 +54,7 @@ static int set_parent_dir(struct gfs2_sbd *sbp, uint64_t childblock,
 }
 
 /* Set's the child's '..' directory inode number in dir_info structure */
-static int set_dotdot_dir(struct gfs2_sbd *sbp, uint64_t childblock,
+static int set_dotdot_dir(struct gfs2_sbd *sdp, uint64_t childblock,
 				   uint64_t parentblock)
 {
 	struct dir_info *di;
@@ -64,7 +64,7 @@ static int set_dotdot_dir(struct gfs2_sbd *sbp, uint64_t childblock,
 		if(di->dinode == childblock) {
 			/* Special case for root inode because we set
 			 * it earlier */
-			if(di->dotdot_parent && sbp->md.rooti->i_di.di_num.no_addr
+			if(di->dotdot_parent && sdp->md.rooti->i_di.di_num.no_addr
 			   != di->dinode) {
 				/* This should never happen */
 				log_crit( _("Dotdot parent already set for"
@@ -166,7 +166,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 		 struct gfs2_buffer_head *bh, char *filename,
 		 uint16_t *count, void *priv)
 {
-	struct gfs2_sbd *sbp = ip->i_sbd;
+	struct gfs2_sbd *sdp = ip->i_sbd;
 	uint8_t q;
 	char tmp_name[MAX_FILENAME];
 	uint64_t entryblock;
@@ -266,7 +266,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 		if (ip->i_di.di_num.no_addr == entryblock)
 			entry_ip = ip;
 		else
-			entry_ip = fsck_load_inode(sbp, entryblock);
+			entry_ip = fsck_load_inode(sdp, entryblock);
 		check_inode_eattr(entry_ip, &pass2_fxns_delete);
 		check_metatree(entry_ip, &pass2_fxns_delete);
 		if (entry_ip != ip)
@@ -340,7 +340,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 		if (ip->i_di.di_num.no_addr == entryblock)
 			entry_ip = ip;
 		else
-			entry_ip = fsck_load_inode(sbp, entryblock);
+			entry_ip = fsck_load_inode(sdp, entryblock);
 		check_inode_eattr(entry_ip, &clear_eattrs);
 		if (entry_ip != ip)
 			fsck_inode_put(&entry_ip);
@@ -364,7 +364,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 			if (ip->i_di.di_num.no_addr == entryblock)
 				entry_ip = ip;
 			else
-				entry_ip = fsck_load_inode(sbp, entryblock);
+				entry_ip = fsck_load_inode(sdp, entryblock);
 			check_inode_eattr(entry_ip, &clear_eattrs);
 			if (entry_ip != ip)
 				fsck_inode_put(&entry_ip);
@@ -395,7 +395,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 			if (ip->i_di.di_num.no_addr == entryblock)
 				entry_ip = ip;
 			else
-				entry_ip = fsck_load_inode(sbp, entryblock);
+				entry_ip = fsck_load_inode(sdp, entryblock);
 			check_inode_eattr(entry_ip, &clear_eattrs);
 			if (entry_ip != ip)
 				fsck_inode_put(&entry_ip);
@@ -423,7 +423,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 			if (ip->i_di.di_num.no_addr == entryblock)
 				entry_ip = ip;
 			else
-				entry_ip = fsck_load_inode(sbp, entryblock);
+				entry_ip = fsck_load_inode(sdp, entryblock);
 			check_inode_eattr(entry_ip, &clear_eattrs);
 			if (entry_ip != ip)
 				fsck_inode_put(&entry_ip);
@@ -443,7 +443,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 			if (ip->i_di.di_num.no_addr == entryblock)
 				entry_ip = ip;
 			else
-				entry_ip = fsck_load_inode(sbp, entryblock);
+				entry_ip = fsck_load_inode(sdp, entryblock);
 			check_inode_eattr(entry_ip, &clear_eattrs);
 			if (entry_ip != ip)
 				fsck_inode_put(&entry_ip);
@@ -455,7 +455,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 		/* Add the address this entry is pointing to
 		 * to this inode's dotdot_parent in
 		 * dir_info */
-		if(set_dotdot_dir(sbp, ip->i_di.di_num.no_addr, entryblock)) {
+		if(set_dotdot_dir(sdp, ip->i_di.di_num.no_addr, entryblock)) {
 			stack;
 			return -1;
 		}
@@ -474,7 +474,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 	}
 
 	/*log_debug( _("Found plain directory dentry\n"));*/
-	error = set_parent_dir(sbp, entryblock, ip->i_di.di_num.no_addr);
+	error = set_parent_dir(sdp, entryblock, ip->i_di.di_num.no_addr);
 	if(error > 0) {
 		log_err( _("%s: Hard link to block %" PRIu64" (0x%" PRIx64
 			   ") detected.\n"), tmp_name, entryblock, entryblock);
@@ -519,7 +519,7 @@ struct metawalk_fxns pass2_fxns = {
 /* Check system directory inode                                           */
 /* Should work for all system directories: root, master, jindex, per_node */
 static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
-		     int builder(struct gfs2_sbd *sbp))
+		     int builder(struct gfs2_sbd *sdp))
 {
 	uint64_t iblock = 0;
 	struct dir_status ds = {0};
@@ -619,12 +619,12 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
 /**
  * is_system_dir - determine if a given block is for a system directory.
  */
-static inline int is_system_dir(struct gfs2_sbd *sbp, uint64_t block)
+static inline int is_system_dir(struct gfs2_sbd *sdp, uint64_t block)
 {
-	if (block == sbp->md.rooti->i_di.di_num.no_addr ||
-	    block == sbp->md.jiinode->i_di.di_num.no_addr ||
-	    block == sbp->md.pinode->i_di.di_num.no_addr ||
-	    block == sbp->master_dir->i_di.di_num.no_addr)
+	if (block == sdp->md.rooti->i_di.di_num.no_addr ||
+	    block == sdp->md.jiinode->i_di.di_num.no_addr ||
+	    block == sdp->md.pinode->i_di.di_num.no_addr ||
+	    block == sdp->master_dir->i_di.di_num.no_addr)
 		return TRUE;
 	return FALSE;
 }
@@ -640,7 +640,7 @@ static inline int is_system_dir(struct gfs2_sbd *sbp, uint64_t block)
  * directory name length
  * entries in range
  */
-int pass2(struct gfs2_sbd *sbp)
+int pass2(struct gfs2_sbd *sdp)
 {
 	uint64_t dirblk;
 	uint8_t q;
@@ -652,25 +652,25 @@ int pass2(struct gfs2_sbd *sbp)
 	int error = 0;
 
 	/* Check all the system directory inodes. */
-	if (check_system_dir(sbp->md.jiinode, "jindex", build_jindex)) {
+	if (check_system_dir(sdp->md.jiinode, "jindex", build_jindex)) {
 		stack;
 		return FSCK_ERROR;
 	}
 	if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
 		return FSCK_OK;
-	if (check_system_dir(sbp->md.pinode, "per_node", build_per_node)) {
+	if (check_system_dir(sdp->md.pinode, "per_node", build_per_node)) {
 		stack;
 		return FSCK_ERROR;
 	}
 	if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
 		return FSCK_OK;
-	if (check_system_dir(sbp->master_dir, "master", build_master)) {
+	if (check_system_dir(sdp->master_dir, "master", build_master)) {
 		stack;
 		return FSCK_ERROR;
 	}
 	if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
 		return FSCK_OK;
-	if (check_system_dir(sbp->md.rooti, "root", build_root)) {
+	if (check_system_dir(sdp->md.rooti, "root", build_root)) {
 		stack;
 		return FSCK_ERROR;
 	}
@@ -684,7 +684,7 @@ int pass2(struct gfs2_sbd *sbp)
 			return FSCK_OK;
 
 		/* Skip the system inodes - they're checked above */
-		if (is_system_dir(sbp, dirblk))
+		if (is_system_dir(sdp, dirblk))
 			continue;
 
 		q = block_type(dirblk);
@@ -700,7 +700,7 @@ int pass2(struct gfs2_sbd *sbp)
 		if(ds.q == gfs2_bad_block) {
 			/* First check that the directory's metatree
 			 * is valid */
-			ip = fsck_load_inode(sbp, dirblk);
+			ip = fsck_load_inode(sdp, dirblk);
 			error = check_metatree(ip, &pass2_fxns);
 			fsck_inode_put(&ip);
 			if (error < 0) {
@@ -708,7 +708,7 @@ int pass2(struct gfs2_sbd *sbp)
 				return error;
 			}
 		}
-		error = check_dir(sbp, dirblk, &pass2_fxns);
+		error = check_dir(sdp, dirblk, &pass2_fxns);
 		if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
 			return FSCK_OK;
 		if(error < 0) {
@@ -724,11 +724,13 @@ int pass2(struct gfs2_sbd *sbp)
 				return FSCK_ERROR;
 			}
 			if(query( _("Remove directory entry for bad"
-				    " inode %"PRIu64" (0x%" PRIx64 ") in %"PRIu64
-				    " (0x%" PRIx64 ")? (y/n)"), dirblk,
-				  dirblk, di->treewalk_parent,
-				  di->treewalk_parent)) {
-				error = remove_dentry_from_dir(sbp, di->treewalk_parent,
+				    " inode %llu (0x%llx) in %llu"
+				    " (0x%llx)? (y/n)"),
+				  (unsigned long long)dirblk,
+				  (unsigned long long)dirblk,
+				  (unsigned long long)di->treewalk_parent,
+				  (unsigned long long)di->treewalk_parent)) {
+				error = remove_dentry_from_dir(sdp, di->treewalk_parent,
 							       dirblk);
 				if(error < 0) {
 					stack;
@@ -752,9 +754,9 @@ int pass2(struct gfs2_sbd *sbp)
 			/* Can't use fsck_blockmap_set here because we don't
 			   have an inode in memory. */
 			gfs2_blockmap_set(bl, dirblk, gfs2_inode_invalid);
-			check_n_fix_bitmap(sbp, dirblk, gfs2_inode_invalid);
+			check_n_fix_bitmap(sdp, dirblk, gfs2_inode_invalid);
 		}
-		ip = fsck_load_inode(sbp, dirblk);
+		ip = fsck_load_inode(sdp, dirblk);
 		if(!ds.dotdir) {
 			log_err(_("No '.' entry found for directory inode@"
 				  "block %"PRIu64" (0x%" PRIx64 ")\n"),
diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c
index e1fe5a5..c2bc0f9 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -14,7 +14,7 @@
 #include "metawalk.h"
 #include "util.h"
 
-static int attach_dotdot_to(struct gfs2_sbd *sbp, uint64_t newdotdot,
+static int attach_dotdot_to(struct gfs2_sbd *sdp, uint64_t newdotdot,
 			    uint64_t olddotdot, uint64_t block)
 {
 	char *filename;
@@ -22,8 +22,8 @@ static int attach_dotdot_to(struct gfs2_sbd *sbp, uint64_t newdotdot,
 	struct gfs2_inode *ip, *pip;
 	uint64_t cur_blks;
 
-	ip = fsck_load_inode(sbp, block);
-	pip = fsck_load_inode(sbp, newdotdot);
+	ip = fsck_load_inode(sdp, block);
+	pip = fsck_load_inode(sdp, newdotdot);
 	/* FIXME: Need to add some interactive
 	 * options here and come up with a
 	 * good default for non-interactive */
@@ -68,7 +68,7 @@ static int attach_dotdot_to(struct gfs2_sbd *sbp, uint64_t newdotdot,
 	return 0;
 }
 
-static struct dir_info *mark_and_return_parent(struct gfs2_sbd *sbp,
+static struct dir_info *mark_and_return_parent(struct gfs2_sbd *sdp,
 					       struct dir_info *di)
 {
 	struct dir_info *pdi;
@@ -102,10 +102,11 @@ static struct dir_info *mark_and_return_parent(struct gfs2_sbd *sbp,
 			}
 			else {
 				log_warn( _("Treewalk parent is correct,"
-						 " fixing dotdot -> %"PRIu64" (0x%" PRIx64 ")\n"),
-						 di->treewalk_parent, di->treewalk_parent);
-				attach_dotdot_to(sbp, di->treewalk_parent,
-								 di->dotdot_parent, di->dinode);
+					    " fixing dotdot -> %llu (0x%llx)\n"),
+					 (unsigned long long)di->treewalk_parent,
+					 (unsigned long long)di->treewalk_parent);
+				attach_dotdot_to(sdp, di->treewalk_parent,
+						 di->dotdot_parent, di->dinode);
 				di->dotdot_parent = di->treewalk_parent;
 			}
 		} else {
@@ -117,10 +118,13 @@ static struct dir_info *mark_and_return_parent(struct gfs2_sbd *sbp,
 				/* FIXME: add a dinode for this entry instead? */
 
 				if(query( _("Remove directory entry for bad"
-					    " inode %"PRIu64" (0x%" PRIx64 ") in %"PRIu64
-					    " (0x%" PRIx64 ")? (y/n)"), di->dinode, di->dinode,
-					  di->treewalk_parent, di->treewalk_parent)) {
-					error = remove_dentry_from_dir(sbp, di->treewalk_parent,
+					    " inode %llu (0x%llx) in %llu"
+					    " (0x%llx)? (y/n)"),
+					(unsigned long long)di->dinode,
+					(unsigned long long)di->dinode,
+					(unsigned long long)di->treewalk_parent,
+					(unsigned long long)di->treewalk_parent)) {
+					error = remove_dentry_from_dir(sdp, di->treewalk_parent,
 												   di->dinode);
 					if(error < 0) {
 						stack;
@@ -144,7 +148,7 @@ static struct dir_info *mark_and_return_parent(struct gfs2_sbd *sbp,
 				log_err( _("Both .. and treewalk parents are "
 					   "directories, going with treewalk "
 					   "for now...\n"));
-				attach_dotdot_to(sbp, di->treewalk_parent,
+				attach_dotdot_to(sdp, di->treewalk_parent,
 						 di->dotdot_parent,
 						 di->dinode);
 				di->dotdot_parent = di->treewalk_parent;
@@ -170,19 +174,19 @@ static struct dir_info *mark_and_return_parent(struct gfs2_sbd *sbp,
  * handle disconnected directories
  * handle lost+found directory errors (missing, not a directory, no space)
  */
-int pass3(struct gfs2_sbd *sbp)
+int pass3(struct gfs2_sbd *sdp)
 {
 	struct osi_node *tmp, *next = NULL;
 	struct dir_info *di, *tdi;
 	struct gfs2_inode *ip;
 	uint8_t q;
 
-	di = dirtree_find(sbp->md.rooti->i_di.di_num.no_addr);
+	di = dirtree_find(sdp->md.rooti->i_di.di_num.no_addr);
 	if (di) {
 		log_info( _("Marking root inode connected\n"));
 		di->checked = 1;
 	}
-	di = dirtree_find(sbp->master_dir->i_di.di_num.no_addr);
+	di = dirtree_find(sdp->master_dir->i_di.di_num.no_addr);
 	if (di) {
 		log_info( _("Marking master directory inode connected\n"));
 		di->checked = 1;
@@ -202,7 +206,7 @@ int pass3(struct gfs2_sbd *sbp)
 			 * param */
 			if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
 				return FSCK_OK;
-			tdi = mark_and_return_parent(sbp, di);
+			tdi = mark_and_return_parent(sdp, di);
 
 			if (tdi) {
 				log_debug( _("Directory at block %" PRIu64
@@ -227,7 +231,7 @@ int pass3(struct gfs2_sbd *sbp)
 					   because we don't have ip */
 					gfs2_blockmap_set(bl, di->dinode,
 							  gfs2_block_free);
-					check_n_fix_bitmap(sbp, di->dinode,
+					check_n_fix_bitmap(sdp, di->dinode,
 							   gfs2_block_free);
 					break;
 				} else
@@ -253,16 +257,16 @@ int pass3(struct gfs2_sbd *sbp)
 				   because we don't have ip */
 				gfs2_blockmap_set(bl, di->dinode,
 						  gfs2_block_free);
-				check_n_fix_bitmap(sbp, di->dinode,
+				check_n_fix_bitmap(sdp, di->dinode,
 						   gfs2_block_free);
 				log_err( _("The block was cleared\n"));
 				break;
 			}
 
-			log_err( _("Found unlinked directory at block %" PRIu64
-				   " (0x%" PRIx64 ")\n"), di->dinode,
-				 di->dinode);
-			ip = fsck_load_inode(sbp, di->dinode);
+			log_err( _("Found unlinked directory at block %llu"
+				   " (0x%llx)\n"), (unsigned long long)di->dinode,
+				 (unsigned long long)di->dinode);
+			ip = fsck_load_inode(sdp, di->dinode);
 			/* Don't skip zero size directories with eattrs */
 			if(!ip->i_di.di_size && !ip->i_di.di_eattr){
 				log_err( _("Unlinked directory has zero "
diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c
index 0fd0aac..0e17a05 100644
--- a/gfs2/fsck/pass4.c
+++ b/gfs2/fsck/pass4.c
@@ -39,7 +39,7 @@ static int fix_link_count(struct inode_info *ii, struct gfs2_inode *ip)
 	return 0;
 }
 
-static int scan_inode_list(struct gfs2_sbd *sbp) {
+static int scan_inode_list(struct gfs2_sbd *sdp) {
 	struct osi_node *tmp, *next = NULL;
 	struct inode_info *ii;
 	struct gfs2_inode *ip;
@@ -67,7 +67,7 @@ static int scan_inode_list(struct gfs2_sbd *sbp) {
 					(unsigned long long)ii->inode);
 				if(query(  _("Delete unlinked inode with bad "
 					     "blocks? (y/n) "))) {
-					ip = fsck_load_inode(sbp, ii->inode);
+					ip = fsck_load_inode(sdp, ii->inode);
 					check_inode_eattr(ip,
 							  &pass4_fxns_delete);
 					check_metatree(ip, &pass4_fxns_delete);
@@ -91,7 +91,7 @@ static int scan_inode_list(struct gfs2_sbd *sbp) {
 					   "not an inode (%d)\n"),
 					 (unsigned long long)ii->inode,
 					 (unsigned long long)ii->inode, q);
-				ip = fsck_load_inode(sbp, ii->inode);
+				ip = fsck_load_inode(sdp, ii->inode);
 				if(query(_("Delete unlinked inode? (y/n) "))) {
 					check_inode_eattr(ip,
 							  &pass4_fxns_delete);
@@ -108,7 +108,7 @@ static int scan_inode_list(struct gfs2_sbd *sbp) {
 				}
 				continue;
 			}
-			ip = fsck_load_inode(sbp, ii->inode);
+			ip = fsck_load_inode(sdp, ii->inode);
 
 			/* We don't want to clear zero-size files with
 			 * eattrs - there might be relevent info in
@@ -145,10 +145,11 @@ static int scan_inode_list(struct gfs2_sbd *sbp) {
 					ii->inode, ii->link_count, ii->counted_links);
 			/* Read in the inode, adjust the link count,
 			 * and write it back out */
-			if(query( _("Update link count for inode %" PRIu64
-				    " (0x%" PRIx64 ") ? (y/n) "),
-				  ii->inode, ii->inode)) {
-				ip = fsck_load_inode(sbp, ii->inode); /* bread, inode_get */
+			if(query( _("Update link count for inode %llu"
+				    " (0x%llx) ? (y/n) "),
+				  (unsigned long long)ii->inode,
+				  (unsigned long long)ii->inode)) {
+				ip = fsck_load_inode(sdp, ii->inode); /* bread, inode_get */
 				fix_link_count(ii, ip);
 				ii->link_count = ii->counted_links;
 				fsck_inode_put(&ip); /* out, brelse, free */
@@ -186,13 +187,13 @@ static int scan_inode_list(struct gfs2_sbd *sbp) {
  * handle unreferenced inodes of other types
  * handle bad blocks
  */
-int pass4(struct gfs2_sbd *sbp)
+int pass4(struct gfs2_sbd *sdp)
 {
 	if(lf_dip)
 		log_debug( _("At beginning of pass4, lost+found entries is %u\n"),
 				  lf_dip->i_di.di_entries);
 	log_info( _("Checking inode reference counts.\n"));
-	if(scan_inode_list(sbp)) {
+	if(scan_inode_list(sdp)) {
 		stack;
 		return FSCK_ERROR;
 	}
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index 79493e1..db1870d 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -48,7 +48,7 @@ static int convert_mark(uint8_t q, uint32_t *count)
 	return -1;
 }
 
-static int check_block_status(struct gfs2_sbd *sbp, char *buffer, unsigned int buflen,
+static int check_block_status(struct gfs2_sbd *sdp, char *buffer, unsigned int buflen,
 					   uint64_t *rg_block, uint64_t rg_data, uint32_t *count)
 {
 	unsigned char *byte, *end;
@@ -84,7 +84,7 @@ static int check_block_status(struct gfs2_sbd *sbp, char *buffer, unsigned int b
 				 (unsigned long long)block,
 				 (unsigned long long)block);
 			if(query(_("Do you want to fix the bitmap? (y/n) "))) {
-				if(gfs2_set_bitmap(sbp, block, block_status))
+				if(gfs2_set_bitmap(sdp, block, block_status))
 					log_err(_("Unlinked block %llu "
 						  "(0x%llx) bitmap not fixed."
 						  "\n"),
@@ -112,10 +112,10 @@ static int check_block_status(struct gfs2_sbd *sbp, char *buffer, unsigned int b
 			log_err( _("Metadata type is %u (%s)\n"), q,
 					block_type_string(q));
 
-			if(query(_("Fix bitmap for block %" PRIu64
-				   " (0x%" PRIx64 ") ? (y/n) "),
-				 block, block)) {
-				if(gfs2_set_bitmap(sbp, block, block_status))
+			if(query(_("Fix bitmap for block %llu (0x%llx) ? (y/n) "),
+				 (unsigned long long)block,
+				 (unsigned long long)block)) {
+				if(gfs2_set_bitmap(sdp, block, block_status))
 					log_err( _("Failed.\n"));
 				else
 					log_err( _("Succeeded.\n"));
@@ -134,7 +134,7 @@ static int check_block_status(struct gfs2_sbd *sbp, char *buffer, unsigned int b
 	return 0;
 }
 
-static void update_rgrp(struct gfs2_sbd *sbp, struct rgrp_list *rgp,
+static void update_rgrp(struct gfs2_sbd *sdp, struct rgrp_list *rgp,
 			uint32_t *count)
 {
 	uint32_t i;
@@ -146,7 +146,7 @@ static void update_rgrp(struct gfs2_sbd *sbp, struct rgrp_list *rgp,
 		bits = &rgp->bits[i];
 
 		/* update the bitmaps */
-		check_block_status(sbp, rgp->bh[i]->b_data + bits->bi_offset,
+		check_block_status(sdp, rgp->bh[i]->b_data + bits->bi_offset,
 						   bits->bi_len, &rg_block, rgp->ri.ri_data0, count);
 		if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
 			return;
@@ -191,7 +191,7 @@ static void update_rgrp(struct gfs2_sbd *sbp, struct rgrp_list *rgp,
  * fix free block maps
  * fix used inode maps
  */
-int pass5(struct gfs2_sbd *sbp)
+int pass5(struct gfs2_sbd *sdp)
 {
 	osi_list_t *tmp;
 	struct rgrp_list *rgp = NULL;
@@ -199,7 +199,7 @@ int pass5(struct gfs2_sbd *sbp)
 	uint64_t rg_count = 0;
 
 	/* Reconcile RG bitmaps with fsck bitmap */
-	for(tmp = sbp->rglist.next; tmp != &sbp->rglist; tmp = tmp->next){
+	for(tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next){
 		if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
 			return FSCK_OK;
 		log_info( _("Verifying Resource Group #%" PRIu64 "\n"), rg_count);
@@ -208,7 +208,7 @@ int pass5(struct gfs2_sbd *sbp)
 
 		rg_count++;
 		/* Compare the bitmaps and report the differences */
-		update_rgrp(sbp, rgp, count);
+		update_rgrp(sdp, rgp, count);
 	}
 	/* Fix up superblock info based on this - don't think there's
 	 * anything to do here... */
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 02/66] fsck.gfs2: Change "if(" to "if ("
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 01/66] fsck.gfs2: Make functions use sdp rather than sbp rpeterso
@ 2012-01-20 15:09 ` rpeterso
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 03/66] libgfs1: Add gfs1 variable to superblock structure rpeterso
                   ` (63 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:09 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch changes all if and while statements to have a space before
the parenthesis so they are consistent.

rhbz#675723
---
 gfs2/fsck/eattr.c        |    8 +-
 gfs2/fsck/fs_recovery.c  |    6 +-
 gfs2/fsck/initialize.c   |   35 ++++++------
 gfs2/fsck/link.c         |    2 +-
 gfs2/fsck/lost_n_found.c |   10 ++--
 gfs2/fsck/main.c         |   16 +++---
 gfs2/fsck/metawalk.c     |   74 ++++++++++++------------
 gfs2/fsck/pass1.c        |   60 ++++++++++----------
 gfs2/fsck/pass1b.c       |   22 ++++----
 gfs2/fsck/pass1c.c       |   32 +++++-----
 gfs2/fsck/pass2.c        |  139 ++++++++++++++++++++++++----------------------
 gfs2/fsck/pass3.c        |   74 +++++++++++++-----------
 gfs2/fsck/pass4.c        |   51 +++++++++--------
 gfs2/fsck/pass5.c        |   20 +++---
 gfs2/fsck/rgrepair.c     |    2 +-
 gfs2/fsck/util.c         |   10 ++--
 16 files changed, 287 insertions(+), 274 deletions(-)

diff --git a/gfs2/fsck/eattr.c b/gfs2/fsck/eattr.c
index 5d3e7cd..377c98c 100644
--- a/gfs2/fsck/eattr.c
+++ b/gfs2/fsck/eattr.c
@@ -16,25 +16,25 @@ int clear_eattr_entry (struct gfs2_inode *ip,
 {
 	struct gfs2_sbd *sdp = ip->i_sbd;
 
-	if(!ea_hdr->ea_name_len){
+	if (!ea_hdr->ea_name_len){
 		/* Skip this entry for now */
 		return 1;
 	}
 
-	if(!GFS2_EATYPE_VALID(ea_hdr->ea_type) &&
+	if (!GFS2_EATYPE_VALID(ea_hdr->ea_type) &&
 	   ((ea_hdr_prev) || (!ea_hdr_prev && ea_hdr->ea_type))){
 		/* Skip invalid entry */
 		return 1;
 	}
 
-	if(ea_hdr->ea_num_ptrs){
+	if (ea_hdr->ea_num_ptrs){
 		uint32_t avail_size;
 		int max_ptrs;
 
 		avail_size = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header);
 		max_ptrs = (be32_to_cpu(ea_hdr->ea_data_len)+avail_size-1)/avail_size;
 
-		if(max_ptrs > ea_hdr->ea_num_ptrs) {
+		if (max_ptrs > ea_hdr->ea_num_ptrs) {
 			return 1;
 		} else {
 			log_debug( _("  Pointers Required: %d\n"
diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c
index b9d856e..8e29167 100644
--- a/gfs2/fsck/fs_recovery.c
+++ b/gfs2/fsck/fs_recovery.c
@@ -410,7 +410,7 @@ int preen_is_safe(struct gfs2_sbd *sdp, int preen, int force_check)
 		return 1; /* not called by rc.sysinit--we're okay to preen */
 	if (force_check)  /* If check was forced by the user? */
 		return 1; /* user's responsibility--we're okay to preen */
-	if(!memcmp(sdp->sd_sb.sb_lockproto + 5, "nolock", 6))
+	if (!memcmp(sdp->sd_sb.sb_lockproto + 5, "nolock", 6))
 		return 1; /* local file system--preen is okay */
 	return 0; /* might be mounted on another node--not guaranteed safe */
 }
@@ -631,7 +631,7 @@ int ji_update(struct gfs2_sbd *sdp)
 	char journal_name[JOURNAL_NAME_SIZE];
 	int i;
 
-	if(!ip) {
+	if (!ip) {
 		log_crit("Journal index inode not found.\n");
 		return -1;
 	}
@@ -645,7 +645,7 @@ int ji_update(struct gfs2_sbd *sdp)
 	else
 		sdp->md.journals = ip->i_di.di_entries - 2;
 
-	if(!(sdp->md.journal = calloc(sdp->md.journals,
+	if (!(sdp->md.journal = calloc(sdp->md.journals,
 				      sizeof(struct gfs2_inode *)))) {
 		log_err("Unable to allocate journal index\n");
 		return -1;
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index ff620c0..6b5bfec 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -20,7 +20,7 @@
 #include "inode_hash.h"
 
 #define CLEAR_POINTER(x) \
-	if(x) { \
+	if (x) { \
 		free(x); \
 		x = NULL; \
 	}
@@ -38,9 +38,9 @@ static struct master_dir fix_md;
  */
 static int block_mounters(struct gfs2_sbd *sdp, int block_em)
 {
-	if(block_em) {
+	if (block_em) {
 		/* verify it starts with lock_ */
-		if(!strncmp(sdp->sd_sb.sb_lockproto, "lock_", 5)) {
+		if (!strncmp(sdp->sd_sb.sb_lockproto, "lock_", 5)) {
 			/* Change lock_ to fsck_ */
 			memcpy(sdp->sd_sb.sb_lockproto, "fsck_", 5);
 		}
@@ -49,13 +49,13 @@ static int block_mounters(struct gfs2_sbd *sdp, int block_em)
 	} else {
 		/* verify it starts with fsck_ */
 		/* verify it starts with lock_ */
-		if(!strncmp(sdp->sd_sb.sb_lockproto, "fsck_", 5)) {
+		if (!strncmp(sdp->sd_sb.sb_lockproto, "fsck_", 5)) {
 			/* Change fsck_ to lock_ */
 			memcpy(sdp->sd_sb.sb_lockproto, "lock_", 5);
 		}
 	}
 
-	if(write_sb(sdp)) {
+	if (write_sb(sdp)) {
 		stack;
 		return -1;
 	}
@@ -162,9 +162,10 @@ static int set_block_ranges(struct gfs2_sbd *sdp)
 	last_data_block = rmax;
 	first_data_block = rmin;
 
-	if(fsck_lseek(sdp->device_fd, (last_fs_block * sdp->sd_sb.sb_bsize))){
-		log_crit( _("Can't seek to last block in file system: %"
-				 PRIu64" (0x%" PRIx64 ")\n"), last_fs_block, last_fs_block);
+	if (fsck_lseek(sdp->device_fd, (last_fs_block * sdp->sd_sb.sb_bsize))){
+		log_crit( _("Can't seek to last block in file system: %llu"
+			 " (0x%llx)\n"), (unsigned long long)last_fs_block,
+			 (unsigned long long)last_fs_block);
 		goto fail;
 	}
 
@@ -572,7 +573,7 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
 	/*******************************************************************
 	 *******  Now, set boundary fields in the super block  *************
 	 *******************************************************************/
-	if(set_block_ranges(sdp)){
+	if (set_block_ranges(sdp)){
 		log_err( _("Unable to determine the boundaries of the"
 			" file system.\n"));
 		goto fail;
@@ -1063,7 +1064,7 @@ static int fill_super_block(struct gfs2_sbd *sdp)
 	sdp->sd_sb.sb_bsize = GFS2_DEFAULT_BSIZE;
 	sdp->bsize = sdp->sd_sb.sb_bsize;
 
-	if(sizeof(struct gfs2_sb) > sdp->sd_sb.sb_bsize){
+	if (sizeof(struct gfs2_sb) > sdp->sd_sb.sb_bsize){
 		log_crit( _("GFS superblock is larger than the blocksize!\n"));
 		log_debug( _("sizeof(struct gfs2_sb) > sdp->sd_sb.sb_bsize\n"));
 		return -1;
@@ -1100,7 +1101,7 @@ int initialize(struct gfs2_sbd *sdp, int force_check, int preen,
 
 	*all_clean = 0;
 
-	if(opts.no)
+	if (opts.no)
 		open_flag = O_RDONLY;
 	else
 		open_flag = O_RDWR | O_EXCL;
@@ -1149,8 +1150,8 @@ int initialize(struct gfs2_sbd *sdp, int force_check, int preen,
 		return FSCK_ERROR;
 
 	/* Change lock protocol to be fsck_* instead of lock_* */
-	if(!opts.no && preen_is_safe(sdp, preen, force_check)) {
-		if(block_mounters(sdp, 1)) {
+	if (!opts.no && preen_is_safe(sdp, preen, force_check)) {
+		if (block_mounters(sdp, 1)) {
 			log_err( _("Unable to block other mounters\n"));
 			return FSCK_USAGE;
 		}
@@ -1174,8 +1175,8 @@ int initialize(struct gfs2_sbd *sdp, int force_check, int preen,
 
 	/* verify various things */
 
-	if(replay_journals(sdp, preen, force_check, &clean_journals)) {
-		if(!opts.no && preen_is_safe(sdp, preen, force_check))
+	if (replay_journals(sdp, preen, force_check, &clean_journals)) {
+		if (!opts.no && preen_is_safe(sdp, preen, force_check))
 			block_mounters(sdp, 0);
 		stack;
 		return FSCK_ERROR;
@@ -1202,8 +1203,8 @@ mount_fail:
 
 static void destroy_sdp(struct gfs2_sbd *sdp)
 {
-	if(!opts.no) {
-		if(block_mounters(sdp, 0)) {
+	if (!opts.no) {
+		if (block_mounters(sdp, 0)) {
 			log_warn( _("Unable to unblock other mounters - manual intervention required\n"));
 			log_warn( _("Use 'gfs2_tool sb <device> proto' to fix\n"));
 		}
diff --git a/gfs2/fsck/link.c b/gfs2/fsck/link.c
index ce8eb52..24d5134 100644
--- a/gfs2/fsck/link.c
+++ b/gfs2/fsck/link.c
@@ -67,7 +67,7 @@ int decrement_link(uint64_t inode_no, uint64_t referenced_from,
 	ii = inodetree_find(inode_no);
 	/* If the list has entries, look for one that matches
 	 * inode_no */
-	if(ii) {
+	if (ii) {
 		if (!ii->counted_links) {
 			log_debug( _("Directory %lld (0x%llx)'s link to "
 			     " %"PRIu64" (0x%" PRIx64 ") via %s is zero!\n"),
diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index 3256bdc..988d2ea 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -31,7 +31,7 @@ int add_inode_to_lf(struct gfs2_inode *ip){
 	struct gfs2_sbd *sdp = ip->i_sbd;
 	struct dir_info *di;
 
-	if(!lf_dip) {
+	if (!lf_dip) {
 		uint8_t q;
 
 		log_info( _("Locating/Creating lost+found directory\n"));
@@ -46,7 +46,7 @@ int add_inode_to_lf(struct gfs2_inode *ip){
 			       sdp->md.rooti->i_di.di_nlink);
 
 		q = block_type(lf_dip->i_di.di_num.no_addr);
-		if(q != gfs2_inode_dir) {
+		if (q != gfs2_inode_dir) {
 			/* This is a new lost+found directory, so set its
 			 * block type and increment link counts for
 			 * the directories */
@@ -79,7 +79,7 @@ int add_inode_to_lf(struct gfs2_inode *ip){
 			di = NULL;
 		}
 	}
-	if(ip->i_di.di_num.no_addr == lf_dip->i_di.di_num.no_addr) {
+	if (ip->i_di.di_num.no_addr == lf_dip->i_di.di_num.no_addr) {
 		log_err( _("Trying to add lost+found to itself...skipping"));
 		return 0;
 	}
@@ -129,7 +129,7 @@ int add_inode_to_lf(struct gfs2_inode *ip){
 				    "for orphan directory %lld (0x%llx)\n"),
 				  (unsigned long long)ip->i_di.di_num.no_addr,
 				  (unsigned long long)ip->i_di.di_num.no_addr);
-		if(gfs2_dirent_del(ip, "..", 2))
+		if (gfs2_dirent_del(ip, "..", 2))
 			log_warn( _("add_inode_to_lf:  Unable to remove "
 				    "\"..\" directory entry.\n"));
 
@@ -186,7 +186,7 @@ int add_inode_to_lf(struct gfs2_inode *ip){
 	increment_link(ip->i_di.di_num.no_addr, lf_dip->i_di.di_num.no_addr,
 		       _("from lost+found"));
 	/* If it's a directory, lost+found is back-linked to it via .. */
-	if(S_ISDIR(ip->i_di.di_mode))
+	if (S_ISDIR(ip->i_di.di_mode))
 		increment_link(lf_dip->i_di.di_num.no_addr,
 			       ip->i_di.di_mode, _("to lost+found"));
 
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index a50a0d7..5dae096 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -61,7 +61,7 @@ static int read_cmdline(int argc, char **argv, struct gfs2_options *gopts)
 {
 	int c;
 
-	while((c = getopt(argc, argv, "afhnpqvyV")) != -1) {
+	while ((c = getopt(argc, argv, "afhnpqvyV")) != -1) {
 		switch(c) {
 
 		case 'a':
@@ -106,10 +106,10 @@ static int read_cmdline(int argc, char **argv, struct gfs2_options *gopts)
 
 		}
 	}
-	if(argc > optind) {
+	if (argc > optind) {
 		gopts->device = (argv[optind]);
-		if(!gopts->device) {
-			fprintf(stderr, _("Please use '-h' for usage.\n"));
+		if (!gopts->device) {
+			fprintf(stderr, _("Please use '-h' for help.\n"));
 			return FSCK_USAGE;
 		}
 	} else {
@@ -134,7 +134,7 @@ static void interrupt(int sig)
 				     _("Do you want to abort gfs2_fsck, skip " \
 				     "the rest of this pass or continue " \
 				     "(a/s/c)?"), "asc");
-	if(tolower(response) == 's') {
+	if (tolower(response) == 's') {
 		skip_this_pass = TRUE;
 		return;
 	}
@@ -226,7 +226,7 @@ int main(int argc, char **argv)
 
 	memset(sdp, 0, sizeof(*sdp));
 
-	if((error = read_cmdline(argc, argv, &opts)))
+	if ((error = read_cmdline(argc, argv, &opts)))
 		exit(error);
 	setbuf(stdout, NULL);
 	log_notice( _("Initializing fsck\n"));
@@ -256,7 +256,7 @@ int main(int argc, char **argv)
 		last_reported_block = 0;
 		pass = "pass 1b";
 		log_notice( _("Starting pass1b\n"));
-		if((error = pass1b(sdp)))
+		if ((error = pass1b(sdp)))
 			exit(error);
 		if (skip_this_pass || fsck_abort) {
 			skip_this_pass = FALSE;
@@ -269,7 +269,7 @@ int main(int argc, char **argv)
 		last_reported_block = 0;
 		pass = "pass 1c";
 		log_notice( _("Starting pass1c\n"));
-		if((error = pass1c(sdp)))
+		if ((error = pass1c(sdp)))
 			exit(error);
 		if (skip_this_pass || fsck_abort) {
 			skip_this_pass = FALSE;
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 0e443fa..47412f9 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -50,7 +50,7 @@ int check_n_fix_bitmap(struct gfs2_sbd *sdp, uint64_t blk,
 			 (unsigned long long)blk, (unsigned long long)blk,
 			 allocdesc[new_bitmap_state],
 			 allocdesc[old_bitmap_state]);
-		if(query( _("Okay to fix the bitmap? (y/n)"))) {
+		if (query( _("Okay to fix the bitmap? (y/n)"))) {
 			/* If the new bitmap state is free (and therefore the
 			   old state was not) we have to add to the free
 			   space in the rgrp. If the old bitmap state was
@@ -312,7 +312,7 @@ static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
 
 	bh_end = bh->b_data + ip->i_sbd->bsize;
 
-	if(type == DIR_LINEAR) {
+	if (type == DIR_LINEAR) {
 		dent = (struct gfs2_dirent *)(bh->b_data + sizeof(struct gfs2_dinode));
 	}
 	else if (type == DIR_EXHASH) {
@@ -327,10 +327,10 @@ static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
 	}
 
 	prev = NULL;
-	if(!pass->check_dentry)
+	if (!pass->check_dentry)
 		return 0;
 
-	while(1) {
+	while (1) {
 		if (skip_this_pass || fsck_abort)
 			return FSCK_OK;
 		memset(&de, 0, sizeof(struct gfs2_dirent));
@@ -373,7 +373,7 @@ static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
 			}
 		}
 		if (!de.de_inum.no_formal_ino){
-			if(first){
+			if (first){
 				log_debug( _("First dirent is a sentinel (place holder).\n"));
 				first = 0;
 			} else {
@@ -410,7 +410,7 @@ static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
 				error = pass->check_dentry(ip, dent, prev, bh,
 							   filename, count,
 							   pass->private);
-				if(error < 0) {
+				if (error < 0) {
 					stack;
 					return -1;
 				}
@@ -429,7 +429,7 @@ static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
 
 		/* If we didn't clear the dentry, or if we did, but it
 		 * was the first dentry, set prev  */
-		if(!error || first)
+		if (!error || first)
 			prev = dent;
 		first = 0;
 		dent = (struct gfs2_dirent *)((char *)dent + de.de_rec_len);
@@ -639,7 +639,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 								  leaf info */
 			ref_count++;
 			continue;
-		} else if(old_leaf == leaf_no) {
+		} else if (old_leaf == leaf_no) {
 			ref_count++;
 			continue;
 		}
@@ -657,7 +657,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 			if (fsck_abort)
 				break;
 			/* Make sure the block number is in range. */
-			if(gfs2_check_range(ip->i_sbd, leaf_no)){
+			if (gfs2_check_range(ip->i_sbd, leaf_no)){
 				log_err( _("Leaf block #%llu (0x%llx) is out "
 					"of range for directory #%llu (0x%llx"
 					").\n"), (unsigned long long)leaf_no,
@@ -686,7 +686,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 				break;
 			}
 			gfs2_leaf_in(&leaf, lbh);
-			if(pass->check_leaf)
+			if (pass->check_leaf)
 				error = pass->check_leaf(ip, leaf_no, lbh,
 							 pass->private);
 
@@ -730,13 +730,13 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 				if (skip_this_pass || fsck_abort)
 					return 0;
 
-				if(error < 0) {
+				if (error < 0) {
 					stack;
 					brelse(lbh);
 					return -1;
 				}
 
-				if(count != leaf.lf_entries) {
+				if (count != leaf.lf_entries) {
 					brelse(lbh);
 					lbh = bread(sdp, leaf_no);
 					gfs2_leaf_in(&leaf, lbh);
@@ -753,7 +753,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 						(unsigned long long)
 						ip->i_di.di_num.no_addr,
 						leaf.lf_entries, count);
-					if(query( _("Update leaf entry count? (y/n) "))) {
+					if (query( _("Update leaf entry count? (y/n) "))) {
 						leaf.lf_entries = count;
 						gfs2_leaf_out(&leaf, lbh);
 						log_warn( _("Leaf entry count updated\n"));
@@ -769,7 +769,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 			leaf_no = leaf.lf_next;
 			log_debug( _("Leaf chain 0x%llx detected.\n"),
 				   (unsigned long long)leaf_no);
-		} while(1); /* while we have chained leaf blocks */
+		} while (1); /* while we have chained leaf blocks */
 	} /* for every leaf block */
 	return 0;
 }
@@ -784,24 +784,24 @@ static int check_eattr_entries(struct gfs2_inode *ip,
 	int error = 0;
 	uint32_t offset = (uint32_t)sizeof(struct gfs2_meta_header);
 
-	if(!pass->check_eattr_entry)
+	if (!pass->check_eattr_entry)
 		return 0;
 
 	ea_hdr = (struct gfs2_ea_header *)(bh->b_data +
 					  sizeof(struct gfs2_meta_header));
 
-	while(1){
+	while (1){
 		if (ea_hdr->ea_type == GFS2_EATYPE_UNUSED)
 			error = 0;
 		else
 			error = pass->check_eattr_entry(ip, bh, ea_hdr,
 							ea_hdr_prev,
 							pass->private);
-		if(error < 0) {
+		if (error < 0) {
 			stack;
 			return -1;
 		}
-		if(error == 0 && pass->check_eattr_extentry &&
+		if (error == 0 && pass->check_eattr_extentry &&
 		   ea_hdr->ea_num_ptrs) {
 			uint32_t tot_ealen = 0;
 			struct gfs2_sbd *sdp = ip->i_sbd;
@@ -818,7 +818,7 @@ static int check_eattr_entries(struct gfs2_inode *ip,
 			** reuse...........  */
 
 			for(i = 0; i < ea_hdr->ea_num_ptrs; i++){
-				if(pass->check_eattr_extentry(ip,
+				if (pass->check_eattr_extentry(ip,
 							      ea_data_ptr,
 							      bh, ea_hdr,
 							      ea_hdr_prev,
@@ -851,7 +851,7 @@ static int check_eattr_entries(struct gfs2_inode *ip,
 			}
 		}
 		offset += be32_to_cpu(ea_hdr->ea_rec_len);
-		if(ea_hdr->ea_flags & GFS2_EAFLAG_LAST ||
+		if (ea_hdr->ea_flags & GFS2_EAFLAG_LAST ||
 		   offset >= ip->i_sbd->sd_sb.sb_bsize || ea_hdr->ea_rec_len == 0){
 			break;
 		}
@@ -880,14 +880,14 @@ static int check_leaf_eattr(struct gfs2_inode *ip, uint64_t block,
 	log_debug( _("Checking EA leaf block #%"PRIu64" (0x%" PRIx64 ").\n"),
 			  block, block);
 
-	if(pass->check_eattr_leaf) {
+	if (pass->check_eattr_leaf) {
 		error = pass->check_eattr_leaf(ip, block, parent, &bh,
 					       pass->private);
-		if(error < 0) {
+		if (error < 0) {
 			stack;
 			return -1;
 		}
-		if(error > 0) {
+		if (error > 0) {
 			if (bh)
 				brelse(bh);
 			return 1;
@@ -992,7 +992,7 @@ static int check_indirect_eattr(struct gfs2_inode *ip, uint64_t indirect,
 		end = ea_leaf_ptr + ((sdp->sd_sb.sb_bsize
 				      - sizeof(struct gfs2_meta_header)) / 8);
 
-		while(*ea_leaf_ptr && (ea_leaf_ptr < end)){
+		while (*ea_leaf_ptr && (ea_leaf_ptr < end)){
 			block = be64_to_cpu(*ea_leaf_ptr);
 			leaf_pointers++;
 			error = check_leaf_eattr(ip, block, indirect, pass);
@@ -1064,15 +1064,15 @@ int check_inode_eattr(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 {
 	int error = 0;
 
-	if(!ip->i_di.di_eattr)
+	if (!ip->i_di.di_eattr)
 		return 0;
 
 	log_debug( _("Extended attributes exist for inode #%llu (0x%llx).\n"),
 		  (unsigned long long)ip->i_di.di_num.no_addr,
 		  (unsigned long long)ip->i_di.di_num.no_addr);
 
-	if(ip->i_di.di_flags & GFS2_DIF_EA_INDIRECT){
-		if((error = check_indirect_eattr(ip, ip->i_di.di_eattr, pass)))
+	if (ip->i_di.di_flags & GFS2_DIF_EA_INDIRECT){
+		if ((error = check_indirect_eattr(ip, ip->i_di.di_eattr, pass)))
 			stack;
 	} else {
 		error = check_leaf_eattr(ip, ip->i_di.di_eattr,
@@ -1135,7 +1135,7 @@ static int build_and_check_metalist(struct gfs2_inode *ip, osi_list_t *mlp,
 	if (S_ISDIR(ip->i_di.di_mode))
 		height++;
 
-	/* if(<there are no indirect blocks to check>) */
+	/* if (<there are no indirect blocks to check>) */
 	if (height < 2)
 		return 0;
 	for (h = 1; h < height; h++) {
@@ -1176,12 +1176,12 @@ static int build_and_check_metalist(struct gfs2_inode *ip, osi_list_t *mlp,
 							   pass->private);
 				/* check_metalist should hold any buffers
 				   it gets with "bread". */
-				if(err < 0) {
+				if (err < 0) {
 					stack;
 					error = err;
 					goto fail;
 				}
-				if(err > 0) {
+				if (err > 0) {
 					if (!error)
 						error = err;
 					log_debug( _("Skipping block %" PRIu64
@@ -1196,7 +1196,7 @@ static int build_and_check_metalist(struct gfs2_inode *ip, osi_list_t *mlp,
 						   (unsigned long long)block);
 					continue;
 				}
-				if(!nbh)
+				if (!nbh)
 					nbh = bread(ip->i_sbd, block);
 				osi_list_add(&nbh->b_altlist, cur_list);
 			} /* for all data on the indirect block */
@@ -1375,7 +1375,7 @@ int check_linear_dir(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
 	uint16_t count = 0;
 
 	error = check_entries(ip, bh, DIR_LINEAR, &count, pass);
-	if(error < 0) {
+	if (error < 0) {
 		stack;
 		return -1;
 	}
@@ -1390,12 +1390,12 @@ int check_dir(struct gfs2_sbd *sdp, uint64_t block, struct metawalk_fxns *pass)
 
 	ip = fsck_load_inode(sdp, block);
 
-	if(ip->i_di.di_flags & GFS2_DIF_EXHASH)
+	if (ip->i_di.di_flags & GFS2_DIF_EXHASH)
 		error = check_leaf_blks(ip, pass);
 	else
 		error = check_linear_dir(ip, ip->i_bh, pass);
 
-	if(error < 0)
+	if (error < 0)
 		stack;
 
 	fsck_inode_put(&ip); /* does a brelse */
@@ -1416,7 +1416,7 @@ static int remove_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 	gfs2_dirent_in(&dentry, (char *)dent);
 	de = &dentry;
 
-	if(de->de_inum.no_addr == *dentryblock)
+	if (de->de_inum.no_addr == *dentryblock)
 		dirent2_del(ip, bh, prev_de, dent);
 	else
 		(*count)++;
@@ -1436,7 +1436,7 @@ int remove_dentry_from_dir(struct gfs2_sbd *sdp, uint64_t dir,
 		     " (0x%llx)\n"), (unsigned long long)dentryblock,
 		  (unsigned long long)dentryblock,
 		  (unsigned long long)dir, (unsigned long long)dir);
-	if(gfs2_check_range(sdp, dir)) {
+	if (gfs2_check_range(sdp, dir)) {
 		log_err( _("Parent directory out of range\n"));
 		return 1;
 	}
@@ -1444,7 +1444,7 @@ int remove_dentry_from_dir(struct gfs2_sbd *sdp, uint64_t dir,
 	remove_dentry_fxns.check_dentry = remove_dentry;
 
 	q = block_type(dir);
-	if(q != gfs2_inode_dir) {
+	if (q != gfs2_inode_dir) {
 		log_info( _("Parent block is not a directory...ignoring\n"));
 		return 1;
 	}
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index ef2714f..02305f4 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -160,11 +160,11 @@ static int resuscitate_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 	block = de->de_inum.no_addr;
 	/* Start of checks */
 	memset(tmp_name, 0, sizeof(tmp_name));
-	if(de->de_name_len < sizeof(tmp_name))
+	if (de->de_name_len < sizeof(tmp_name))
 		strncpy(tmp_name, filename, de->de_name_len);
 	else
 		strncpy(tmp_name, filename, sizeof(tmp_name) - 1);
-	if(gfs2_check_range(sdp, block)) {
+	if (gfs2_check_range(sdp, block)) {
 		log_err( _("Block # referenced by system directory entry %s "
 			   "in inode %lld (0x%llx) is out of range; "
 			   "ignored.\n"),
@@ -237,7 +237,7 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block,
 		blktypedesc = _("a journaled data block");
 	}
 	q = block_type(block);
-	if(q != gfs2_block_free) {
+	if (q != gfs2_block_free) {
 		log_err( _("Found duplicate block %llu (0x%llx) referenced "
 			   "as metadata in indirect block for dinode "
 			   "%llu (0x%llx) - was marked %d (%s)\n"),
@@ -259,7 +259,7 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block,
 			 (unsigned long long)ip->i_di.di_num.no_addr,
 			 (unsigned long long)block,
 			 (unsigned long long)block, blktypedesc);
-		if(!found_dup) {
+		if (!found_dup) {
 			fsck_blockmap_set(ip, block, _("bad indirect"),
 					  gfs2_meta_inval);
 			brelse(nbh);
@@ -320,7 +320,7 @@ static int undo_check_metalist(struct gfs2_inode *ip, uint64_t block,
 	nbh = bread(ip->i_sbd, block);
 
 	if (gfs2_check_meta(nbh, iblk_type)) {
-		if(!found_dup) {
+		if (!found_dup) {
 			fsck_blockmap_set(ip, block, _("bad indirect"),
 					  gfs2_block_free);
 			brelse(nbh);
@@ -545,10 +545,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect,
 
 	/* This inode contains an eattr - it may be invalid, but the
 	 * eattr attributes points to a non-zero block */
-	if(gfs2_check_range(sdp, indirect)) {
-		/*log_warn("EA indirect block #%"PRIu64" is out of range.\n",
-			indirect);
-			fsck_blockmap_set(parent, "bad", bad_block);*/
+	if (gfs2_check_range(sdp, indirect)) {
 		/* Doesn't help to mark this here - this gets checked
 		 * in pass1c */
 		return 1;
@@ -560,8 +557,8 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect,
 	   handling sort it out.  If it isn't, clear it but don't
 	   count it as a duplicate. */
 	*bh = bread(sdp, indirect);
-	if(gfs2_check_meta(*bh, GFS2_METATYPE_IN)) {
-		if(q != gfs2_block_free) { /* Duplicate? */
+	if (gfs2_check_meta(*bh, GFS2_METATYPE_IN)) {
+		if (q != gfs2_block_free) { /* Duplicate? */
 			add_duplicate_ref(ip, indirect, ref_as_ea, 0,
 					  INODE_VALID);
 			if (!clear_eas(ip, bc, indirect, 1,
@@ -575,7 +572,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect,
 			    "type"));
 		return 1;
 	}
-	if(q != gfs2_block_free) { /* Duplicate? */
+	if (q != gfs2_block_free) { /* Duplicate? */
 		log_err( _("Inode #%llu (0x%llx): Duplicate Extended "
 			   "Attribute indirect block found at #%llu "
 			   "(0x%llx).\n"),
@@ -650,8 +647,8 @@ static int check_leaf_block(struct gfs2_inode *ip, uint64_t block, int btype,
 	   really is an EA.  If it is, let duplicate handling sort it out.
 	   If it isn't, clear it but don't count it as a duplicate. */
 	leaf_bh = bread(sdp, block);
-	if(gfs2_check_meta(leaf_bh, btype)) {
-		if(q != gfs2_block_free) { /* Duplicate? */
+	if (gfs2_check_meta(leaf_bh, btype)) {
+		if (q != gfs2_block_free) { /* Duplicate? */
 			add_duplicate_ref(ip, block, ref_as_ea, 0,
 					  INODE_VALID);
 			clear_eas(ip, bc, block, 1,
@@ -664,7 +661,7 @@ static int check_leaf_block(struct gfs2_inode *ip, uint64_t block, int btype,
 		brelse(leaf_bh);
 		return 1;
 	}
-	if(q != gfs2_block_free) { /* Duplicate? */
+	if (q != gfs2_block_free) { /* Duplicate? */
 		log_debug( _("Duplicate block found at #%lld (0x%llx).\n"),
 			   (unsigned long long)block,
 			   (unsigned long long)block);
@@ -714,7 +711,7 @@ static int check_extended_leaf_eattr(struct gfs2_inode *ip, uint64_t *data_ptr,
 	struct gfs2_buffer_head *bh = NULL;
 	int error;
 
-	if(gfs2_check_range(sdp, el_blk)){
+	if (gfs2_check_range(sdp, el_blk)){
 		log_err( _("Inode #%llu (0x%llx): Extended Attribute block "
 			   "%llu (0x%llx) has an extended leaf block #%llu "
 			   "(0x%llx) that is out of range.\n"),
@@ -781,7 +778,7 @@ static int check_eattr_entries(struct gfs2_inode *ip,
 	struct gfs2_sbd *sdp = ip->i_sbd;
 	char ea_name[256];
 
-	if(!ea_hdr->ea_name_len){
+	if (!ea_hdr->ea_name_len){
 		/* Skip this entry for now */
 		return 1;
 	}
@@ -790,20 +787,20 @@ static int check_eattr_entries(struct gfs2_inode *ip,
 	strncpy(ea_name, (char *)ea_hdr + sizeof(struct gfs2_ea_header),
 		ea_hdr->ea_name_len);
 
-	if(!GFS2_EATYPE_VALID(ea_hdr->ea_type) &&
+	if (!GFS2_EATYPE_VALID(ea_hdr->ea_type) &&
 	   ((ea_hdr_prev) || (!ea_hdr_prev && ea_hdr->ea_type))){
 		/* Skip invalid entry */
 		return 1;
 	}
 
-	if(ea_hdr->ea_num_ptrs){
+	if (ea_hdr->ea_num_ptrs){
 		uint32_t avail_size;
 		int max_ptrs;
 
 		avail_size = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header);
 		max_ptrs = (be32_to_cpu(ea_hdr->ea_data_len)+avail_size-1)/avail_size;
 
-		if(max_ptrs > ea_hdr->ea_num_ptrs) {
+		if (max_ptrs > ea_hdr->ea_num_ptrs) {
 			return 1;
 		} else {
 			log_debug( _("  Pointers Required: %d\n  Pointers Reported: %d\n"),
@@ -1007,7 +1004,7 @@ static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip)
 		if (fsck_blockmap_set(ip, block, _("directory"),
 				      gfs2_inode_dir))
 			goto bad_dinode;
-		if(!dirtree_insert(block))
+		if (!dirtree_insert(block))
 			goto bad_dinode;
 		break;
 	case S_IFREG:
@@ -1058,7 +1055,7 @@ static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip)
 			goto bad_dinode;
 		return 0;
 	}
-	if(set_link_count(ip->i_di.di_num.no_addr, ip->i_di.di_nlink))
+	if (set_link_count(ip->i_di.di_num.no_addr, ip->i_di.di_nlink))
 		goto bad_dinode;
 
 	if (S_ISDIR(ip->i_di.di_mode) &&
@@ -1070,7 +1067,7 @@ static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip)
 				 (unsigned long long)ip->i_di.di_num.no_addr,
 				 ip->i_di.di_depth,
 				 (1 >> (ip->i_di.di_size/sizeof(uint64_t))));
-			if(fsck_blockmap_set(ip, block, _("bad depth"),
+			if (fsck_blockmap_set(ip, block, _("bad depth"),
 					     gfs2_block_free))
 				goto bad_dinode;
 			return 0;
@@ -1151,10 +1148,11 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh)
 
 	ip = fsck_inode_get(sdp, bh);
 	q = block_type(block);
-	if(q != gfs2_block_free) {
-		log_err( _("Found a duplicate inode block at #%" PRIu64
-			   " (0x%" PRIx64 ") previously marked as a %s\n"),
-			 block, block, block_type_string(q));
+	if (q != gfs2_block_free) {
+		log_err( _("Found a duplicate inode block at #%llu"
+			   " (0x%llx) previously marked as a %s\n"),
+			 (unsigned long long)block,
+			 (unsigned long long)block, block_type_string(q));
 		add_duplicate_ref(ip, block, ref_as_meta, 0, INODE_VALID);
 		fsck_inode_put(&ip);
 		return 0;
@@ -1166,9 +1164,9 @@ static int handle_di(struct gfs2_sbd *sdp, struct gfs2_buffer_head *bh)
 			(unsigned long long)block,
 			(unsigned long long)ip->i_di.di_num.no_addr,
 			(unsigned long long)ip->i_di.di_num.no_addr);
-		if(query( _("Fix address in inode at block #%"
-			    PRIu64 " (0x%" PRIx64 ")? (y/n) "),
-			  block, block)) {
+		if (query( _("Fix address in inode at block #%llu"
+			    " (0x%llx)? (y/n) "),
+			  (unsigned long long)block, (unsigned long long)block)) {
 			ip->i_di.di_num.no_addr = ip->i_di.di_num.no_formal_ino = block;
 			bmodified(ip->i_bh);
 		} else
@@ -1235,7 +1233,7 @@ static int check_system_inode(struct gfs2_sbd *sdp,
 	   inode and get it all setup - of course, everything will be in
 	   lost+found then, but we *need* our system inodes before we can
 	   do any of that. */
-	if(!(*sysinode) || ds.q != mark) {
+	if (!(*sysinode) || ds.q != mark) {
 		log_err( _("Invalid or missing %s system inode (should be %d, "
 			   "is %d).\n"), filename, mark, ds.q);
 		if (query(_("Create new %s system inode? (y/n) "), filename)) {
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index 01d479c..c5a31fa 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -141,11 +141,11 @@ static int check_dir_dup_ref(struct gfs2_inode *ip,  struct gfs2_dirent *de,
 	struct inode_with_dups *id;
 
 	id = osi_list_entry(tmp2, struct inode_with_dups, list);
-	if(id->name)
+	if (id->name)
 		/* We can only have one parent of inodes that contain duplicate
 		 * blocks...no need to keep looking for this one. */
 		return 1;
-	if(id->block_no == de->de_inum.no_addr) {
+	if (id->block_no == de->de_inum.no_addr) {
 		id->name = strdup(filename);
 		id->parent = ip->i_di.di_num.no_addr;
 		log_debug( _("Duplicate block %llu (0x%llx"
@@ -223,7 +223,7 @@ static int clear_dup_metalist(struct gfs2_inode *ip, uint64_t block,
 		return 0;
 	}
 	/* This block, having failed the above test, is duplicated somewhere */
-	if(block == dh->b->block) {
+	if (block == dh->b->block) {
 		log_err( _("Not clearing duplicate reference in inode \"%s\" "
 			   "at block #%llu (0x%llx) to block #%llu (0x%llx) "
 			   "because it's valid for another inode.\n"),
@@ -273,7 +273,7 @@ static int clear_eattr_entry (struct gfs2_inode *ip,
 	struct gfs2_sbd *sdp = ip->i_sbd;
 	char ea_name[256];
 
-	if(!ea_hdr->ea_name_len){
+	if (!ea_hdr->ea_name_len){
 		/* Skip this entry for now */
 		return 1;
 	}
@@ -282,13 +282,13 @@ static int clear_eattr_entry (struct gfs2_inode *ip,
 	strncpy(ea_name, (char *)ea_hdr + sizeof(struct gfs2_ea_header),
 		ea_hdr->ea_name_len);
 
-	if(!GFS2_EATYPE_VALID(ea_hdr->ea_type) &&
+	if (!GFS2_EATYPE_VALID(ea_hdr->ea_type) &&
 	   ((ea_hdr_prev) || (!ea_hdr_prev && ea_hdr->ea_type))){
 		/* Skip invalid entry */
 		return 1;
 	}
 
-	if(ea_hdr->ea_num_ptrs){
+	if (ea_hdr->ea_num_ptrs){
 		uint32_t avail_size;
 		int max_ptrs;
 
@@ -296,7 +296,7 @@ static int clear_eattr_entry (struct gfs2_inode *ip,
 		max_ptrs = (be32_to_cpu(ea_hdr->ea_data_len) + avail_size - 1) /
 			avail_size;
 
-		if(max_ptrs > ea_hdr->ea_num_ptrs)
+		if (max_ptrs > ea_hdr->ea_num_ptrs)
 			return 1;
 		else {
 			log_debug( _("  Pointers Required: %d\n  Pointers Reported: %d\n"),
@@ -342,11 +342,11 @@ static int find_block_ref(struct gfs2_sbd *sdp, uint64_t inode)
 	/* Exhash dir leafs will be checked by check_metatree (right after
 	   the "end:" label.)  But if this is a linear directory we need to
 	   check the dir with check_linear_dir. */
-	if(S_ISDIR(ip->i_di.di_mode) && !(ip->i_di.di_flags & GFS2_DIF_EXHASH))
+	if (S_ISDIR(ip->i_di.di_mode) && !(ip->i_di.di_flags & GFS2_DIF_EXHASH))
 		error = check_linear_dir(ip, ip->i_bh, &find_dirents);
 
 	/* Check for ea references in the inode */
-	if(!error)
+	if (!error)
 		error = check_inode_eattr(ip, &find_refs);
 
 	fsck_inode_put(&ip); /* out, brelse, free */
@@ -406,7 +406,7 @@ static int clear_a_reference(struct gfs2_sbd *sdp, struct duptree *b,
 		id = osi_list_entry(tmp, struct inode_with_dups, list);
 		dh->b = b;
 		dh->id = id;
-		if(dh->ref_inode_count == 1) /* down to the last reference */
+		if (dh->ref_inode_count == 1) /* down to the last reference */
 			return 1;
 		if (!(query( _("Okay to clear %s inode %lld (0x%llx)? (y/n) "),
 			     (inval ? _("invalidated") : ""),
@@ -436,7 +436,7 @@ static int clear_a_reference(struct gfs2_sbd *sdp, struct duptree *b,
 		 * block for each duplicate and point the metadata at
 		 * the cloned blocks */
 	}
-	if(dh->ref_inode_count == 1) /* down to the last reference */
+	if (dh->ref_inode_count == 1) /* down to the last reference */
 		return 1;
 	return 0;
 }
diff --git a/gfs2/fsck/pass1c.c b/gfs2/fsck/pass1c.c
index 2a86e14..c6af290 100644
--- a/gfs2/fsck/pass1c.c
+++ b/gfs2/fsck/pass1c.c
@@ -75,7 +75,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block,
 	uint8_t q;
 	struct gfs2_buffer_head *indir_bh = NULL;
 
-	if(gfs2_check_range(sdp, block)) {
+	if (gfs2_check_range(sdp, block)) {
 		log_err( _("Extended attributes indirect block #%llu"
 			" (0x%llx) for inode #%llu"
 			" (0x%llx) out of range...removing\n"),
@@ -86,7 +86,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block,
 		return ask_remove_eattr(ip);
 	}
 	q = block_type(block);
-	if(q != gfs2_indir_blk) {
+	if (q != gfs2_indir_blk) {
 		log_err( _("Extended attributes indirect block #%llu"
 			" (0x%llx) for inode #%llu"
 			" (0x%llx) invalid.\n"),
@@ -110,7 +110,7 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
 	struct gfs2_sbd *sdp = ip->i_sbd;
 	uint8_t q;
 
-	if(gfs2_check_range(sdp, block)) {
+	if (gfs2_check_range(sdp, block)) {
 		log_err( _("Extended attributes block for inode #%llu"
 			" (0x%llx) out of range.\n"),
 			(unsigned long long)ip->i_di.di_num.no_addr,
@@ -118,7 +118,7 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
 		return ask_remove_eattr(ip);
 	}
 	q = block_type(block);
-	if(q != gfs2_meta_eattr) {
+	if (q != gfs2_meta_eattr) {
 		log_err( _("Extended attributes block for inode #%llu"
 			   " (0x%llx) invalid.\n"),
 			 (unsigned long long)ip->i_di.di_num.no_addr,
@@ -143,24 +143,24 @@ static int check_eattr_entry(struct gfs2_inode *ip,
 			                  ((unsigned long)leaf_bh->b_data));
 	uint32_t max_size = sdp->sd_sb.sb_bsize;
 
-	if(!ea_hdr->ea_name_len){
-		log_err( _("EA has name length == 0\n"));
+	if (!ea_hdr->ea_name_len){
+		log_err( _("EA has name length of zero\n"));
 		return ask_remove_eattr_entry(sdp, leaf_bh, ea_hdr,
 					      ea_hdr_prev, 1, 1);
 	}
-	if(offset + be32_to_cpu(ea_hdr->ea_rec_len) > max_size){
+	if (offset + be32_to_cpu(ea_hdr->ea_rec_len) > max_size){
 		log_err( _("EA rec length too long\n"));
 		return ask_remove_eattr_entry(sdp, leaf_bh, ea_hdr,
 					      ea_hdr_prev, 1, 1);
 	}
-	if(offset + be32_to_cpu(ea_hdr->ea_rec_len) == max_size &&
+	if (offset + be32_to_cpu(ea_hdr->ea_rec_len) == max_size &&
 	   (ea_hdr->ea_flags & GFS2_EAFLAG_LAST) == 0){
 		log_err( _("last EA has no last entry flag\n"));
 		return ask_remove_eattr_entry(sdp, leaf_bh, ea_hdr,
 					      ea_hdr_prev, 0, 0);
 	}
-	if(!ea_hdr->ea_name_len){
-		log_err( _("EA has name length == 0\n"));
+	if (!ea_hdr->ea_name_len){
+		log_err( _("EA has name length of zero\n"));
 		return ask_remove_eattr_entry(sdp, leaf_bh, ea_hdr,
 					      ea_hdr_prev, 0, 0);
 	}
@@ -169,7 +169,7 @@ static int check_eattr_entry(struct gfs2_inode *ip,
 	strncpy(ea_name, (char *)ea_hdr + sizeof(struct gfs2_ea_header),
 		ea_hdr->ea_name_len);
 
-	if(!GFS2_EATYPE_VALID(ea_hdr->ea_type) &&
+	if (!GFS2_EATYPE_VALID(ea_hdr->ea_type) &&
 	   ((ea_hdr_prev) || (!ea_hdr_prev && ea_hdr->ea_type))){
 		log_err( _("EA (%s) type is invalid (%d > %d).\n"),
 			ea_name, ea_hdr->ea_type, GFS2_EATYPE_LAST);
@@ -177,14 +177,14 @@ static int check_eattr_entry(struct gfs2_inode *ip,
 					      ea_hdr_prev, 0, 0);
 	}
 
-	if(ea_hdr->ea_num_ptrs){
+	if (ea_hdr->ea_num_ptrs){
 		uint32_t avail_size;
 		int max_ptrs;
 
 		avail_size = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header);
 		max_ptrs = (be32_to_cpu(ea_hdr->ea_data_len)+avail_size-1)/avail_size;
 
-		if(max_ptrs > ea_hdr->ea_num_ptrs){
+		if (max_ptrs > ea_hdr->ea_num_ptrs){
 			log_err( _("EA (%s) has incorrect number of pointers.\n"), ea_name);
 			log_err( _("  Required:  %d\n  Reported:  %d\n"),
 				 max_ptrs, ea_hdr->ea_num_ptrs);
@@ -207,8 +207,8 @@ static int check_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_ptr,
 	struct gfs2_sbd *sdp = ip->i_sbd;
 
 	q = block_type(be64_to_cpu(*ea_ptr));
-	if(q != gfs2_meta_eattr) {
-		if(remove_eattr_entry(sdp, leaf_bh, ea_hdr, ea_hdr_prev)){
+	if (q != gfs2_meta_eattr) {
+		if (remove_eattr_entry(sdp, leaf_bh, ea_hdr, ea_hdr_prev)){
 			stack;
 			return -1;
 		}
@@ -257,7 +257,7 @@ int pass1c(struct gfs2_sbd *sdp)
 				  (unsigned long long)ip->i_di.di_eattr);
 			/* FIXME: Handle walking the eattr here */
 			error = check_inode_eattr(ip, &pass1c_fxns);
-			if(error < 0) {
+			if (error < 0) {
 				stack;
 				brelse(bh);
 				return FSCK_ERROR;
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 0993d2a..af26988 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -24,13 +24,15 @@ static int set_parent_dir(struct gfs2_sbd *sdp, uint64_t childblock,
 	struct dir_info *di;
 
 	di = dirtree_find(childblock);
-	if(!di) {
-		log_err( _("Unable to find block %"PRIu64" (0x%" PRIx64
-			   ") in dir_info list\n"), childblock, childblock);
+	if (!di) {
+		log_err( _("Unable to find block %llu (0x%llx"
+			   ") in dir_info list\n"),
+			(unsigned long long)childblock,
+			(unsigned long long)childblock);
 		return -1;
 	}
 
-	if(di->dinode == childblock) {
+	if (di->dinode == childblock) {
 		if (di->treewalk_parent) {
 			log_err( _("Another directory at block %" PRIu64
 				   " (0x%" PRIx64 ") already contains this "
@@ -60,11 +62,11 @@ static int set_dotdot_dir(struct gfs2_sbd *sdp, uint64_t childblock,
 	struct dir_info *di;
 
 	di = dirtree_find(childblock);
-	if(di) {
-		if(di->dinode == childblock) {
+	if (di) {
+		if (di->dinode == childblock) {
 			/* Special case for root inode because we set
 			 * it earlier */
-			if(di->dotdot_parent && sdp->md.rooti->i_di.di_num.no_addr
+			if (di->dotdot_parent && sdp->md.rooti->i_di.di_num.no_addr
 			   != di->dinode) {
 				/* This should never happen */
 				log_crit( _("Dotdot parent already set for"
@@ -115,31 +117,31 @@ static int check_file_type(uint8_t de_type, uint8_t blk_type)
 {
 	switch(blk_type) {
 	case gfs2_inode_dir:
-		if(de_type != DT_DIR)
+		if (de_type != DT_DIR)
 			return 1;
 		break;
 	case gfs2_inode_file:
-		if(de_type != DT_REG)
+		if (de_type != DT_REG)
 			return 1;
 		break;
 	case gfs2_inode_lnk:
-		if(de_type != DT_LNK)
+		if (de_type != DT_LNK)
 			return 1;
 		break;
 	case gfs2_inode_blk:
-		if(de_type != DT_BLK)
+		if (de_type != DT_BLK)
 			return 1;
 		break;
 	case gfs2_inode_chr:
-		if(de_type != DT_CHR)
+		if (de_type != DT_CHR)
 			return 1;
 		break;
 	case gfs2_inode_fifo:
-		if(de_type != DT_FIFO)
+		if (de_type != DT_FIFO)
 			return 1;
 		break;
 	case gfs2_inode_sock:
-		if(de_type != DT_SOCK)
+		if (de_type != DT_SOCK)
 			return 1;
 		break;
 	default:
@@ -190,17 +192,17 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 
 	/* Start of checks */
 	memset(tmp_name, 0, MAX_FILENAME);
-	if(de->de_name_len < MAX_FILENAME)
+	if (de->de_name_len < MAX_FILENAME)
 		strncpy(tmp_name, filename, de->de_name_len);
 	else
 		strncpy(tmp_name, filename, MAX_FILENAME - 1);
 
-	if(gfs2_check_range(ip->i_sbd, entryblock)) {
+	if (gfs2_check_range(ip->i_sbd, entryblock)) {
 		log_err( _("Block # referenced by directory entry %s in inode "
 			   "%lld (0x%llx) is out of range\n"),
 			 tmp_name, (unsigned long long)ip->i_di.di_num.no_addr,
 			 (unsigned long long)ip->i_di.di_num.no_addr);
-		if(query( _("Clear directory entry to out of range block? "
+		if (query( _("Clear directory entry to out of range block? "
 			    "(y/n) "))) {
 			goto nuke_dentry;
 		} else {
@@ -217,7 +219,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 		log_err( _("Dir entry with bad record or name length\n"
 			"\tRecord length = %u\n\tName length = %u\n"),
 			de->de_rec_len, de->de_name_len);
-		if(!query( _("Clear the directory entry? (y/n) "))) {
+		if (!query( _("Clear the directory entry? (y/n) "))) {
 			log_err( _("Directory entry not fixed.\n"));
 			goto dentry_is_valid;
 		}
@@ -237,7 +239,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 		log_err( _("\tName length found  = %u\n"
 			   "\tHash expected      = %u (0x%x)\n"),
 			 de->de_name_len, calculated_hash, calculated_hash);
-		if(!query( _("Fix directory hash for %s? (y/n) "),
+		if (!query( _("Fix directory hash for %s? (y/n) "),
 			   tmp_name)) {
 			log_err( _("Directory entry hash for %s not "
 				   "fixed.\n"), tmp_name);
@@ -252,13 +254,13 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 
 	q = block_type(entryblock);
 	/* Get the status of the directory inode */
-	if(q == gfs2_inode_invalid || q == gfs2_bad_block) {
+	if (q == gfs2_inode_invalid || q == gfs2_bad_block) {
 		/* This entry's inode has bad blocks in it */
 
 		/* Handle bad blocks */
 		log_err( _("Found a bad directory entry: %s\n"), tmp_name);
 
-		if(!query( _("Delete inode containing bad blocks? (y/n)"))) {
+		if (!query( _("Delete inode containing bad blocks? (y/n)"))) {
 			log_warn( _("Entry to inode containing bad blocks remains\n"));
 			goto dentry_is_valid;
 		}
@@ -275,7 +277,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 				  _("bad directory entry"), gfs2_block_free);
 		goto nuke_dentry;
 	}
-	if(q < gfs2_inode_dir || q > gfs2_inode_sock) {
+	if (q < gfs2_inode_dir || q > gfs2_inode_sock) {
 		log_err( _("Directory entry '%s' referencing inode %llu "
 			   "(0x%llx) in dir inode %llu (0x%llx) block type "
 			   "%d: %s.\n"), tmp_name,
@@ -287,7 +289,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 			 _("was previously marked invalid") :
 			 _("was deleted or is not an inode"));
 
-		if(!query( _("Clear directory entry to non-inode block? "
+		if (!query( _("Clear directory entry to non-inode block? "
 			     "(y/n) "))) {
 			log_err( _("Directory entry to non-inode block remains\n"));
 			goto dentry_is_valid;
@@ -313,7 +315,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 	}
 
 	error = check_file_type(de->de_type, q);
-	if(error < 0) {
+	if (error < 0) {
 		log_err( _("Error: directory entry type is "
 			   "incompatible with block type@block %lld "
 			   "(0x%llx) in directory inode %llu (0x%llx).\n"),
@@ -326,14 +328,14 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 		stack;
 		return -1;
 	}
-	if(error > 0) {
+	if (error > 0) {
 		log_err( _("Type '%s' in dir entry (%s, %llu/0x%llx) conflicts"
 			 " with type '%s' in dinode. (Dir entry is stale.)\n"),
 			 de_type_string(de->de_type), tmp_name,
 			 (unsigned long long)entryblock,
 			 (unsigned long long)entryblock,
 			 block_type_string(q));
-		if(!query( _("Clear stale directory entry? (y/n) "))) {
+		if (!query( _("Clear stale directory entry? (y/n) "))) {
 			log_err( _("Stale directory entry remains\n"));
 			goto dentry_is_valid;
 		}
@@ -347,15 +349,15 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 		goto nuke_dentry;
 	}
 
-	if(!strcmp(".", tmp_name)) {
+	if (!strcmp(".", tmp_name)) {
 		log_debug( _("Found . dentry\n"));
 
-		if(ds->dotdir) {
+		if (ds->dotdir) {
 			log_err( _("Already found '.' entry in directory %llu"
 				" (0x%llx)\n"),
 				(unsigned long long)ip->i_di.di_num.no_addr,
 				(unsigned long long)ip->i_di.di_num.no_addr);
-			if(!query( _("Clear duplicate '.' entry? (y/n) "))) {
+			if (!query( _("Clear duplicate '.' entry? (y/n) "))) {
 				log_err( _("Duplicate '.' entry remains\n"));
 				/* FIXME: Should we continue on here
 				 * and check the rest of the '.' entry? */
@@ -375,7 +377,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 		 * location */
 
 		/* check that '.' refers to this inode */
-		if(entryblock != ip->i_di.di_num.no_addr) {
+		if (entryblock != ip->i_di.di_num.no_addr) {
 			log_err( _("'.' entry's value incorrect in directory %llu"
 				" (0x%llx).  Points to %llu"
 				" (0x%llx) when it should point to %llu"
@@ -386,7 +388,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 				(unsigned long long)entryblock,
 				(unsigned long long)ip->i_di.di_num.no_addr,
 				(unsigned long long)ip->i_di.di_num.no_addr);
-			if(!query( _("Remove '.' reference? (y/n) "))) {
+			if (!query( _("Remove '.' reference? (y/n) "))) {
 				log_err( _("Invalid '.' reference remains\n"));
 				/* Not setting ds->dotdir here since
 				 * this '.' entry is invalid */
@@ -405,14 +407,14 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 		ds->dotdir = 1;
 		goto dentry_is_valid;
 	}
-	if(!strcmp("..", tmp_name)) {
+	if (!strcmp("..", tmp_name)) {
 		log_debug( _("Found .. dentry\n"));
-		if(ds->dotdotdir) {
+		if (ds->dotdotdir) {
 			log_err( _("Already found '..' entry in directory %llu"
 				"(0x%llx)\n"),
 				(unsigned long long)ip->i_di.di_num.no_addr,
 				(unsigned long long)ip->i_di.di_num.no_addr);
-			if(!query( _("Clear duplicate '..' entry? (y/n) "))) {
+			if (!query( _("Clear duplicate '..' entry? (y/n) "))) {
 				log_err( _("Duplicate '..' entry remains\n"));
 				/* FIXME: Should we continue on here
 				 * and check the rest of the '..'
@@ -431,12 +433,12 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 			goto nuke_dentry;
 		}
 
-		if(q != gfs2_inode_dir) {
+		if (q != gfs2_inode_dir) {
 			log_err( _("Found '..' entry in directory %llu (0x%llx) "
 				"pointing to something that's not a directory"),
 				(unsigned long long)ip->i_di.di_num.no_addr,
 				(unsigned long long)ip->i_di.di_num.no_addr);
-			if(!query( _("Clear bad '..' directory entry? (y/n) "))) {
+			if (!query( _("Clear bad '..' directory entry? (y/n) "))) {
 				log_err( _("Bad '..' directory entry remains\n"));
 				goto dentry_is_valid;
 			}
@@ -455,7 +457,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 		/* Add the address this entry is pointing to
 		 * to this inode's dotdot_parent in
 		 * dir_info */
-		if(set_dotdot_dir(sdp, ip->i_di.di_num.no_addr, entryblock)) {
+		if (set_dotdot_dir(sdp, ip->i_di.di_num.no_addr, entryblock)) {
 			stack;
 			return -1;
 		}
@@ -465,7 +467,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 	}
 
 	/* After this point we're only concerned with directories */
-	if(q != gfs2_inode_dir) {
+	if (q != gfs2_inode_dir) {
 		log_debug( _("Found non-dir inode dentry pointing to %lld "
 			     "(0x%llx)\n"),
 			   (unsigned long long)entryblock,
@@ -475,11 +477,13 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 
 	/*log_debug( _("Found plain directory dentry\n"));*/
 	error = set_parent_dir(sdp, entryblock, ip->i_di.di_num.no_addr);
-	if(error > 0) {
-		log_err( _("%s: Hard link to block %" PRIu64" (0x%" PRIx64
-			   ") detected.\n"), tmp_name, entryblock, entryblock);
+	if (error > 0) {
+		log_err( _("%s: Hard link to block %llu (0x%llx"
+			   ") detected.\n"), tmp_name,
+			(unsigned long long)entryblock,
+			(unsigned long long)entryblock);
 
-		if(query( _("Clear hard link to directory? (y/n) ")))
+		if (query( _("Clear hard link to directory? (y/n) ")))
 			goto nuke_dentry;
 		else {
 			log_err( _("Hard link to directory remains\n"));
@@ -535,7 +539,7 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
 		ds.q = block_type(iblock);
 	}
 	pass2_fxns.private = (void *) &ds;
-	if(ds.q == gfs2_bad_block) {
+	if (ds.q == gfs2_bad_block) {
 		/* First check that the directory's metatree is valid */
 		error = check_metatree(sysinode, &pass2_fxns);
 		if (error < 0) {
@@ -546,7 +550,7 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
 	error = check_dir(sysinode->i_sbd, iblock, &pass2_fxns);
 	if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
 		return FSCK_OK;
-	if(error < 0) {
+	if (error < 0) {
 		stack;
 		return -1;
 	}
@@ -554,23 +558,23 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
 		fsck_blockmap_set(sysinode, iblock, dirname,
 				  gfs2_inode_invalid);
 
-	if(check_inode_eattr(sysinode, &pass2_fxns)) {
+	if (check_inode_eattr(sysinode, &pass2_fxns)) {
 		stack;
 		return -1;
 	}
-	if(!ds.dotdir) {
+	if (!ds.dotdir) {
 		log_err( _("No '.' entry found for %s directory.\n"), dirname);
 		if (query( _("Is it okay to add '.' entry? (y/n) "))) {
 			uint64_t cur_blks = sysinode->i_di.di_blocks;
 
 			sprintf(tmp_name, ".");
 			filename_len = strlen(tmp_name); /* no trailing NULL */
-			if(!(filename = malloc(sizeof(char) * filename_len))) {
+			if (!(filename = malloc(sizeof(char) * filename_len))) {
 				log_err( _("Unable to allocate name string\n"));
 				stack;
 				return -1;
 			}
-			if(!(memset(filename, 0, sizeof(char) *
+			if (!(memset(filename, 0, sizeof(char) *
 				    filename_len))) {
 				log_err( _("Unable to zero name string\n"));
 				stack;
@@ -591,13 +595,13 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
 		} else
 			log_err( _("The directory was not fixed.\n"));
 	}
-	if(sysinode->i_di.di_entries != ds.entry_count) {
+	if (sysinode->i_di.di_entries != ds.entry_count) {
 		log_err( _("%s inode %llu (0x%llx"
 			"): Entries is %d - should be %d\n"), dirname,
 			(unsigned long long)sysinode->i_di.di_num.no_addr,
 			(unsigned long long)sysinode->i_di.di_num.no_addr,
 			sysinode->i_di.di_entries, ds.entry_count);
-		if(query( _("Fix entries for %s inode %llu (0x%llx)? (y/n) "),
+		if (query( _("Fix entries for %s inode %llu (0x%llx)? (y/n) "),
 			  dirname,
 			  (unsigned long long)sysinode->i_di.di_num.no_addr,
 			  (unsigned long long)sysinode->i_di.di_num.no_addr)) {
@@ -689,7 +693,7 @@ int pass2(struct gfs2_sbd *sdp)
 
 		q = block_type(dirblk);
 
-		if(q != gfs2_inode_dir)
+		if (q != gfs2_inode_dir)
 			continue;
 
 		log_debug( _("Checking directory inode at block %"PRIu64" (0x%"
@@ -697,7 +701,7 @@ int pass2(struct gfs2_sbd *sdp)
 
 		memset(&ds, 0, sizeof(ds));
 		pass2_fxns.private = (void *) &ds;
-		if(ds.q == gfs2_bad_block) {
+		if (ds.q == gfs2_bad_block) {
 			/* First check that the directory's metatree
 			 * is valid */
 			ip = fsck_load_inode(sdp, dirblk);
@@ -711,7 +715,7 @@ int pass2(struct gfs2_sbd *sdp)
 		error = check_dir(sdp, dirblk, &pass2_fxns);
 		if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
 			return FSCK_OK;
-		if(error < 0) {
+		if (error < 0) {
 			stack;
 			return FSCK_ERROR;
 		}
@@ -719,11 +723,11 @@ int pass2(struct gfs2_sbd *sdp)
 			struct dir_info *di;
 
 			di = dirtree_find(dirblk);
-			if(!di) {
+			if (!di) {
 				stack;
 				return FSCK_ERROR;
 			}
-			if(query( _("Remove directory entry for bad"
+			if (query( _("Remove directory entry for bad"
 				    " inode %llu (0x%llx) in %llu"
 				    " (0x%llx)? (y/n)"),
 				  (unsigned long long)dirblk,
@@ -732,17 +736,18 @@ int pass2(struct gfs2_sbd *sdp)
 				  (unsigned long long)di->treewalk_parent)) {
 				error = remove_dentry_from_dir(sdp, di->treewalk_parent,
 							       dirblk);
-				if(error < 0) {
+				if (error < 0) {
 					stack;
 					return FSCK_ERROR;
 				}
-				if(error > 0) {
-					log_warn( _("Unable to find dentry for %"
-						    PRIu64 " (0x%" PRIx64 ") in %" PRIu64
-						    " (0x%" PRIx64 ")\n"),
-						  dirblk, dirblk,
-						  di->treewalk_parent,
-						  di->treewalk_parent);
+				if (error > 0) {
+					log_warn( _("Unable to find dentry for %llu"
+						    " (0x%llx) in %llu"
+						    " (0x%llx)\n"),
+						  (unsigned long long)dirblk,
+						  (unsigned long long)dirblk,
+						  (unsigned long long)di->treewalk_parent,
+						  (unsigned long long)di->treewalk_parent);
 				}
 				log_warn( _("Directory entry removed\n"));
 			} else
@@ -757,7 +762,7 @@ int pass2(struct gfs2_sbd *sdp)
 			check_n_fix_bitmap(sdp, dirblk, gfs2_inode_invalid);
 		}
 		ip = fsck_load_inode(sdp, dirblk);
-		if(!ds.dotdir) {
+		if (!ds.dotdir) {
 			log_err(_("No '.' entry found for directory inode at "
 				  "block %"PRIu64" (0x%" PRIx64 ")\n"),
 				dirblk, dirblk);
@@ -768,13 +773,13 @@ int pass2(struct gfs2_sbd *sdp)
 				sprintf(tmp_name, ".");
 				filename_len = strlen(tmp_name); /* no trailing
 								    NULL */
-				if(!(filename = malloc(sizeof(char) *
+				if (!(filename = malloc(sizeof(char) *
 						       filename_len))) {
 					log_err(_("Unable to allocate name\n"));
 					stack;
 					return FSCK_ERROR;
 				}
-				if(!memset(filename, 0, sizeof(char) *
+				if (!memset(filename, 0, sizeof(char) *
 					   filename_len)) {
 					log_err( _("Unable to zero name\n"));
 					stack;
@@ -806,7 +811,7 @@ int pass2(struct gfs2_sbd *sdp)
 			}
 		}
 
-		if(!fsck_abort && ip->i_di.di_entries != ds.entry_count) {
+		if (!fsck_abort && ip->i_di.di_entries != ds.entry_count) {
 			log_err( _("Entries is %d - should be %d for inode "
 				"block %llu (0x%llx)\n"),
 				ip->i_di.di_entries, ds.entry_count,
diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c
index c2bc0f9..f6cbbc2 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -32,14 +32,14 @@ static int attach_dotdot_to(struct gfs2_sbd *sdp, uint64_t newdotdot,
 	 * this case? */
 
 	filename_len = strlen("..");
-	if(!(filename = malloc((sizeof(char) * filename_len) + 1))) {
+	if (!(filename = malloc((sizeof(char) * filename_len) + 1))) {
 		log_err( _("Unable to allocate name\n"));
 		fsck_inode_put(&ip);
 		fsck_inode_put(&pip);
 		stack;
 		return -1;
 	}
-	if(!memset(filename, 0, (sizeof(char) * filename_len) + 1)) {
+	if (!memset(filename, 0, (sizeof(char) * filename_len) + 1)) {
 		log_err( _("Unable to zero name\n"));
 		fsck_inode_put(&ip);
 		fsck_inode_put(&pip);
@@ -47,7 +47,7 @@ static int attach_dotdot_to(struct gfs2_sbd *sdp, uint64_t newdotdot,
 		return -1;
 	}
 	memcpy(filename, "..", filename_len);
-	if(gfs2_dirent_del(ip, filename, filename_len))
+	if (gfs2_dirent_del(ip, filename, filename_len))
 		log_warn( _("Unable to remove \"..\" directory entry.\n"));
 	else
 		decrement_link(olddotdot, block, _("old \"..\""));
@@ -76,16 +76,19 @@ static struct dir_info *mark_and_return_parent(struct gfs2_sbd *sdp,
 
 	di->checked = 1;
 
-	if(!di->treewalk_parent)
+	if (!di->treewalk_parent)
 		return NULL;
 
-	if(di->dotdot_parent != di->treewalk_parent) {
-		log_warn( _("Directory '..' and treewalk connections disagree for inode %"
-				 PRIu64 " (0x%" PRIx64 ")\n"), di->dinode, di->dinode);
-		log_notice( _("'..' has %" PRIu64" (0x%" PRIx64 "), treewalk has %"
-				   PRIu64" (0x%" PRIx64 ")\n"), di->dotdot_parent,
-				   di->dotdot_parent, di->treewalk_parent,
-				   di->treewalk_parent);
+	if (di->dotdot_parent != di->treewalk_parent) {
+		log_warn( _("Directory '..' and treewalk connections disagree for inode %llu"
+				 " (0x%llx)\n"), (unsigned long long)di->dinode,
+			(unsigned long long)di->dinode);
+		log_notice( _("'..' has %llu (0x%llx), treewalk has %llu"
+			      " (0x%llx)\n"),
+			   (unsigned long long)di->dotdot_parent,
+			   (unsigned long long)di->dotdot_parent,
+			   (unsigned long long)di->treewalk_parent,
+			   (unsigned long long)di->treewalk_parent);
 		q_dotdot = block_type(di->dotdot_parent);
 		q_treewalk = block_type(di->treewalk_parent);
 		/* if the dotdot entry isn't a directory, but the
@@ -95,8 +98,8 @@ static struct dir_info *mark_and_return_parent(struct gfs2_sbd *sdp,
 		 * choose? if neither are directories, we have a
 		 * problem - need to move this directory into lost+found
 		 */
-		if(q_dotdot != gfs2_inode_dir) {
-			if(q_treewalk != gfs2_inode_dir) {
+		if (q_dotdot != gfs2_inode_dir) {
+			if (q_treewalk != gfs2_inode_dir) {
 				log_err( _("Orphaned directory, move to lost+found\n"));
 				return NULL;
 			}
@@ -110,14 +113,14 @@ static struct dir_info *mark_and_return_parent(struct gfs2_sbd *sdp,
 				di->dotdot_parent = di->treewalk_parent;
 			}
 		} else {
-			if(q_treewalk != gfs2_inode_dir) {
+			if (q_treewalk != gfs2_inode_dir) {
 				int error = 0;
 				log_warn( _(".. parent is valid, but treewalk"
 						 "is bad - reattaching to lost+found"));
 
 				/* FIXME: add a dinode for this entry instead? */
 
-				if(query( _("Remove directory entry for bad"
+				if (query( _("Remove directory entry for bad"
 					    " inode %llu (0x%llx) in %llu"
 					    " (0x%llx)? (y/n)"),
 					(unsigned long long)di->dinode,
@@ -126,15 +129,17 @@ static struct dir_info *mark_and_return_parent(struct gfs2_sbd *sdp,
 					(unsigned long long)di->treewalk_parent)) {
 					error = remove_dentry_from_dir(sdp, di->treewalk_parent,
 												   di->dinode);
-					if(error < 0) {
+					if (error < 0) {
 						stack;
 						return NULL;
 					}
-					if(error > 0) {
-						log_warn( _("Unable to find dentry for block %"
-								 PRIu64" (0x%" PRIx64 ") in %" PRIu64 " (0x%"
-								 PRIx64 ")\n"),di->dinode, di->dinode,
-								 di->treewalk_parent, di->treewalk_parent);
+					if (error > 0) {
+						log_warn( _("Unable to find dentry for block %llu"
+							" (0x%llx) in %llu (0x%llx)\n"),
+							 (unsigned long long)di->dinode,
+							(unsigned long long)di->dinode,
+							(unsigned long long)di->treewalk_parent,
+							(unsigned long long)di->treewalk_parent);
 					}
 					log_warn( _("Directory entry removed\n"));
 				} else {
@@ -157,9 +162,10 @@ static struct dir_info *mark_and_return_parent(struct gfs2_sbd *sdp,
 	}
 	else {
 		q_dotdot = block_type(di->dotdot_parent);
-		if(q_dotdot != gfs2_inode_dir) {
-			log_err( _("Orphaned directory at block %" PRIu64 " (0x%" PRIx64
-					") moved to lost+found\n"), di->dinode, di->dinode);
+		if (q_dotdot != gfs2_inode_dir) {
+			log_err( _("Orphaned directory at block %llu (0x%llx) moved to lost+found\n"),
+				(unsigned long long)di->dinode,
+				(unsigned long long)di->dinode);
 			return NULL;
 		}
 	}
@@ -200,7 +206,7 @@ int pass3(struct gfs2_sbd *sdp)
 	for (tmp = osi_first(&dirtree); tmp; tmp = next) {
 		next = osi_next(tmp);
 		di = (struct dir_info *)tmp;
-		while(!di->checked) {
+		while (!di->checked) {
 			/* FIXME: Change this so it returns success or
 			 * failure and put the parent inode in a
 			 * param */
@@ -216,10 +222,10 @@ int pass3(struct gfs2_sbd *sdp)
 				continue;
 			}
 			q = block_type(di->dinode);
-			if(q == gfs2_bad_block) {
+			if (q == gfs2_bad_block) {
 				log_err( _("Found unlinked directory "
 					   "containing bad block\n"));
-				if(query(_("Clear unlinked directory "
+				if (query(_("Clear unlinked directory "
 					   "with bad blocks? (y/n) "))) {
 					log_warn( _("inode %lld (0x%llx) is "
 						    "now marked as free\n"),
@@ -237,13 +243,13 @@ int pass3(struct gfs2_sbd *sdp)
 				} else
 					log_err( _("Unlinked directory with bad block remains\n"));
 			}
-			if(q != gfs2_inode_dir && q != gfs2_inode_file &&
+			if (q != gfs2_inode_dir && q != gfs2_inode_file &&
 			   q != gfs2_inode_lnk && q != gfs2_inode_blk &&
 			   q != gfs2_inode_chr && q != gfs2_inode_fifo &&
 			   q != gfs2_inode_sock) {
 				log_err( _("Unlinked block marked as an inode "
 					   "is not an inode\n"));
-				if(!query(_("Clear the unlinked block?"
+				if (!query(_("Clear the unlinked block?"
 					    " (y/n) "))) {
 					log_err( _("The block was not "
 						   "cleared\n"));
@@ -268,10 +274,10 @@ int pass3(struct gfs2_sbd *sdp)
 				 (unsigned long long)di->dinode);
 			ip = fsck_load_inode(sdp, di->dinode);
 			/* Don't skip zero size directories with eattrs */
-			if(!ip->i_di.di_size && !ip->i_di.di_eattr){
+			if (!ip->i_di.di_size && !ip->i_di.di_eattr){
 				log_err( _("Unlinked directory has zero "
 					   "size.\n"));
-				if(query( _("Remove zero-size unlinked "
+				if (query( _("Remove zero-size unlinked "
 					    "directory? (y/n) "))) {
 					fsck_blockmap_set(ip, di->dinode,
 						_("zero-sized unlinked inode"),
@@ -283,9 +289,9 @@ int pass3(struct gfs2_sbd *sdp)
 						   "directory remains\n"));
 				}
 			}
-			if(query( _("Add unlinked directory to "
+			if (query( _("Add unlinked directory to "
 				    "lost+found? (y/n) "))) {
-				if(add_inode_to_lf(ip)) {
+				if (add_inode_to_lf(ip)) {
 					fsck_inode_put(&ip);
 					stack;
 					return FSCK_ERROR;
@@ -298,7 +304,7 @@ int pass3(struct gfs2_sbd *sdp)
 			break;
 		}
 	}
-	if(lf_dip)
+	if (lf_dip)
 		log_debug( _("At end of pass3, lost+found entries is %u\n"),
 				  lf_dip->i_di.di_entries);
 	return FSCK_OK;
diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c
index 0e17a05..1e52c3f 100644
--- a/gfs2/fsck/pass4.c
+++ b/gfs2/fsck/pass4.c
@@ -27,7 +27,7 @@ static int fix_link_count(struct inode_info *ii, struct gfs2_inode *ip)
 		  ip->i_di.di_nlink, ii->counted_links,
 		 (unsigned long long)ip->i_di.di_num.no_addr,
 		 (unsigned long long)ip->i_di.di_num.no_addr);
-	if(ip->i_di.di_nlink == ii->counted_links)
+	if (ip->i_di.di_nlink == ii->counted_links)
 		return 0;
 	ip->i_di.di_nlink = ii->counted_links;
 	bmodified(ip->i_bh);
@@ -52,20 +52,21 @@ static int scan_inode_list(struct gfs2_sbd *sdp) {
 		if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
 			return 0;
 		next = osi_next(tmp);
-		if(!(ii = (struct inode_info *)tmp)) {
+		if (!(ii = (struct inode_info *)tmp)) {
 			log_crit( _("osi_tree broken in scan_info_list!!\n"));
 			exit(FSCK_ERROR);
 		}
-		if(ii->counted_links == 0) {
-			log_err( _("Found unlinked inode at %" PRIu64 " (0x%" PRIx64 ")\n"),
-					ii->inode, ii->inode);
+		if (ii->counted_links == 0) {
+			log_err( _("Found unlinked inode at %llu (0x%llx)\n"),
+				(unsigned long long)ii->inode,
+				(unsigned long long)ii->inode);
 			q = block_type(ii->inode);
-			if(q == gfs2_bad_block) {
-				log_err( _("Unlinked inode %llu (0x%llx) contains"
+			if (q == gfs2_bad_block) {
+				log_err( _("Unlinked inode %llu (0x%llx) contains "
 					"bad blocks\n"),
 					(unsigned long long)ii->inode,
 					(unsigned long long)ii->inode);
-				if(query(  _("Delete unlinked inode with bad "
+				if (query(  _("Delete unlinked inode with bad "
 					     "blocks? (y/n) "))) {
 					ip = fsck_load_inode(sdp, ii->inode);
 					check_inode_eattr(ip,
@@ -79,7 +80,7 @@ static int scan_inode_list(struct gfs2_sbd *sdp) {
 				} else
 					log_err( _("Unlinked inode with bad blocks not cleared\n"));
 			}
-			if(q != gfs2_inode_dir &&
+			if (q != gfs2_inode_dir &&
 			   q != gfs2_inode_file &&
 			   q != gfs2_inode_lnk &&
 			   q != gfs2_inode_blk &&
@@ -92,7 +93,7 @@ static int scan_inode_list(struct gfs2_sbd *sdp) {
 					 (unsigned long long)ii->inode,
 					 (unsigned long long)ii->inode, q);
 				ip = fsck_load_inode(sdp, ii->inode);
-				if(query(_("Delete unlinked inode? (y/n) "))) {
+				if (query(_("Delete unlinked inode? (y/n) "))) {
 					check_inode_eattr(ip,
 							  &pass4_fxns_delete);
 					check_metatree(ip, &pass4_fxns_delete);
@@ -113,9 +114,9 @@ static int scan_inode_list(struct gfs2_sbd *sdp) {
 			/* We don't want to clear zero-size files with
 			 * eattrs - there might be relevent info in
 			 * them. */
-			if(!ip->i_di.di_size && !ip->i_di.di_eattr){
+			if (!ip->i_di.di_size && !ip->i_di.di_eattr){
 				log_err( _("Unlinked inode has zero size\n"));
-				if(query(_("Clear zero-size unlinked inode? "
+				if (query(_("Clear zero-size unlinked inode? "
 					   "(y/n) "))) {
 					fsck_blockmap_set(ip, ii->inode,
 						_("unlinked zero-length"),
@@ -125,9 +126,9 @@ static int scan_inode_list(struct gfs2_sbd *sdp) {
 				}
 
 			}
-			if(query( _("Add unlinked inode to lost+found? "
+			if (query( _("Add unlinked inode to lost+found? "
 				    "(y/n)"))) {
-				if(add_inode_to_lf(ip)) {
+				if (add_inode_to_lf(ip)) {
 					stack;
 					fsck_inode_put(&ip);
 					return -1;
@@ -138,14 +139,16 @@ static int scan_inode_list(struct gfs2_sbd *sdp) {
 			} else
 				log_err( _("Unlinked inode left unlinked\n"));
 			fsck_inode_put(&ip);
-		} /* if(ii->counted_links == 0) */
-		else if(ii->link_count != ii->counted_links) {
-			log_err( _("Link count inconsistent for inode %" PRIu64
-					" (0x%" PRIx64 ") has %u but fsck found %u.\n"), ii->inode, 
-					ii->inode, ii->link_count, ii->counted_links);
+		} /* if (ii->counted_links == 0) */
+		else if (ii->link_count != ii->counted_links) {
+			log_err( _("Link count inconsistent for inode %llu"
+				" (0x%llx) has %u but fsck found %u.\n"),
+				(unsigned long long)ii->inode, 
+				(unsigned long long)ii->inode, ii->link_count,
+				ii->counted_links);
 			/* Read in the inode, adjust the link count,
 			 * and write it back out */
-			if(query( _("Update link count for inode %llu"
+			if (query( _("Update link count for inode %llu"
 				    " (0x%llx) ? (y/n) "),
 				  (unsigned long long)ii->inode,
 				  (unsigned long long)ii->inode)) {
@@ -167,7 +170,7 @@ static int scan_inode_list(struct gfs2_sbd *sdp) {
 	} /* osi_list_foreach(tmp, list) */
 
 	if (lf_addition) {
-		if(!(ii = inodetree_find(lf_dip->i_di.di_num.no_addr))) {
+		if (!(ii = inodetree_find(lf_dip->i_di.di_num.no_addr))) {
 			log_crit( _("Unable to find lost+found inode in inode_hash!!\n"));
 			return -1;
 		} else {
@@ -189,16 +192,16 @@ static int scan_inode_list(struct gfs2_sbd *sdp) {
  */
 int pass4(struct gfs2_sbd *sdp)
 {
-	if(lf_dip)
+	if (lf_dip)
 		log_debug( _("At beginning of pass4, lost+found entries is %u\n"),
 				  lf_dip->i_di.di_entries);
 	log_info( _("Checking inode reference counts.\n"));
-	if(scan_inode_list(sdp)) {
+	if (scan_inode_list(sdp)) {
 		stack;
 		return FSCK_ERROR;
 	}
 
-	if(lf_dip)
+	if (lf_dip)
 		log_debug( _("At end of pass4, lost+found entries is %u\n"),
 				  lf_dip->i_di.di_entries);
 	return FSCK_OK;
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index db1870d..1811e5a 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -62,7 +62,7 @@ static int check_block_status(struct gfs2_sbd *sdp, char *buffer, unsigned int b
 	bit = 0;
 	end = (unsigned char *) buffer + buflen;
 
-	while(byte < end) {
+	while (byte < end) {
 		rg_status = ((*byte >> bit) & GFS2_BIT_MASK);
 		block = rg_data + *rg_block;
 		warm_fuzzy_stuff(block);
@@ -83,8 +83,8 @@ static int check_block_status(struct gfs2_sbd *sdp, char *buffer, unsigned int b
 				   "block %llu (0x%llx).\n"),
 				 (unsigned long long)block,
 				 (unsigned long long)block);
-			if(query(_("Do you want to fix the bitmap? (y/n) "))) {
-				if(gfs2_set_bitmap(sdp, block, block_status))
+			if (query(_("Do you want to fix the bitmap? (y/n) "))) {
+				if (gfs2_set_bitmap(sdp, block, block_status))
 					log_err(_("Unlinked block %llu "
 						  "(0x%llx) bitmap not fixed."
 						  "\n"),
@@ -112,10 +112,10 @@ static int check_block_status(struct gfs2_sbd *sdp, char *buffer, unsigned int b
 			log_err( _("Metadata type is %u (%s)\n"), q,
 					block_type_string(q));
 
-			if(query(_("Fix bitmap for block %llu (0x%llx) ? (y/n) "),
+			if (query(_("Fix bitmap for block %llu (0x%llx) ? (y/n) "),
 				 (unsigned long long)block,
 				 (unsigned long long)block)) {
-				if(gfs2_set_bitmap(sdp, block, block_status))
+				if (gfs2_set_bitmap(sdp, block, block_status))
 					log_err( _("Failed.\n"));
 				else
 					log_err( _("Succeeded.\n"));
@@ -153,7 +153,7 @@ static void update_rgrp(struct gfs2_sbd *sdp, struct rgrp_list *rgp,
 	}
 
 	/* actually adjust counters and write out to disk */
-	if(rgp->rg.rg_free != count[0]) {
+	if (rgp->rg.rg_free != count[0]) {
 		log_err( _("RG #%llu (0x%llx) free count inconsistent: "
 			"is %u should be %u\n"),
 			(unsigned long long)rgp->ri.ri_addr,
@@ -162,21 +162,21 @@ static void update_rgrp(struct gfs2_sbd *sdp, struct rgrp_list *rgp,
 		rgp->rg.rg_free = count[0];
 		update = 1;
 	}
-	if(rgp->rg.rg_dinodes != count[1]) {
+	if (rgp->rg.rg_dinodes != count[1]) {
 		log_err( _("Inode count inconsistent: is %u should be %u\n"),
 				rgp->rg.rg_dinodes, count[1]);
 		rgp->rg.rg_dinodes = count[1];
 		update = 1;
 	}
-	if((rgp->ri.ri_data - count[0] - count[1]) != count[2]) {
+	if ((rgp->ri.ri_data - count[0] - count[1]) != count[2]) {
 		/* FIXME not sure how to handle this case ATM - it
 		 * means that the total number of blocks we've counted
 		 * exceeds the blocks in the rg */
 		log_err( _("Internal fsck error - AAHHH!\n"));
 		exit(FSCK_ERROR);
 	}
-	if(update) {
-		if(query( _("Update resource group counts? (y/n) "))) {
+	if (update) {
+		if (query( _("Update resource group counts? (y/n) "))) {
 			log_warn( _("Resource group counts updated\n"));
 			/* write out the rgrp */
 			gfs2_rgrp_out(&rgp->rg, rgp->bh[0]);
diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c
index af5a02d..1bddacf 100644
--- a/gfs2/fsck/rgrepair.c
+++ b/gfs2/fsck/rgrepair.c
@@ -742,7 +742,7 @@ static void sort_rgrp_list(osi_list_t *head)
 	osi_list_t *tmp, *x, *next;
 	int swaps;
 
-	while(1) {
+	while (1) {
 		swaps = 0;
 		osi_list_foreach_safe(tmp, head, x) {
 			next = tmp->next;
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index 6fe05ab..adca24a 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -91,11 +91,11 @@ int fsck_query(const char *format, ...)
 
 	errors_found++;
 	fsck_abort = 0;
-	if(opts.yes) {
+	if (opts.yes) {
 		errors_corrected++;
 		return 1;
 	}
-	if(opts.no)
+	if (opts.no)
 		return 0;
 
 	opts.query = TRUE;
@@ -123,7 +123,7 @@ int fsck_query(const char *format, ...)
 				break;
 			}
 			printf("Continuing.\n");
-		} else if(tolower(response) == 'y') {
+		} else if (tolower(response) == 'y') {
 			errors_corrected++;
                         ret = 1;
                         break;
@@ -253,12 +253,12 @@ int add_duplicate_ref(struct gfs2_inode *ip, uint64_t block,
 		/* Check for the inode on the invalid inode reference list. */
 		uint8_t q;
 
-		if(!(found_id = malloc(sizeof(*found_id)))) {
+		if (!(found_id = malloc(sizeof(*found_id)))) {
 			log_crit( _("Unable to allocate "
 				    "inode_with_dups structure\n"));
 			return -1;
 		}
-		if(!(memset(found_id, 0, sizeof(*found_id)))) {
+		if (!(memset(found_id, 0, sizeof(*found_id)))) {
 			log_crit( _("Unable to zero inode_with_dups "
 				    "structure\n"));
 			return -1;
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 03/66] libgfs1: Add gfs1 variable to superblock structure
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 01/66] fsck.gfs2: Make functions use sdp rather than sbp rpeterso
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 02/66] fsck.gfs2: Change "if(" to "if (" rpeterso
@ 2012-01-20 15:09 ` rpeterso
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 04/66] libgfs2: Make check_sb and read_sb operate on gfs1 rpeterso
                   ` (62 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:09 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch adds a "gfs1" variable to the in-core superblock structure
for utils that can operate on both gfs and gfs2 file systems and need
to determine which is which.

rhbz#675723
---
 gfs2/edit/extended.c   |   10 ++--
 gfs2/edit/gfs2hex.c    |   13 +++---
 gfs2/edit/hexedit.c    |  111 ++++++++++++++++++++++++------------------------
 gfs2/edit/hexedit.h    |    3 +-
 gfs2/edit/savemeta.c   |   30 ++++++------
 gfs2/libgfs2/libgfs2.h |    1 +
 6 files changed, 84 insertions(+), 84 deletions(-)

diff --git a/gfs2/edit/extended.c b/gfs2/edit/extended.c
index 3c45060..059f18b 100644
--- a/gfs2/edit/extended.c
+++ b/gfs2/edit/extended.c
@@ -64,7 +64,7 @@ static int _do_indirect_extended(char *diebuf, struct iinfo *iinf, int hgt)
 		iinf->ii[x].dirents = 0;
 		memset(&iinf->ii[x].dirent, 0, sizeof(struct gfs2_dirents));
 	}
-	for (x = (gfs1 ? sizeof(struct gfs_indirect):
+	for (x = (sbd.gfs1 ? sizeof(struct gfs_indirect):
 			  sizeof(struct gfs2_meta_header)), y = 0;
 		 x < sbd.bsize;
 		 x += sizeof(uint64_t), y++) {
@@ -250,7 +250,7 @@ static int display_indirect(struct iinfo *ind, int indblocks, int level,
 /* ------------------------------------------------------------------------ */
 static void print_inode_type(__be16 de_type)
 {
-	if (gfs1) {
+	if (sbd.gfs1) {
 		switch(de_type) {
 		case GFS_FILE_NON:
 			print_gfs2("Unknown");
@@ -514,7 +514,7 @@ static int parse_rindex(struct gfs2_inode *dip, int print_rindex)
 
 		roff = print_entry_ndx * risize();
 
-		if (gfs1)
+		if (sbd.gfs1)
 			error = gfs1_readi(dip, (void *)&rbuf, roff, risize());
 		else
 			error = gfs2_readi(dip, (void *)&rbuf, roff, risize());
@@ -542,7 +542,7 @@ static int parse_rindex(struct gfs2_inode *dip, int print_rindex)
 				struct gfs2_buffer_head *tmp_bh;
 
 				tmp_bh = bread(&sbd, ri.ri_addr);
-				if (gfs1) {
+				if (sbd.gfs1) {
 					struct gfs_rgrp rg1;
 					gfs_rgrp_in(&rg1, tmp_bh);
 					gfs_rgrp_print(&rg1);
@@ -663,7 +663,7 @@ int display_extended(void)
 	else if (display_indirect(indirect, indirect_blocks, 0, 0) == 0)
 		return -1;
 	else if (block_is_rglist()) {
-		if (gfs1)
+		if (sbd.gfs1)
 			tmp_bh = bread(&sbd, sbd1->sb_rindex_di.no_addr);
 		else
 			tmp_bh = bread(&sbd, masterblock("rindex"));
diff --git a/gfs2/edit/gfs2hex.c b/gfs2/edit/gfs2hex.c
index 0f8a84a5..7962228 100644
--- a/gfs2/edit/gfs2hex.c
+++ b/gfs2/edit/gfs2hex.c
@@ -43,7 +43,6 @@ uint64_t block = 0;
 int blockhist = 0;
 struct iinfo *indirect;
 int indirect_blocks;
-int gfs1  = 0;
 uint64_t block_in_mem = -1;
 struct gfs2_sbd sbd;
 uint64_t starting_blk;
@@ -275,7 +274,7 @@ void do_dinode_extended(struct gfs2_dinode *dine, struct gfs2_buffer_head *lbh)
 	unsigned int x, y, ptroff = 0;
 	uint64_t p, last;
 	int isdir = !!(S_ISDIR(dine->di_mode)) || 
-		(gfs1 && dine->__pad1 == GFS_FILE_DIR);
+		(sbd.gfs1 && dine->__pad1 == GFS_FILE_DIR);
 
 	indirect_blocks = 0;
 	memset(indirect, 0, sizeof(indirect));
@@ -466,11 +465,11 @@ static void gfs2_sb_print2(struct gfs2_sb *sbp2)
 	pv(sbp2, sb_fs_format, "%u", "0x%x");
 	pv(sbp2, sb_multihost_format, "%u", "0x%x");
 
-	if (gfs1)
+	if (sbd.gfs1)
 		pv(sbd1, sb_flags, "%u", "0x%x");
 	pv(sbp2, sb_bsize, "%u", "0x%x");
 	pv(sbp2, sb_bsize_shift, "%u", "0x%x");
-	if (gfs1) {
+	if (sbd.gfs1) {
 		pv(sbd1, sb_seg_size, "%u", "0x%x");
 		gfs2_inum_print2("jindex ino", &sbd1->sb_jindex_di);
 		gfs2_inum_print2("rindex ino", &sbd1->sb_rindex_di);
@@ -481,7 +480,7 @@ static void gfs2_sb_print2(struct gfs2_sb *sbp2)
 
 	pv(sbp2, sb_lockproto, "%s", NULL);
 	pv(sbp2, sb_locktable, "%s", NULL);
-	if (gfs1) {
+	if (sbd.gfs1) {
 		gfs2_inum_print2("quota ino ", &gfs1_quota_di);
 		gfs2_inum_print2("license   ", &gfs1_license_di);
 	}
@@ -573,7 +572,7 @@ int display_gfs2(void)
 			break;
 
 		case GFS2_METATYPE_RG:
-			if (gfs1) {
+			if (sbd.gfs1) {
 				struct gfs1_rgrp rg1;
 
 				gfs1_rgrp_in(&rg1, bh);
@@ -606,7 +605,7 @@ int display_gfs2(void)
 			break;
 
 		case GFS2_METATYPE_LH:
-			if (gfs1) {
+			if (sbd.gfs1) {
 				gfs_log_header_in(&lh1, bh);
 				gfs_log_header_print(&lh1);
 			} else {
diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index d908169..79a297e 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -1067,13 +1067,14 @@ int display_block_type(int from_restore)
 		print_gfs2("of %llu (0x%llx) ", max_block, max_block);
 	if (block == RGLIST_DUMMY_BLOCK) {
 		ret_type = GFS2_METATYPE_RG;
-		struct_len = gfs1 ? sizeof(struct gfs_rgrp) : sizeof(struct gfs2_rgrp);
+		struct_len = sbd.gfs1 ? sizeof(struct gfs_rgrp) :
+			sizeof(struct gfs2_rgrp);
 	}
 	else if ((ret_type = get_block_type(bh))) {
 		switch (*(bh->b_data + 7)) {
 		case GFS2_METATYPE_SB:   /* 1 */
 			print_gfs2("(superblock)");
-			if (gfs1)
+			if (sbd.gfs1)
 				struct_len = sizeof(struct gfs_sb);
 			else
 				struct_len = sizeof(struct gfs2_sb);
@@ -1092,7 +1093,7 @@ int display_block_type(int from_restore)
 			break;
 		case GFS2_METATYPE_IN:   /* 5 */
 			print_gfs2("(indir blklist)");
-			if (gfs1)
+			if (sbd.gfs1)
 				struct_len = sizeof(struct gfs_indirect);
 			else
 				struct_len = sizeof(struct gfs2_meta_header);
@@ -1111,7 +1112,7 @@ int display_block_type(int from_restore)
 			break;
 		case GFS2_METATYPE_LD:
 		 	print_gfs2("(log descriptor)");
-			if (gfs1)
+			if (sbd.gfs1)
 				struct_len = sizeof(struct gfs_log_descriptor);
 			else
 				struct_len =
@@ -1166,7 +1167,7 @@ int display_block_type(int from_restore)
 		print_gfs2("(p.%d of %d--%s)", pgnum + 1,
 			   (sbd.bsize % screen_chunk_size) > 0 ?
 			   sbd.bsize / screen_chunk_size + 1 : sbd.bsize /
-			   screen_chunk_size, allocdesc[gfs1][type]);
+			   screen_chunk_size, allocdesc[sbd.gfs1][type]);
 		/*eol(9);*/
 		if ((*(bh->b_data + 7) == GFS2_METATYPE_RG)) {
 			int ptroffset = edit_row[dmode] * 16 + edit_col[dmode];
@@ -1183,7 +1184,7 @@ int display_block_type(int from_restore)
 				for (b = blknum; b < blknum + 4; b++) {
 					btype = gfs2_get_bitmap(&sbd, b, rgd);
 					print_gfs2("0x%x-%s  ", b,
-						   allocdesc[gfs1][btype]);
+						   allocdesc[sbd.gfs1][btype]);
 				}
 			}
 		} else if ((*(bh->b_data + 7) == GFS2_METATYPE_RB)) {
@@ -1215,7 +1216,7 @@ int display_block_type(int from_restore)
 				for (b = blknum; b < blknum + 4; b++) {
 					btype = gfs2_get_bitmap(&sbd, b, rgd);
 					print_gfs2("0x%x-%s  ", b,
-						   allocdesc[gfs1][btype]);
+						   allocdesc[sbd.gfs1][btype]);
 				}
 			}
 		}
@@ -1224,12 +1225,12 @@ int display_block_type(int from_restore)
  	}
 	if (block == sbd.sd_sb.sb_root_dir.no_addr)
 		print_gfs2("--------------- Root directory ------------------");
-	else if (!gfs1 && block == sbd.sd_sb.sb_master_dir.no_addr)
+	else if (!sbd.gfs1 && block == sbd.sd_sb.sb_master_dir.no_addr)
 		print_gfs2("-------------- Master directory -----------------");
-	else if (!gfs1 && block == RGLIST_DUMMY_BLOCK)
+	else if (!sbd.gfs1 && block == RGLIST_DUMMY_BLOCK)
 		print_gfs2("------------------ RG List ----------------------");
 	else {
-		if (gfs1) {
+		if (sbd.gfs1) {
 			if (block == sbd1->sb_rindex_di.no_addr)
 				print_gfs2("---------------- rindex file -------------------");
 			else if (block == gfs1_quota_di.no_addr)
@@ -1435,7 +1436,7 @@ static int hexdump(uint64_t startaddr, int len)
 		l+=16;
 		print_entry_ndx++;
 	} /* while */
-	if (gfs1) {
+	if (sbd.gfs1) {
 		COLORS_NORMAL;
 		print_gfs2("         *** This seems to be a GFS-1 file system ***");
 		eol(0);
@@ -1479,7 +1480,7 @@ static uint64_t find_rgrp_block(struct gfs2_inode *dif, int rg)
 	uint64_t foffset, gfs1_adj = 0;
 
 	foffset = rg * risize();
-	if (gfs1) {
+	if (sbd.gfs1) {
 		uint64_t sd_jbsize =
 			(sbd.bsize - sizeof(struct gfs2_meta_header));
 
@@ -1551,7 +1552,7 @@ static uint64_t get_rg_addr(int rgnum)
 	uint64_t rgblk = 0, gblock;
 	struct gfs2_inode *riinode;
 
-	if (gfs1)
+	if (sbd.gfs1)
 		gblock = sbd1->sb_rindex_di.no_addr;
 	else
 		gblock = masterblock("rindex");
@@ -1583,7 +1584,7 @@ static void set_rgrp_flags(int rgnum, uint32_t new_flags, int modify, int full)
 
 	rgblk = get_rg_addr(rgnum);
 	rbh = bread(&sbd, rgblk);
-	if (gfs1)
+	if (sbd.gfs1)
 		gfs_rgrp_in(&rg.rg1, rbh);
 	else
 		gfs2_rgrp_in(&rg.rg2, rbh);
@@ -1592,7 +1593,7 @@ static void set_rgrp_flags(int rgnum, uint32_t new_flags, int modify, int full)
 		       rgnum, (unsigned long long)rgblk,
 		       (unsigned long long)rgblk, rg.rg2.rg_flags, new_flags);
 		rg.rg2.rg_flags = new_flags;
-		if (gfs1)
+		if (sbd.gfs1)
 			gfs_rgrp_out(&rg.rg1, rbh);
 		else
 			gfs2_rgrp_out(&rg.rg2, rbh);
@@ -1602,7 +1603,7 @@ static void set_rgrp_flags(int rgnum, uint32_t new_flags, int modify, int full)
 			print_gfs2("RG #%d", rgnum);
 			print_gfs2(" located at: %llu (0x%llx)", rgblk, rgblk);
                         eol(0);
-			if (gfs1)
+			if (sbd.gfs1)
 				gfs_rgrp_print(&rg.rg1);
 			else
 				gfs2_rgrp_print(&rg.rg2);
@@ -1638,7 +1639,7 @@ int has_indirect_blocks(void)
 	if (indirect_blocks || gfs2_struct_type == GFS2_METATYPE_SB ||
 	    gfs2_struct_type == GFS2_METATYPE_LF ||
 	    (gfs2_struct_type == GFS2_METATYPE_DI &&
-	     (S_ISDIR(di.di_mode) || (gfs1 && di.__pad1 == GFS_FILE_DIR))))
+	     (S_ISDIR(di.di_mode) || (sbd.gfs1 && di.__pad1 == GFS_FILE_DIR))))
 		return TRUE;
 	return FALSE;
 }
@@ -1648,7 +1649,7 @@ int has_indirect_blocks(void)
 /* ------------------------------------------------------------------------ */
 int block_is_rindex(void)
 {
-	if ((gfs1 && block == sbd1->sb_rindex_di.no_addr) ||
+	if ((sbd.gfs1 && block == sbd1->sb_rindex_di.no_addr) ||
 	    (block == masterblock("rindex")))
 		return TRUE;
 	return FALSE;
@@ -1659,7 +1660,7 @@ int block_is_rindex(void)
 /* ------------------------------------------------------------------------ */
 int block_is_jindex(void)
 {
-	if ((gfs1 && block == sbd1->sb_jindex_di.no_addr))
+	if ((sbd.gfs1 && block == sbd1->sb_jindex_di.no_addr))
 		return TRUE;
 	return FALSE;
 }
@@ -1669,7 +1670,7 @@ int block_is_jindex(void)
 /* ------------------------------------------------------------------------ */
 int block_is_inum_file(void)
 {
-	if (!gfs1 && block == masterblock("inum"))
+	if (!sbd.gfs1 && block == masterblock("inum"))
 		return TRUE;
 	return FALSE;
 }
@@ -1679,9 +1680,9 @@ int block_is_inum_file(void)
 /* ------------------------------------------------------------------------ */
 int block_is_statfs_file(void)
 {
-	if (gfs1 && block == gfs1_license_di.no_addr)
+	if (sbd.gfs1 && block == gfs1_license_di.no_addr)
 		return TRUE;
-	if (!gfs1 && block == masterblock("statfs"))
+	if (!sbd.gfs1 && block == masterblock("statfs"))
 		return TRUE;
 	return FALSE;
 }
@@ -1691,9 +1692,9 @@ int block_is_statfs_file(void)
 /* ------------------------------------------------------------------------ */
 int block_is_quota_file(void)
 {
-	if (gfs1 && block == gfs1_quota_di.no_addr)
+	if (sbd.gfs1 && block == gfs1_quota_di.no_addr)
 		return TRUE;
-	if (!gfs1 && block == masterblock("quota"))
+	if (!sbd.gfs1 && block == masterblock("quota"))
 		return TRUE;
 	return FALSE;
 }
@@ -1703,7 +1704,7 @@ int block_is_quota_file(void)
 /* ------------------------------------------------------------------------ */
 int block_is_per_node(void)
 {
-	if (!gfs1 && block == masterblock("per_node"))
+	if (!sbd.gfs1 && block == masterblock("per_node"))
 		return TRUE;
 	return FALSE;
 }
@@ -1716,7 +1717,7 @@ int block_is_in_per_node(void)
 	int d;
 	struct gfs2_inode *per_node_di;
 
-	if (gfs1)
+	if (sbd.gfs1)
 		return FALSE;
 
 	per_node_di = inode_read(&sbd, masterblock("per_node"));
@@ -1774,7 +1775,7 @@ static void read_superblock(int fd)
 		sbd1->sb_multihost_format == GFS_FORMAT_MULTI) {
 		struct gfs_sb *sbbuf = (struct gfs_sb *)bh->b_data;
 
-		gfs1 = TRUE;
+		sbd.gfs1 = TRUE;
 		sbd1->sb_flags = be32_to_cpu(sbbuf->sb_flags);
 		sbd1->sb_seg_size = be32_to_cpu(sbbuf->sb_seg_size);
 		gfs2_inum_in(&sbd1->sb_rindex_di, (void *)&sbbuf->sb_rindex_di);
@@ -1782,12 +1783,12 @@ static void read_superblock(int fd)
 		gfs2_inum_in(&gfs1_license_di, (void *)&sbbuf->sb_license_di);
 	}
 	else
-		gfs1 = FALSE;
+		sbd.gfs1 = FALSE;
 	sbd.bsize = sbd.sd_sb.sb_bsize;
 	if (!sbd.bsize)
 		sbd.bsize = GFS2_DEFAULT_BSIZE;
 	compute_constants(&sbd);
-	if (gfs1 || (sbd.sd_sb.sb_header.mh_magic == GFS2_MAGIC &&
+	if (sbd.gfs1 || (sbd.sd_sb.sb_header.mh_magic == GFS2_MAGIC &&
 		     sbd.sd_sb.sb_header.mh_type == GFS2_METATYPE_SB))
 		block = 0x10 * (GFS2_DEFAULT_BSIZE / sbd.bsize);
 	else {
@@ -1799,7 +1800,7 @@ static void read_superblock(int fd)
 				sbd.device.length << GFS2_BASIC_BLOCK_SHIFT);
 		exit(-1);
 	}
-	if(gfs1) {
+	if(sbd.gfs1) {
 		sbd.sd_inptrs = (sbd.bsize - sizeof(struct gfs_indirect)) /
 			sizeof(uint64_t);
 		sbd.sd_diptrs = (sbd.bsize - sizeof(struct gfs_dinode)) /
@@ -1854,7 +1855,7 @@ int display(int identify_only)
 	uint64_t blk;
 
 	if (block == RGLIST_DUMMY_BLOCK) {
-		if (gfs1)
+		if (sbd.gfs1)
 			blk = sbd1->sb_rindex_di.no_addr;
 		else
 			blk = masterblock("rindex");
@@ -2014,7 +2015,7 @@ static uint64_t find_journal_block(const char *journal, uint64_t *j_size)
 
 	journal_num = atoi(journal + 7);
 	/* Figure out the block of the jindex file */
-	if (gfs1)
+	if (sbd.gfs1)
 		jindex_block = sbd1->sb_jindex_di.no_addr;
 	else
 		jindex_block = masterblock("jindex");
@@ -2023,10 +2024,10 @@ static uint64_t find_journal_block(const char *journal, uint64_t *j_size)
 	/* get the dinode data from it. */
 	gfs2_dinode_in(&di, jindex_bh); /* parse disk inode to struct*/
 
-	if (!gfs1)
+	if (!sbd.gfs1)
 		do_dinode_extended(&di, jindex_bh); /* parse dir. */
 
-	if (gfs1) {
+	if (sbd.gfs1) {
 		struct gfs2_inode *jiinode;
 		struct gfs_jindex ji;
 
@@ -2205,36 +2206,36 @@ uint64_t check_keywords(const char *kword)
 	else if (!strcmp(kword, "root") || !strcmp(kword, "rootdir"))
 		blk = sbd.sd_sb.sb_root_dir.no_addr;
 	else if (!strcmp(kword, "master")) {
-		if (!gfs1)
+		if (!sbd.gfs1)
 			blk = sbd.sd_sb.sb_master_dir.no_addr;
 		else
 			fprintf(stderr, "This is GFS1; there's no master directory.\n");
 	}
 	else if (!strcmp(kword, "jindex")) {
-		if (gfs1)
+		if (sbd.gfs1)
 			blk = sbd1->sb_jindex_di.no_addr;
 		else
 			blk = masterblock("jindex"); /* journal index */
 	}
-	else if (!gfs1 && !strcmp(kword, "per_node"))
+	else if (!sbd.gfs1 && !strcmp(kword, "per_node"))
 		blk = masterblock("per_node");
-	else if (!gfs1 && !strcmp(kword, "inum"))
+	else if (!sbd.gfs1 && !strcmp(kword, "inum"))
 		blk = masterblock("inum");
 	else if (!strcmp(kword, "statfs")) {
-		if (gfs1)
+		if (sbd.gfs1)
 			blk = gfs1_license_di.no_addr;
 		else
 			blk = masterblock("statfs");
 	}
 	else if (!strcmp(kword, "rindex") || !strcmp(kword, "rgindex")) {
-		if (gfs1)
+		if (sbd.gfs1)
 			blk = sbd1->sb_rindex_di.no_addr;
 		else
 			blk = masterblock("rindex");
 	} else if (!strcmp(kword, "rgs")) {
 		blk = RGLIST_DUMMY_BLOCK;
 	} else if (!strcmp(kword, "quota")) {
-		if (gfs1)
+		if (sbd.gfs1)
 			blk = gfs1_quota_di.no_addr;
 		else
 			blk = masterblock("quota");
@@ -2550,7 +2551,7 @@ static void find_change_block_alloc(int *newval)
 		printf("Error: value %d is not valid.\nValid values are:\n",
 		       *newval);
 		for (i = GFS2_BLKST_FREE; i <= GFS2_BLKST_DINODE; i++)
-			printf("%d - %s\n", i, allocdesc[gfs1][i]);
+			printf("%d - %s\n", i, allocdesc[sbd.gfs1][i]);
 		gfs2_rgrp_free(&sbd.rglist);
 		exit(-1);
 	}
@@ -2573,7 +2574,7 @@ static void find_change_block_alloc(int *newval)
 					       "an rgrp).\n");
 					exit(-1);
 				}
-				printf("%d (%s)\n", type, allocdesc[gfs1][type]);
+				printf("%d (%s)\n", type, allocdesc[sbd.gfs1][type]);
 			}
 			gfs2_rgrp_relse(rgd);
 		} else {
@@ -3057,7 +3058,7 @@ static int print_ld_blocks(const uint64_t *b, const char *end, int start_line)
 			bcount++;
 		}
 		b++;
-		if (gfs1)
+		if (sbd.gfs1)
 			b++;
 	}
 	eol(0);
@@ -3176,14 +3177,14 @@ static void dump_journal(const char *journal)
 	jblock = find_journal_block(journal, &j_size);
 	if (!jblock)
 		return;
-	if (!gfs1) {
+	if (!sbd.gfs1) {
 		j_bh = bread(&sbd, jblock);
 		j_inode = inode_get(&sbd, j_bh);
 		jbuf = malloc(sbd.bsize);
 	}
 
-	for (jb = 0; jb < j_size; jb += (gfs1 ? 1:sbd.bsize)) {
-		if (gfs1) {
+	for (jb = 0; jb < j_size; jb += (sbd.gfs1 ? 1:sbd.bsize)) {
+		if (sbd.gfs1) {
 			if (j_bh)
 				brelse(j_bh);
 			j_bh = bread(&sbd, jblock + jb);
@@ -3218,21 +3219,21 @@ static void dump_journal(const char *journal)
 				 "Quota", "Final Entry", "Unknown"}};
 
 			print_gfs2("0x%llx (j+%4llx): Log descriptor, ",
-				   abs_block, jb / (gfs1 ? 1 : sbd.bsize));
+				   abs_block, jb / (sbd.gfs1 ? 1 : sbd.bsize));
 			gfs2_log_descriptor_in(&ld, &dummy_bh);
 			print_gfs2("type %d ", ld.ld_type);
 
 			for (ltndx = 0;; ltndx++) {
-				if (ld.ld_type == logtypes[gfs1][ltndx] ||
-				    logtypes[gfs1][ltndx] == 0)
+				if (ld.ld_type == logtypes[sbd.gfs1][ltndx] ||
+				    logtypes[sbd.gfs1][ltndx] == 0)
 					break;
 			}
-			print_gfs2("(%s) ", logtypestr[gfs1][ltndx]);
+			print_gfs2("(%s) ", logtypestr[sbd.gfs1][ltndx]);
 			print_gfs2("len:%u, data1: %u",
 				   ld.ld_length, ld.ld_data1);
 			eol(0);
 			print_gfs2("                    ");
-			if (gfs1)
+			if (sbd.gfs1)
 				b = (uint64_t *)(dummy_bh.b_data +
 					sizeof(struct gfs_log_descriptor));
 			else
@@ -3246,7 +3247,7 @@ static void dump_journal(const char *journal)
 			struct gfs2_log_header lh;
 			struct gfs_log_header lh1;
 
-			if (gfs1) {
+			if (sbd.gfs1) {
 				gfs_log_header_in(&lh1, &dummy_bh);
 				check_journal_wrap(lh1.lh_sequence,
 						   &highest_seq);
@@ -3268,7 +3269,7 @@ static void dump_journal(const char *journal)
 					   lh.lh_tail, lh.lh_blkno);
 			}
 			eol(0);
-		} else if (gfs1 && ld_blocks > 0) {
+		} else if (sbd.gfs1 && ld_blocks > 0) {
 			print_gfs2("0x%llx (j+%4llx): GFS log descriptor"
 				   " continuation block", abs_block, jb);
 			eol(0);
@@ -3658,7 +3659,7 @@ int main(int argc, char *argv[])
 	read_superblock(fd);
 	max_block = lseek(fd, 0, SEEK_END) / sbd.bsize;
 	strcpy(sbd.device_name, device);
-	if (gfs1)
+	if (sbd.gfs1)
 		edit_row[GFS2_MODE]++;
 	else
 		read_master_dir();
diff --git a/gfs2/edit/hexedit.h b/gfs2/edit/hexedit.h
index cc87925..8a3c615 100644
--- a/gfs2/edit/hexedit.h
+++ b/gfs2/edit/hexedit.h
@@ -81,7 +81,6 @@ extern char device[NAME_MAX];
 extern int identify;
 extern int color_scheme;
 extern WINDOW *wind;
-extern int gfs1;
 extern int editing;
 extern uint64_t temp_blk;
 extern uint64_t starting_blk;
@@ -231,7 +230,7 @@ extern enum dsp_mode dmode;
 /* ------------------------------------------------------------------------ */
 static inline int risize(void)
 {
-	if (gfs1)
+	if (sbd.gfs1)
 		return sizeof(struct gfs_rindex);
 	else
 		return sizeof(struct gfs2_rindex);
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index 160277c..c4719ea 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -120,12 +120,12 @@ static int get_gfs_struct_info(struct gfs2_buffer_head *lbh, int *block_type,
 		*gstruct_len = sbd.bsize;
 		break;
 	case GFS2_METATYPE_DI:   /* 4 (disk inode) */
-		if (gfs1)
+		if (sbd.gfs1)
 			inode = inode_get(&sbd, lbh);
 		else
 			inode = gfs_inode_get(&sbd, lbh);
 		if (S_ISDIR(inode->i_di.di_mode) ||
-		     (gfs1 && inode->i_di.__pad1 == GFS_FILE_DIR))
+		     (sbd.gfs1 && inode->i_di.__pad1 == GFS_FILE_DIR))
 			*gstruct_len = sbd.bsize;
 		else if (!inode->i_di.di_height && !block_is_systemfile() &&
 			 !S_ISDIR(inode->i_di.di_mode))
@@ -143,7 +143,7 @@ static int get_gfs_struct_info(struct gfs2_buffer_head *lbh, int *block_type,
 		*gstruct_len = sbd.bsize;
 		break;
 	case GFS2_METATYPE_LH:   /* 8 (log header) */
-		if (gfs1)
+		if (sbd.gfs1)
 			*gstruct_len = 512; /* gfs copies the log header
 					       twice and compares the copy,
 					       so we need to save all 512
@@ -454,7 +454,7 @@ static void save_inode_data(struct metafd *mfd)
 	for (i = 0; i < GFS2_MAX_META_HEIGHT; i++)
 		osi_list_init(&metalist[i]);
 	metabh = bread(&sbd, block);
-	if (gfs1)
+	if (sbd.gfs1)
 		inode = inode_get(&sbd, metabh);
 	else
 		inode = gfs_inode_get(&sbd, metabh);
@@ -466,7 +466,7 @@ static void save_inode_data(struct metafd *mfd)
 	   the hash table exists, and we have to save the directory data. */
 	if (inode->i_di.di_flags & GFS2_DIF_EXHASH &&
 	    (S_ISDIR(inode->i_di.di_mode) ||
-	     (gfs1 && inode->i_di.__pad1 == GFS_FILE_DIR)))
+	     (sbd.gfs1 && inode->i_di.__pad1 == GFS_FILE_DIR)))
 		height++;
 	else if (height && !block_is_systemfile() &&
 		 !S_ISDIR(inode->i_di.di_mode))
@@ -563,7 +563,7 @@ static void get_journal_inode_blocks(void)
 		int amt;
 		struct gfs2_inode *j_inode = NULL;
 
-		if (gfs1) {
+		if (sbd.gfs1) {
 			struct gfs_jindex ji;
 			char jbuf[sizeof(struct gfs_jindex)];
 
@@ -647,7 +647,7 @@ void savemeta(char *out_fn, int saveoption, int gziplevel)
 
 	lseek(sbd.device_fd, 0, SEEK_SET);
 	blks_saved = total_out = last_reported_block = 0;
-	if (!gfs1)
+	if (!sbd.gfs1)
 		sbd.bsize = BUFSIZE;
 	if (!slow) {
 		if (device_geometry(&sbd)) {
@@ -660,13 +660,13 @@ void savemeta(char *out_fn, int saveoption, int gziplevel)
 			exit(-1);
 		}
 		osi_list_init(&sbd.rglist);
-		if (!gfs1)
+		if (!sbd.gfs1)
 			sbd.sd_sb.sb_bsize = GFS2_DEFAULT_BSIZE;
 		if (compute_constants(&sbd)) {
 			fprintf(stderr, "Bad constants (1)\n");
 			exit(-1);
 		}
-		if(gfs1) {
+		if(sbd.gfs1) {
 			sbd.bsize = sbd.sd_sb.sb_bsize;
 			sbd.sd_inptrs = (sbd.bsize -
 					 sizeof(struct gfs_indirect)) /
@@ -691,7 +691,7 @@ void savemeta(char *out_fn, int saveoption, int gziplevel)
 	printf("There are %" PRIu64 " blocks of %u bytes in the destination "
 	       "device.\n", last_fs_block, sbd.bsize);
 	if (!slow) {
-		if (gfs1) {
+		if (sbd.gfs1) {
 			sbd.md.riinode = inode_read(&sbd,
 						sbd1->sb_rindex_di.no_addr);
 			jindex_block = sbd1->sb_jindex_di.no_addr;
@@ -706,7 +706,7 @@ void savemeta(char *out_fn, int saveoption, int gziplevel)
 		}
 		lbh = bread(&sbd, jindex_block);
 		gfs2_dinode_in(&di, lbh);
-		if (!gfs1)
+		if (!sbd.gfs1)
 			do_dinode_extended(&di, lbh);
 		brelse(lbh);
 	}
@@ -716,7 +716,7 @@ void savemeta(char *out_fn, int saveoption, int gziplevel)
 
 		printf("Reading resource groups...");
 		fflush(stdout);
-		if (gfs1)
+		if (sbd.gfs1)
 			slow = gfs1_ri_update(&sbd, 0, &rgcount, 0);
 		else
 			slow = ri_update(&sbd, 0, &rgcount, &sane);
@@ -738,7 +738,7 @@ void savemeta(char *out_fn, int saveoption, int gziplevel)
 		save_block(sbd.device_fd, &mfd, 0x10 * (4096 / sbd.bsize));
 		/* If this is gfs1, save off the rindex because it's not
 		   part of the file system as it is in gfs2. */
-		if (gfs1) {
+		if (sbd.gfs1) {
 			int j;
 
 			block = sbd1->sb_rindex_di.no_addr;
@@ -919,7 +919,7 @@ static int restore_data(int fd, gzFile *gzin_fd, int printblocksonly,
 			    sbd1->sb_header.mh_type == GFS_METATYPE_SB &&
 			    sbd1->sb_header.mh_format == GFS_FORMAT_SB &&
 			    sbd1->sb_multihost_format == GFS_FORMAT_MULTI) {
-				gfs1 = TRUE;
+				sbd.gfs1 = TRUE;
 			} else if (check_sb(&sbd.sd_sb)) {
 				fprintf(stderr,"Error: Invalid superblock data.\n");
 				return -1;
@@ -935,7 +935,7 @@ static int restore_data(int fd, gzFile *gzin_fd, int printblocksonly,
 				       " device.\n\n",
 				       last_fs_block, sbd.bsize);
 			} else {
-				printf("This is %s metadata\n", gfs1 ?
+				printf("This is %s metadata\n", sbd.gfs1 ?
 				       "gfs (not gfs2)" : "gfs2");
 			}
 			first = 0;
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 9063c8b..9c79959 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -243,6 +243,7 @@ struct gfs2_sbd {
 	uint32_t physical_block_size;
 	uint64_t rg_one_length;
 	uint64_t rg_length;
+	int gfs1;
 };
 
 struct metapath {
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 04/66] libgfs2: Make check_sb and read_sb operate on gfs1
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (2 preceding siblings ...)
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 03/66] libgfs1: Add gfs1 variable to superblock structure rpeterso
@ 2012-01-20 15:09 ` rpeterso
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 05/66] libgfs2: move gfs1 structures to libgfs2 rpeterso
                   ` (61 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:09 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch adds "allow_gfs1" parameters to the read_sb and check_sb functions.
This will allow gfs2-utils to read and operate on gfs1 file systems in
follow-up patches.

rhbz#675723
---
 gfs2/edit/savemeta.c   |   38 +++++++++-------------------
 gfs2/fsck/initialize.c |    4 +-
 gfs2/fsck/util.c       |    5 ++-
 gfs2/libgfs2/libgfs2.h |   28 +++++++++++++++++++--
 gfs2/libgfs2/super.c   |   63 +++++++++++++++++++++++++++++-------------------
 gfs2/mkfs/main_grow.c  |    2 +-
 6 files changed, 81 insertions(+), 59 deletions(-)

diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index c4719ea..665af07 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -628,7 +628,7 @@ static int next_rg_freemeta(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
 
 void savemeta(char *out_fn, int saveoption, int gziplevel)
 {
-	int slow;
+	int slow, ret;
 	osi_list_t *tmp;
 	int rgcount;
 	uint64_t jindex_block;
@@ -666,26 +666,13 @@ void savemeta(char *out_fn, int saveoption, int gziplevel)
 			fprintf(stderr, "Bad constants (1)\n");
 			exit(-1);
 		}
-		if(sbd.gfs1) {
-			sbd.bsize = sbd.sd_sb.sb_bsize;
-			sbd.sd_inptrs = (sbd.bsize -
-					 sizeof(struct gfs_indirect)) /
-				sizeof(uint64_t);
-			sbd.sd_diptrs = (sbd.bsize -
-					  sizeof(struct gfs_dinode)) /
-				sizeof(uint64_t);
-		} else {
-			if (read_sb(&sbd) < 0)
-				slow = TRUE;
-			else {
-				sbd.sd_inptrs = (sbd.bsize -
-					 sizeof(struct gfs2_meta_header)) /
-					sizeof(uint64_t);
-				sbd.sd_diptrs = (sbd.bsize -
-					  sizeof(struct gfs2_dinode)) /
-					sizeof(uint64_t);
-			}
+		ret = read_sb(&sbd, 1);
+		if (ret < 0) {
+			slow = TRUE;
+			sbd.gfs1 = 0;
 		}
+		if (sbd.gfs1)
+			sbd.bsize = sbd.sd_sb.sb_bsize;
 	}
 	last_fs_block = lseek(sbd.device_fd, 0, SEEK_END) / sbd.bsize;
 	printf("There are %" PRIu64 " blocks of %u bytes in the destination "
@@ -910,20 +897,19 @@ static int restore_data(int fd, gzFile *gzin_fd, int printblocksonly,
 		}
 		if (first) {
 			struct gfs2_sb bufsb;
+			int ret;
 
 			dummy_bh.b_data = (char *)&bufsb;
 			memcpy(&bufsb, savedata->buf, sizeof(bufsb));
 			gfs2_sb_in(&sbd.sd_sb, &dummy_bh);
 			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) {
-				sbd.gfs1 = TRUE;
-			} else if (check_sb(&sbd.sd_sb)) {
+			ret = check_sb(&sbd.sd_sb, 1);
+			if (ret < 0) {
 				fprintf(stderr,"Error: Invalid superblock data.\n");
 				return -1;
 			}
+			if (ret == 1)
+				sbd.gfs1 = TRUE;
 			sbd.bsize = sbd.sd_sb.sb_bsize;
 			if (find_highblk)
 				;
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 6b5bfec..29e4560 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -1074,7 +1074,7 @@ static int fill_super_block(struct gfs2_sbd *sdp)
 		log_crit(_("Bad constants (1)\n"));
 		exit(-1);
 	}
-	if (read_sb(sdp) < 0) {
+	if (read_sb(sdp, 0) < 0) {
 		/* First, check for a gfs1 (not gfs2) file system */
 		if (sdp->sd_sb.sb_header.mh_magic == GFS2_MAGIC &&
 		    sdp->sd_sb.sb_header.mh_type == GFS2_METATYPE_SB)
@@ -1083,7 +1083,7 @@ static int fill_super_block(struct gfs2_sbd *sdp)
 		if (sb_repair(sdp) != 0)
 			return -1; /* unrepairable, so exit */
 		/* Now that we've tried to repair it, re-read it. */
-		if (read_sb(sdp) < 0)
+		if (read_sb(sdp, 0) < 0)
 			return -1;
 	}
 
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index adca24a..2645a55 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -27,7 +27,7 @@ void big_file_comfort(struct gfs2_inode *ip, uint64_t blks_checked)
 	if (blks_checked - last_reported_fblock < one_percent)
 		return;
 
-	last_reported_block = blks_checked;
+	last_reported_fblock = blks_checked;
 	gettimeofday(&tv, NULL);
 	if (!seconds)
 		seconds = tv.tv_sec;
@@ -62,7 +62,8 @@ void warm_fuzzy_stuff(uint64_t block)
 
 	if (!one_percent)
 		one_percent = last_fs_block / 100;
-	if (block - last_reported_block >= one_percent) {
+	if (!last_reported_block ||
+	    block - last_reported_block >= one_percent) {
 		last_reported_block = block;
 		gettimeofday(&tv, NULL);
 		if (!seconds)
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 9c79959..6db9d6c 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -489,7 +489,29 @@ extern int write_journal(struct gfs2_sbd *sdp, unsigned int j,
 
 extern int device_size(int fd, uint64_t *bytes);
 
-/* gfs1.c - GFS1 backward compatibility functions */
+/* gfs1.c - GFS1 backward compatibility structures and functions */
+
+#define GFS_FORMAT_SB           (100)  /* Super-Block */
+#define GFS_METATYPE_SB         (1)    /* Super-Block */
+#define GFS_FORMAT_FS           (1309) /* Filesystem (all-encompassing) */
+#define GFS_FORMAT_MULTI        (1401) /* Multi-Host */
+/* GFS1 Dinode types  */
+#define GFS_FILE_NON            (0)
+#define GFS_FILE_REG            (1)    /* regular file */
+#define GFS_FILE_DIR            (2)    /* directory */
+#define GFS_FILE_LNK            (5)    /* link */
+#define GFS_FILE_BLK            (7)    /* block device node */
+#define GFS_FILE_CHR            (8)    /* character device node */
+#define GFS_FILE_FIFO           (101)  /* fifo/pipe */
+#define GFS_FILE_SOCK           (102)  /* socket */
+
+/* GFS 1 journal block types: */
+#define GFS_LOG_DESC_METADATA   (300)    /* metadata */
+#define GFS_LOG_DESC_IUL        (400)    /* unlinked inode */
+#define GFS_LOG_DESC_IDA        (401)    /* de-allocated inode */
+#define GFS_LOG_DESC_Q          (402)    /* quota */
+#define GFS_LOG_DESC_LAST       (500)    /* final in a logged transaction */
+
 struct gfs_indirect {
 	struct gfs2_meta_header in_header;
 
@@ -673,8 +695,8 @@ extern int gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block,
 extern int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
 				 uint64_t *block, uint32_t type, int first);
 /* super.c */
-extern int check_sb(struct gfs2_sb *sb);
-extern int read_sb(struct gfs2_sbd *sdp);
+extern int check_sb(struct gfs2_sb *sb, int allow_gfs);
+extern int read_sb(struct gfs2_sbd *sdp, int allow_gfs);
 extern int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *sane);
 extern int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int *sane);
 extern int write_sb(struct gfs2_sbd *sdp);
diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c
index f2dd171..7c9f395 100644
--- a/gfs2/libgfs2/super.c
+++ b/gfs2/libgfs2/super.c
@@ -18,9 +18,9 @@
  * read and that the sizes of the various on-disk structures have not
  * changed.
  *
- * Returns: 0 on success, -1 on failure
+ * Returns: -1 on failure, 1 if this is gfs (gfs1), 2 if this is gfs2
  */
-int check_sb(struct gfs2_sb *sb)
+int check_sb(struct gfs2_sb *sb, int allow_gfs)
 {
 	if (sb->sb_header.mh_magic != GFS2_MAGIC ||
 	    sb->sb_header.mh_type != GFS2_METATYPE_SB) {
@@ -31,13 +31,16 @@ int check_sb(struct gfs2_sb *sb)
 				  sb->sb_header.mh_type);
 		return -EINVAL;
 	}
-	/*  If format numbers match exactly, we're done.  */
-	if (sb->sb_fs_format != GFS2_FORMAT_FS ||
-	    sb->sb_multihost_format != GFS2_FORMAT_MULTI) {
+	if (sb->sb_fs_format == GFS_FORMAT_FS &&
+	    sb->sb_header.mh_format == GFS_FORMAT_SB &&
+	    sb->sb_multihost_format == GFS_FORMAT_MULTI) {
+		if (allow_gfs)
+			return 1;
+
 		log_crit("Old gfs1 file system detected.\n");
 		return -EINVAL;
 	}
-	return 0;
+	return 2;
 }
 
 
@@ -49,31 +52,44 @@ int check_sb(struct gfs2_sb *sb)
  * initializes various constants maintained in the super
  * block
  *
- * Returns: 0 on success, -1 on failure.
+ * allow_gfs - passed in as 1 if we're allowed to accept gfs1 file systems
+ *
+ * Returns: 0 on success, -1 on failure
+ * sdp->gfs1 will be set if this is gfs (gfs1)
  */
-int read_sb(struct gfs2_sbd *sdp)
+int read_sb(struct gfs2_sbd *sdp, int allow_gfs)
 {
 	struct gfs2_buffer_head *bh;
 	uint64_t space = 0;
 	unsigned int x;
-	int error;
+	int ret;
 
 	bh = bread(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift);
 	gfs2_sb_in(&sdp->sd_sb, bh);
 	brelse(bh);
 
-	error = check_sb(&sdp->sd_sb);
-	if (error)
-		goto out;
-
+	ret = check_sb(&sdp->sd_sb, allow_gfs);
+	if (ret < 0)
+		return ret;
+	if (ret == 1)
+		sdp->gfs1 = 1;
 	sdp->sd_fsb2bb_shift = sdp->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT;
 	sdp->bsize = sdp->sd_sb.sb_bsize;
-	sdp->sd_diptrs =
-		(sdp->sd_sb.sb_bsize-sizeof(struct gfs2_dinode)) /
-		sizeof(uint64_t);
-	sdp->sd_inptrs =
-		(sdp->sd_sb.sb_bsize-sizeof(struct gfs2_meta_header)) /
-		sizeof(uint64_t);
+	if (sdp->gfs1) {
+		sdp->sd_diptrs = (sdp->sd_sb.sb_bsize -
+				  sizeof(struct gfs_dinode)) /
+			sizeof(uint64_t);
+		sdp->sd_inptrs = (sdp->sd_sb.sb_bsize -
+				  sizeof(struct gfs_indirect)) /
+			sizeof(uint64_t);
+	} else {
+		sdp->sd_diptrs = (sdp->sd_sb.sb_bsize -
+				  sizeof(struct gfs2_dinode)) /
+			sizeof(uint64_t);
+		sdp->sd_inptrs = (sdp->sd_sb.sb_bsize -
+				  sizeof(struct gfs2_meta_header)) /
+			sizeof(uint64_t);
+	}
 	sdp->sd_jbsize = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header);
 	sdp->sd_hash_bsize = sdp->bsize / 2;
 	sdp->sd_hash_bsize_shift = sdp->sd_sb.sb_bsize_shift - 1;
@@ -90,8 +106,7 @@ int read_sb(struct gfs2_sbd *sdp)
 	}
 	if (x > GFS2_MAX_META_HEIGHT){
 		log_err("Bad max metadata height.\n");
-		error = -1;
-		goto out;
+		return -1;
 	}
 
 	sdp->sd_jheightsize[0] = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode);
@@ -106,14 +121,12 @@ int read_sb(struct gfs2_sbd *sdp)
 	sdp->sd_max_jheight = x;
 	if(sdp->sd_max_jheight > GFS2_MAX_META_HEIGHT) {
 		log_err("Bad max jheight.\n");
-		error = -1;
+		return -1;
 	}
 	sdp->fssize = lseek(sdp->device_fd, 0, SEEK_END) / sdp->sd_sb.sb_bsize;
 	sdp->sb_addr = GFS2_SB_ADDR * GFS2_BASIC_BLOCK / sdp->bsize;
 
- out:
-
-	return error;
+	return 0;
 }
 
 /**
diff --git a/gfs2/mkfs/main_grow.c b/gfs2/mkfs/main_grow.c
index 18110a0..a28bdc3 100644
--- a/gfs2/mkfs/main_grow.c
+++ b/gfs2/mkfs/main_grow.c
@@ -352,7 +352,7 @@ main_grow(int argc, char *argv[])
 			log_crit(_("Bad constants (1)\n"));
 			exit(-1);
 		}
-		if(read_sb(sdp) < 0)
+		if (read_sb(sdp, 0) < 0)
 			die( _("gfs: Error reading superblock.\n"));
 
 		if (fix_device_geometry(sdp)) {
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 05/66] libgfs2: move gfs1 structures to libgfs2
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (3 preceding siblings ...)
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 04/66] libgfs2: Make check_sb and read_sb operate on gfs1 rpeterso
@ 2012-01-20 15:09 ` rpeterso
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 06/66] fsck.gfs2: Check for blocks wrongly inside resource groups rpeterso
                   ` (60 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:09 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch moves a number of gfs1-specific structures from gfs2_edit to
libgfs2 so other utils can reference them.
It also changes function rindex_read so it can operate on gfs1 or gfs2
rindex files.

rhbz#675723
---
 gfs2/edit/extended.c   |   11 +++--
 gfs2/edit/hexedit.c    |   13 +++--
 gfs2/edit/hexedit.h    |  126 ------------------------------------------------
 gfs2/libgfs2/libgfs2.h |   94 +++++++++++++++++++++++++++++++++++
 gfs2/libgfs2/super.c   |   41 ++++++++++-----
 5 files changed, 136 insertions(+), 149 deletions(-)

diff --git a/gfs2/edit/extended.c b/gfs2/edit/extended.c
index 059f18b..366dfc6 100644
--- a/gfs2/edit/extended.c
+++ b/gfs2/edit/extended.c
@@ -504,7 +504,8 @@ static int parse_rindex(struct gfs2_inode *dip, int print_rindex)
 
 	start_line = line;
 	error = 0;
-	print_gfs2("RG index entries found: %d.", dip->i_di.di_size / risize());
+	print_gfs2("RG index entries found: %d.", dip->i_di.di_size /
+		   sizeof(struct gfs2_rindex));
 	eol(0);
 	lines_per_row[dmode] = 6;
 	memset(highlighted_addr, 0, sizeof(highlighted_addr));
@@ -512,12 +513,14 @@ static int parse_rindex(struct gfs2_inode *dip, int print_rindex)
 	for (print_entry_ndx=0; ; print_entry_ndx++) {
 		uint64_t roff;
 
-		roff = print_entry_ndx * risize();
+		roff = print_entry_ndx * sizeof(struct gfs2_rindex);
 
 		if (sbd.gfs1)
-			error = gfs1_readi(dip, (void *)&rbuf, roff, risize());
+			error = gfs1_readi(dip, (void *)&rbuf, roff,
+					   sizeof(struct gfs2_rindex));
 		else
-			error = gfs2_readi(dip, (void *)&rbuf, roff, risize());
+			error = gfs2_readi(dip, (void *)&rbuf, roff,
+					   sizeof(struct gfs2_rindex));
 		if (!error) /* end of file */
 			break;
 		gfs2_rindex_in(&ri, rbuf);
diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index 79a297e..903f169 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -1464,7 +1464,8 @@ uint64_t masterblock(const char *fn)
 static void rgcount(void)
 {
 	printf("%lld RGs in this file system.\n",
-	       (unsigned long long)sbd.md.riinode->i_di.di_size / risize());
+	       (unsigned long long)sbd.md.riinode->i_di.di_size /
+	       sizeof(struct gfs2_rindex));
 	inode_put(&sbd.md.riinode);
 	gfs2_rgrp_free(&sbd.rglist);
 	exit(EXIT_SUCCESS);
@@ -1479,7 +1480,7 @@ static uint64_t find_rgrp_block(struct gfs2_inode *dif, int rg)
 	struct gfs2_rindex fbuf, ri;
 	uint64_t foffset, gfs1_adj = 0;
 
-	foffset = rg * risize();
+	foffset = rg * sizeof(struct gfs2_rindex);
 	if (sbd.gfs1) {
 		uint64_t sd_jbsize =
 			(sbd.bsize - sizeof(struct gfs2_meta_header));
@@ -1488,7 +1489,8 @@ static uint64_t find_rgrp_block(struct gfs2_inode *dif, int rg)
 			sizeof(struct gfs2_meta_header);
 		gfs1_adj += sizeof(struct gfs2_meta_header);
 	}
-	amt = gfs2_readi(dif, (void *)&fbuf, foffset + gfs1_adj, risize());
+	amt = gfs2_readi(dif, (void *)&fbuf, foffset + gfs1_adj,
+			 sizeof(struct gfs2_rindex));
 	if (!amt) /* end of file */
 		return 0;
 	gfs2_rindex_in(&ri, (void *)&fbuf);
@@ -1557,11 +1559,12 @@ static uint64_t get_rg_addr(int rgnum)
 	else
 		gblock = masterblock("rindex");
 	riinode = inode_read(&sbd, gblock);
-	if (rgnum < riinode->i_di.di_size / risize())
+	if (rgnum < riinode->i_di.di_size / sizeof(struct gfs2_rindex))
 		rgblk = find_rgrp_block(riinode, rgnum);
 	else
 		fprintf(stderr, "Error: File system only has %lld RGs.\n",
-			(unsigned long long)riinode->i_di.di_size / risize());
+			(unsigned long long)riinode->i_di.di_size /
+			sizeof(struct gfs2_rindex));
 	inode_put(&riinode);
 	return rgblk;
 }
diff --git a/gfs2/edit/hexedit.h b/gfs2/edit/hexedit.h
index 8a3c615..f7b539e 100644
--- a/gfs2/edit/hexedit.h
+++ b/gfs2/edit/hexedit.h
@@ -21,27 +21,6 @@
 enum dsp_mode { HEX_MODE = 0, GFS2_MODE = 1, EXTENDED_MODE = 2, INIT_MODE = 3 };
 #define BLOCK_STACK_SIZE 256
 
-#define GFS_FORMAT_SB           (100)  /* Super-Block */
-#define GFS_METATYPE_SB         (1)    /* Super-Block */
-#define GFS_FORMAT_FS           (1309) /* Filesystem (all-encompassing) */
-#define GFS_FORMAT_MULTI        (1401) /* Multi-Host */
-/* GFS1 Dinode types  */
-#define GFS_FILE_NON            (0)
-#define GFS_FILE_REG            (1)    /* regular file */
-#define GFS_FILE_DIR            (2)    /* directory */
-#define GFS_FILE_LNK            (5)    /* link */
-#define GFS_FILE_BLK            (7)    /* block device node */
-#define GFS_FILE_CHR            (8)    /* character device node */
-#define GFS_FILE_FIFO           (101)  /* fifo/pipe */
-#define GFS_FILE_SOCK           (102)  /* socket */
-
-/* GFS 1 journal block types: */
-#define GFS_LOG_DESC_METADATA   (300)    /* metadata */
-#define GFS_LOG_DESC_IUL        (400)    /* unlinked inode */
-#define GFS_LOG_DESC_IDA        (401)    /* de-allocated inode */
-#define GFS_LOG_DESC_Q          (402)    /* quota */
-#define GFS_LOG_DESC_LAST       (500)    /* final in a logged transaction */
-
 #define pv(struct, member, fmt, fmt2) do {				\
 		print_it("  "#member, fmt, fmt2, struct->member);	\
 	} while (FALSE);
@@ -89,71 +68,6 @@ extern int dsplines;
 extern int dsp_lines[DMODES];
 extern int combined_display;
 
-struct gfs_jindex {
-        uint64_t ji_addr;       /* starting block of the journal */
-        uint32_t ji_nsegment;   /* number (quantity) of segments in journal */
-        uint32_t ji_pad;
-
-        char ji_reserved[64];
-};
-
-struct gfs_log_descriptor {
-	struct gfs2_meta_header ld_header;
-
-	uint32_t ld_type;       /* GFS_LOG_DESC_... Type of this log chunk */
-	uint32_t ld_length;     /* Number of buffers in this chunk */
-	uint32_t ld_data1;      /* descriptor-specific field */
-	uint32_t ld_data2;      /* descriptor-specific field */
-	char ld_reserved[64];
-};
-
-struct gfs_log_header {
-	struct gfs2_meta_header lh_header;
-
-	uint32_t lh_flags;      /* GFS_LOG_HEAD_... */
-	uint32_t lh_pad;
-
-	uint64_t lh_first;     /* Block number of first header in this trans */
-	uint64_t lh_sequence;   /* Sequence number of this transaction */
-
-	uint64_t lh_tail;       /* Block number of log tail */
-	uint64_t lh_last_dump;  /* Block number of last dump */
-
-	char lh_reserved[64];
-};
-
-struct gfs_rindex {
-	uint64_t ri_addr;     /* block # of 1st block (header) in rgrp */
-	uint32_t ri_length;   /* # fs blocks containing rgrp header & bitmap */
-	uint32_t ri_pad;
-
-	uint64_t ri_data1;    /* block # of first data/meta block in rgrp */
-	uint32_t ri_data;     /* number (qty) of data/meta blocks in rgrp */
-
-	uint32_t ri_bitbytes; /* total # bytes used by block alloc bitmap */
-
-	char ri_reserved[64];
-};
-
-struct gfs_rgrp {
-	struct gfs2_meta_header rg_header;
-
-	uint32_t rg_flags;      /* ?? */
-
-	uint32_t rg_free;       /* Number (qty) of free data blocks */
-
-	/* Dinodes are USEDMETA, but are handled separately from other METAs */
-	uint32_t rg_useddi;     /* Number (qty) of dinodes (used or free) */
-	uint32_t rg_freedi;     /* Number (qty) of unused (free) dinodes */
-	struct gfs2_inum rg_freedi_list; /* 1st block in chain of free dinodes */
-
-	/* These META statistics do not include dinodes (used or free) */
-	uint32_t rg_usedmeta;   /* Number (qty) of used metadata blocks */
-	uint32_t rg_freemeta;   /* Number (qty) of unused metadata blocks */
-
-	char rg_reserved[64];
-};
-
 struct gfs2_dirents {
 	uint64_t block;
 	struct gfs2_dirent dirent;
@@ -189,35 +103,6 @@ struct blkstack_info {
 	struct metapath mp;
 };
 
-struct gfs_sb {
-	/*  Order is important; need to be able to read old superblocks
-	    in order to support on-disk version upgrades */
-	struct gfs2_meta_header sb_header;
-
-	uint32_t sb_fs_format;         /* GFS_FORMAT_FS (on-disk version) */
-	uint32_t sb_multihost_format;  /* GFS_FORMAT_MULTI */
-	uint32_t sb_flags;             /* ?? */
-
-	uint32_t sb_bsize;             /* fundamental FS block size in bytes */
-	uint32_t sb_bsize_shift;       /* log2(sb_bsize) */
-	uint32_t sb_seg_size;          /* Journal segment size in FS blocks */
-
-	/* These special inodes do not appear in any on-disk directory. */
-	struct gfs2_inum sb_jindex_di;  /* journal index inode */
-	struct gfs2_inum sb_rindex_di;  /* resource group index inode */
-	struct gfs2_inum sb_root_di;    /* root directory inode */
-
-	/* Default inter-node locking protocol (lock module) and namespace */
-	char sb_lockproto[GFS2_LOCKNAME_LEN]; /* lock protocol name */
-	char sb_locktable[GFS2_LOCKNAME_LEN]; /* unique name for this FS */
-
-	/* More special inodes */
-	struct gfs2_inum sb_quota_di;   /* quota inode */
-	struct gfs2_inum sb_license_di; /* license inode */
-
-	char sb_reserved[96];
-};
-
 extern struct blkstack_info blockstack[BLOCK_STACK_SIZE];
 extern struct iinfo *indirect; /* more than the most indirect
 			       pointers possible for any given 4K block */
@@ -226,17 +111,6 @@ extern int indirect_blocks;  /* count of indirect blocks */
 extern enum dsp_mode dmode;
 
 /* ------------------------------------------------------------------------ */
-/* risize - size of one rindex entry, whether gfs1 or gfs2                  */
-/* ------------------------------------------------------------------------ */
-static inline int risize(void)
-{
-	if (sbd.gfs1)
-		return sizeof(struct gfs_rindex);
-	else
-		return sizeof(struct gfs2_rindex);
-}
-
-/* ------------------------------------------------------------------------ */
 /* block_is_rglist - there's no such block as the rglist.  This is a        */
 /*                   special case meant to parse the rindex and follow the  */
 /*                   blocks to the real rgs.                                */
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 6db9d6c..c7d5977 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -564,6 +564,100 @@ struct gfs_dinode {
 	char di_reserved[56];
 };
 
+struct gfs_sb {
+	/*  Order is important; need to be able to read old superblocks
+	    in order to support on-disk version upgrades */
+	struct gfs2_meta_header sb_header;
+
+	uint32_t sb_fs_format;         /* GFS_FORMAT_FS (on-disk version) */
+	uint32_t sb_multihost_format;  /* GFS_FORMAT_MULTI */
+	uint32_t sb_flags;             /* ?? */
+
+	uint32_t sb_bsize;             /* fundamental FS block size in bytes */
+	uint32_t sb_bsize_shift;       /* log2(sb_bsize) */
+	uint32_t sb_seg_size;          /* Journal segment size in FS blocks */
+
+	/* These special inodes do not appear in any on-disk directory. */
+	struct gfs2_inum sb_jindex_di;  /* journal index inode */
+	struct gfs2_inum sb_rindex_di;  /* resource group index inode */
+	struct gfs2_inum sb_root_di;    /* root directory inode */
+
+	/* Default inter-node locking protocol (lock module) and namespace */
+	char sb_lockproto[GFS2_LOCKNAME_LEN]; /* lock protocol name */
+	char sb_locktable[GFS2_LOCKNAME_LEN]; /* unique name for this FS */
+
+	/* More special inodes */
+	struct gfs2_inum sb_quota_di;   /* quota inode */
+	struct gfs2_inum sb_license_di; /* license inode */
+
+	char sb_reserved[96];
+};
+
+struct gfs_rgrp {
+	struct gfs2_meta_header rg_header;
+
+	uint32_t rg_flags;      /* ?? */
+
+	uint32_t rg_free;       /* Number (qty) of free data blocks */
+
+	/* Dinodes are USEDMETA, but are handled separately from other METAs */
+	uint32_t rg_useddi;     /* Number (qty) of dinodes (used or free) */
+	uint32_t rg_freedi;     /* Number (qty) of unused (free) dinodes */
+	struct gfs2_inum rg_freedi_list; /* 1st block in chain of free dinodes */
+
+	/* These META statistics do not include dinodes (used or free) */
+	uint32_t rg_usedmeta;   /* Number (qty) of used metadata blocks */
+	uint32_t rg_freemeta;   /* Number (qty) of unused metadata blocks */
+
+	char rg_reserved[64];
+};
+
+struct gfs_log_header {
+	struct gfs2_meta_header lh_header;
+
+	uint32_t lh_flags;      /* GFS_LOG_HEAD_... */
+	uint32_t lh_pad;
+
+	uint64_t lh_first;     /* Block number of first header in this trans */
+	uint64_t lh_sequence;   /* Sequence number of this transaction */
+
+	uint64_t lh_tail;       /* Block number of log tail */
+	uint64_t lh_last_dump;  /* Block number of last dump */
+
+	char lh_reserved[64];
+};
+
+struct gfs_rindex {
+	uint64_t ri_addr;     /* block # of 1st block (header) in rgrp */
+	uint32_t ri_length;   /* # fs blocks containing rgrp header & bitmap */
+	uint32_t ri_pad;
+
+	uint64_t ri_data1;    /* block # of first data/meta block in rgrp */
+	uint32_t ri_data;     /* number (qty) of data/meta blocks in rgrp */
+
+	uint32_t ri_bitbytes; /* total # bytes used by block alloc bitmap */
+
+	char ri_reserved[64];
+};
+
+struct gfs_jindex {
+        uint64_t ji_addr;       /* starting block of the journal */
+        uint32_t ji_nsegment;   /* number (quantity) of segments in journal */
+        uint32_t ji_pad;
+
+        char ji_reserved[64];
+};
+
+struct gfs_log_descriptor {
+	struct gfs2_meta_header ld_header;
+
+	uint32_t ld_type;       /* GFS_LOG_DESC_... Type of this log chunk */
+	uint32_t ld_length;     /* Number of buffers in this chunk */
+	uint32_t ld_data1;      /* descriptor-specific field */
+	uint32_t ld_data2;      /* descriptor-specific field */
+	char ld_reserved[64];
+};
+
 extern void gfs1_lookup_block(struct gfs2_inode *ip,
 			      struct gfs2_buffer_head *bh,
 			      unsigned int height, struct metapath *mp,
diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c
index 7c9f395..d902ba2 100644
--- a/gfs2/libgfs2/super.c
+++ b/gfs2/libgfs2/super.c
@@ -143,7 +143,10 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *sane)
 {
 	unsigned int rg;
 	int error;
-	struct gfs2_rindex buf;
+	union {
+		struct gfs_rindex bufgfs1;
+		struct gfs2_rindex bufgfs2;
+	} buf;
 	struct rgrp_list *rgd, *prev_rgd;
 	uint64_t prev_length = 0;
 
@@ -155,8 +158,14 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *sane)
 	for (rg = 0; ; rg++) {
 		if (fd > 0)
 			error = read(fd, &buf, sizeof(struct gfs2_rindex));
+		else if (sdp->gfs1)
+			error = gfs1_readi(sdp->md.riinode,
+					   (char *)&buf.bufgfs1,
+					   rg * sizeof(struct gfs2_rindex),
+					   sizeof(struct gfs2_rindex));
 		else
-			error = gfs2_readi(sdp->md.riinode, (char *)&buf,
+			error = gfs2_readi(sdp->md.riinode,
+					   (char *)&buf.bufgfs2,
 					   rg * sizeof(struct gfs2_rindex),
 					   sizeof(struct gfs2_rindex));
 		if (!error)
@@ -172,23 +181,27 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *sane)
 		memset(rgd, 0, sizeof(struct rgrp_list));
 		osi_list_add_prev(&rgd->list, &sdp->rglist);
 
-		gfs2_rindex_in(&rgd->ri, (char *)&buf);
+		gfs2_rindex_in(&rgd->ri, (char *)&buf.bufgfs2);
 
 		rgd->start = rgd->ri.ri_addr;
 		if (prev_rgd) {
 			/* If rg addresses go backwards, it's not sane
 			   (or it's converted from gfs1). */
-			if (prev_rgd->start >= rgd->start)
-				*sane = 0;
-			/* If rg lengths are not consistent, it's not sane
-			   (or it's converted from gfs1).  The first RG will
-			   be a different length due to space allocated for
-			   the superblock, so we can't detect this until
-			   we check rgrp 3, when we can compare the distance
-			   between rgrp 1 and rgrp 2. */
-			if (rg > 2 && prev_length &&
-			    prev_length != rgd->start - prev_rgd->start)
-				*sane = 0;
+			if (!sdp->gfs1) {
+				if (prev_rgd->start >= rgd->start)
+					*sane = 0;
+				/* If rg lengths are not consistent, it's not
+				   sane (or it's converted from gfs1).  The
+				   first RG will be a different length due to
+				   space allocated for the superblock, so we
+				   can't detect this until we check rgrp 3,
+				   when we can compare the distance between
+				   rgrp 1 and rgrp 2. */
+				if (rg > 2 && prev_length &&
+				    prev_length != rgd->start -
+				    prev_rgd->start)
+					*sane = 0;
+			}
 			prev_length = rgd->start - prev_rgd->start;
 			prev_rgd->length = prev_length;
 		}
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 06/66] fsck.gfs2: Check for blocks wrongly inside resource groups
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (4 preceding siblings ...)
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 05/66] libgfs2: move gfs1 structures to libgfs2 rpeterso
@ 2012-01-20 15:09 ` rpeterso
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 07/66] fsck.gfs2: Rename check_leaf to check_ealeaf_block rpeterso
                   ` (59 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:09 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

It's not enough to range_check blocks in order to call them valid.
We also need to check whether those block collide with resource groups.
We don't want a bitmap block to ever be referenced unless it's part of
the rgrp and rindex functions.  This patch changes most of the fsck code
from doing simple block range checks to doing range checks plus checks
for blocks inside the resource groups.

rhbz#675723
---
 gfs2/fsck/lost_n_found.c |    2 +-
 gfs2/fsck/metawalk.c     |   20 +++++++-------
 gfs2/fsck/pass1.c        |   66 +++++++++++++++++++++++----------------------
 gfs2/fsck/pass1b.c       |    2 +-
 gfs2/fsck/pass1c.c       |   10 +++---
 gfs2/fsck/pass2.c        |    4 +-
 gfs2/fsck/rgrepair.c     |    2 +-
 gfs2/fsck/util.c         |    2 +-
 gfs2/libgfs2/fs_bits.c   |   19 ++++++++++++-
 gfs2/libgfs2/libgfs2.h   |    1 +
 10 files changed, 74 insertions(+), 54 deletions(-)

diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index 988d2ea..1cadab9 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -95,7 +95,7 @@ int add_inode_to_lf(struct gfs2_inode *ip){
 		/* If there's a pre-existing .. directory entry, we have to
 		   back out the links. */
 		di = dirtree_find(ip->i_di.di_num.no_addr);
-		if (di && gfs2_check_range(sdp, di->dotdot_parent) == 0) {
+		if (di && !valid_block(sdp, di->dotdot_parent) == 0) {
 			struct gfs2_inode *dip;
 
 			log_debug(_("Directory %lld (0x%llx) already had a "
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 47412f9..a06bcf2 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -456,7 +456,7 @@ static void warn_and_patch(struct gfs2_inode *ip, uint64_t *leaf_no,
 	}
 	if (*leaf_no == *bad_leaf ||
 	    query( _("Attempt to patch around it? (y/n) "))) {
-		if (gfs2_check_range(ip->i_sbd, old_leaf) == 0)
+		if (!valid_block(ip->i_sbd, old_leaf) == 0)
 			gfs2_put_leaf_nr(ip, pindex, old_leaf);
 		else
 			gfs2_put_leaf_nr(ip, pindex, first_ok_leaf);
@@ -606,7 +606,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 	first_ok_leaf = leaf_no = -1;
 	for(lindex = 0; lindex < (1 << ip->i_di.di_depth); lindex++) {
 		gfs2_get_leaf_nr(ip, lindex, &leaf_no);
-		if (gfs2_check_range(ip->i_sbd, leaf_no) == 0) {
+		if (!valid_block(ip->i_sbd, leaf_no) == 0) {
 			lbh = bread(sdp, leaf_no);
 			/* Make sure it's really a valid leaf block. */
 			if (gfs2_check_meta(lbh, GFS2_METATYPE_LF) == 0) {
@@ -645,7 +645,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 		}
 
 		do {
-			if (gfs2_check_range(ip->i_sbd, old_leaf) == 0) {
+			if (!valid_block(ip->i_sbd, old_leaf) == 0) {
 				error = check_num_ptrs(ip, old_leaf,
 						       &ref_count, &exp_count,
 						       &lindex, &oldleaf);
@@ -657,7 +657,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 			if (fsck_abort)
 				break;
 			/* Make sure the block number is in range. */
-			if (gfs2_check_range(ip->i_sbd, leaf_no)){
+			if (!valid_block(ip->i_sbd, leaf_no)){
 				log_err( _("Leaf block #%llu (0x%llx) is out "
 					"of range for directory #%llu (0x%llx"
 					").\n"), (unsigned long long)leaf_no,
@@ -909,7 +909,7 @@ int delete_block(struct gfs2_inode *ip, uint64_t block,
 		 struct gfs2_buffer_head **bh, const char *btype,
 		 void *private)
 {
-	if (gfs2_check_range(ip->i_sbd, block) == 0) {
+	if (!valid_block(ip->i_sbd, block) == 0) {
 		fsck_blockmap_set(ip, block, btype, gfs2_block_free);
 		return 0;
 	}
@@ -930,7 +930,7 @@ static int delete_block_if_notdup(struct gfs2_inode *ip, uint64_t block,
 	uint8_t q;
 	struct duptree *d;
 
-	if (gfs2_check_range(ip->i_sbd, block) != 0)
+	if (!valid_block(ip->i_sbd, block) != 0)
 		return -EFAULT;
 
 	q = block_type(block);
@@ -1189,7 +1189,7 @@ static int build_and_check_metalist(struct gfs2_inode *ip, osi_list_t *mlp,
 						   block, block);
 					continue;
 				}
-				if (gfs2_check_range(ip->i_sbd, block)) {
+				if (!valid_block(ip->i_sbd, block)) {
 					log_debug( _("Skipping invalid block "
 						     "%lld (0x%llx)\n"),
 						   (unsigned long long)block,
@@ -1236,7 +1236,7 @@ static int check_data(struct gfs2_inode *ip, struct metawalk_fxns *pass,
 		if (skip_this_pass || fsck_abort)
 			return error;
 		block =  be64_to_cpu(*ptr);
-		/* It's important that we don't call gfs2_check_range and
+		/* It's important that we don't call !valid_block and
 		   bypass calling check_data on invalid blocks because that
 		   would defeat the rangecheck_block related functions in
 		   pass1. Therefore the individual check_data functions
@@ -1436,8 +1436,8 @@ int remove_dentry_from_dir(struct gfs2_sbd *sdp, uint64_t dir,
 		     " (0x%llx)\n"), (unsigned long long)dentryblock,
 		  (unsigned long long)dentryblock,
 		  (unsigned long long)dir, (unsigned long long)dir);
-	if (gfs2_check_range(sdp, dir)) {
-		log_err( _("Parent directory out of range\n"));
+	if (!valid_block(sdp, dir)) {
+		log_err( _("Parent directory is invalid\n"));
 		return 1;
 	}
 	remove_dentry_fxns.private = &dentryblock;
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 02305f4..59c7f66 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -120,11 +120,11 @@ static int resuscitate_metalist(struct gfs2_inode *ip, uint64_t block,
 	struct block_count *bc = (struct block_count *)private;
 
 	*bh = NULL;
-	if (gfs2_check_range(ip->i_sbd, block)){ /* blk outside of FS */
+	if (!valid_block(ip->i_sbd, block)){ /* blk outside of FS */
 		fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
 				  _("itself"), gfs2_bad_block);
-		log_err( _("Bad indirect block pointer (out of range) "
-			   "found in system inode %lld (0x%llx).\n"),
+		log_err( _("Bad indirect block pointer (invalid or out of "
+			   "range) found in system inode %lld (0x%llx).\n"),
 			 (unsigned long long)ip->i_di.di_num.no_addr,
 			 (unsigned long long)ip->i_di.di_num.no_addr);
 		return 1;
@@ -164,10 +164,10 @@ static int resuscitate_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 		strncpy(tmp_name, filename, de->de_name_len);
 	else
 		strncpy(tmp_name, filename, sizeof(tmp_name) - 1);
-	if (gfs2_check_range(sdp, block)) {
+	if (!valid_block(sdp, block)) {
 		log_err( _("Block # referenced by system directory entry %s "
-			   "in inode %lld (0x%llx) is out of range; "
-			   "ignored.\n"),
+			   "in inode %lld (0x%llx) is invalid or out of range;"
+			   " ignored.\n"),
 			 tmp_name, (unsigned long long)ip->i_di.di_num.no_addr,
 			 (unsigned long long)ip->i_di.di_num.no_addr);
 		return 0;
@@ -219,10 +219,10 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block,
 
 	*bh = NULL;
 
-	if (gfs2_check_range(ip->i_sbd, block)){ /* blk outside of FS */
+	if (!valid_block(ip->i_sbd, block)){ /* blk outside of FS */
 		fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
 				  _("itself"), gfs2_bad_block);
-		log_debug( _("Bad indirect block pointer (out of range) "
+		log_debug( _("Bad indirect block (invalid/out of range) "
 			     "found in inode %lld (0x%llx).\n"),
 			   (unsigned long long)ip->i_di.di_num.no_addr,
 			   (unsigned long long)ip->i_di.di_num.no_addr);
@@ -293,7 +293,7 @@ static int undo_check_metalist(struct gfs2_inode *ip, uint64_t block,
 
 	*bh = NULL;
 
-	if (gfs2_check_range(ip->i_sbd, block)){ /* blk outside of FS */
+	if (!valid_block(ip->i_sbd, block)){ /* blk outside of FS */
 		fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
 				  _("itself"), gfs2_block_free);
 		return 1;
@@ -348,9 +348,9 @@ static int check_data(struct gfs2_inode *ip, uint64_t block, void *private)
 	uint8_t q;
 	struct block_count *bc = (struct block_count *) private;
 
-	if (gfs2_check_range(ip->i_sbd, block)) {
+	if (!valid_block(ip->i_sbd, block)) {
 		log_err( _("inode %lld (0x%llx) has a bad data block pointer "
-			   "%lld (out of range)\n"),
+			   "%lld (invalid or out of range)\n"),
 			 (unsigned long long)ip->i_di.di_num.no_addr,
 			 (unsigned long long)ip->i_di.di_num.no_addr,
 			 (unsigned long long)block);
@@ -399,12 +399,12 @@ static int undo_check_data(struct gfs2_inode *ip, uint64_t block,
 	struct duptree *d;
 	struct block_count *bc = (struct block_count *) private;
 
-	if (gfs2_check_range(ip->i_sbd, block)) {
+	if (!valid_block(ip->i_sbd, block)) {
 		/* Mark the owner of this block with the bad_block
 		 * designator so we know to check it for out of range
 		 * blocks later */
 		fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
-				  _("bad (out of range) data"),
+				  _("bad (invalid or out of range) data"),
 				  gfs2_block_free);
 		return 1;
 	}
@@ -545,7 +545,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t indirect,
 
 	/* This inode contains an eattr - it may be invalid, but the
 	 * eattr attributes points to a non-zero block */
-	if (gfs2_check_range(sdp, indirect)) {
+	if (!valid_block(sdp, indirect)) {
 		/* Doesn't help to mark this here - this gets checked
 		 * in pass1c */
 		return 1;
@@ -711,10 +711,10 @@ static int check_extended_leaf_eattr(struct gfs2_inode *ip, uint64_t *data_ptr,
 	struct gfs2_buffer_head *bh = NULL;
 	int error;
 
-	if (gfs2_check_range(sdp, el_blk)){
+	if (!valid_block(sdp, el_blk)){
 		log_err( _("Inode #%llu (0x%llx): Extended Attribute block "
 			   "%llu (0x%llx) has an extended leaf block #%llu "
-			   "(0x%llx) that is out of range.\n"),
+			   "(0x%llx) that is invalid or out of range.\n"),
 			 (unsigned long long)ip->i_di.di_num.no_addr,
 			 (unsigned long long)ip->i_di.di_num.no_addr,
 			 (unsigned long long)ip->i_di.di_eattr,
@@ -755,9 +755,10 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
 	}
 	if (!b || b->block != ip->i_di.di_num.no_addr)
 		gfs2_special_add(&sdp->eattr_blocks, ip->i_di.di_num.no_addr);
-	if (gfs2_check_range(sdp, block)) {
+	if (!valid_block(sdp, block)) {
 		log_warn( _("Inode #%llu (0x%llx): Extended Attribute leaf "
-			    "block #%llu (0x%llx) is out of range.\n"),
+			    "block #%llu (0x%llx) is invalid or out of "
+			    "range.\n"),
 			 (unsigned long long)ip->i_di.di_num.no_addr,
 			 (unsigned long long)ip->i_di.di_num.no_addr,
 			 (unsigned long long)block, (unsigned long long)block);
@@ -823,15 +824,15 @@ static int mark_block_invalid(struct gfs2_inode *ip, uint64_t block,
 {
 	uint8_t q;
 
-	if (gfs2_check_range(ip->i_sbd, block) != 0)
+	if (!valid_block(ip->i_sbd, block) != 0)
 		return -EFAULT;
 
 	q = block_type(block);
 	if (q != gfs2_block_free) {
 		add_duplicate_ref(ip, block, reftype, 0, INODE_INVALID);
 		log_info( _("%s block %lld (0x%llx), part of inode "
-			    "%lld (0x%llx), was free so the invalid "
-			    "reference is ignored.\n"),
+			    "%lld (0x%llx), was previously referenced so "
+			    "the invalid reference is ignored.\n"),
 			  btype, (unsigned long long)block,
 			  (unsigned long long)block,
 			  (unsigned long long)ip->i_di.di_num.no_addr,
@@ -895,13 +896,13 @@ static int rangecheck_block(struct gfs2_inode *ip, uint64_t block,
 	long *bad_pointers = (long *)private;
 	uint8_t q;
 
-	if (gfs2_check_range(ip->i_sbd, block) != 0) {
+	if (!valid_block(ip->i_sbd, block) != 0) {
 		(*bad_pointers)++;
-		log_debug( _("Bad %s block pointer (out of range #%ld) "
-			     "found in inode %lld (0x%llx).\n"), btype,
-			   *bad_pointers,
-			   (unsigned long long)ip->i_di.di_num.no_addr,
-			   (unsigned long long)ip->i_di.di_num.no_addr);
+		log_info( _("Bad %s block pointer (invalid or out of range "
+			    "#%ld) found in inode %lld (0x%llx).\n"),
+			  btype, *bad_pointers,
+			  (unsigned long long)ip->i_di.di_num.no_addr,
+			  (unsigned long long)ip->i_di.di_num.no_addr);
 		if ((*bad_pointers) <= BAD_POINTER_TOLERANCE)
 			return ENOENT;
 		else
@@ -911,11 +912,12 @@ static int rangecheck_block(struct gfs2_inode *ip, uint64_t block,
 	q = block_type(block);
 	if (q != gfs2_block_free) {
 		(*bad_pointers)++;
-		log_debug( _("Duplicated %s block pointer (violation #%ld) "
-			     "found in inode %lld (0x%llx).\n"), btype,
-			   *bad_pointers,
-			   (unsigned long long)ip->i_di.di_num.no_addr,
-			   (unsigned long long)ip->i_di.di_num.no_addr);
+		log_info( _("Duplicated %s block pointer (violation %ld, block"
+			    " %lld (0x%llx)) found in inode %lld (0x%llx).\n"),
+			  btype, *bad_pointers,
+			  (unsigned long long)block, (unsigned long long)block,
+			  (unsigned long long)ip->i_di.di_num.no_addr,
+			  (unsigned long long)ip->i_di.di_num.no_addr);
 		if ((*bad_pointers) <= BAD_POINTER_TOLERANCE)
 			return ENOENT;
 		else
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index c5a31fa..b4580bf 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -203,7 +203,7 @@ static int clear_dup_metalist(struct gfs2_inode *ip, uint64_t block,
 	struct dup_handler *dh = (struct dup_handler *) private;
 	struct duptree *d;
 
-	if (gfs2_check_range(ip->i_sbd, block) != 0)
+	if (!valid_block(ip->i_sbd, block) != 0)
 		return 0;
 
 	/* This gets tricky. We're traversing a metadata tree trying to
diff --git a/gfs2/fsck/pass1c.c b/gfs2/fsck/pass1c.c
index c6af290..150dc2f 100644
--- a/gfs2/fsck/pass1c.c
+++ b/gfs2/fsck/pass1c.c
@@ -75,10 +75,10 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block,
 	uint8_t q;
 	struct gfs2_buffer_head *indir_bh = NULL;
 
-	if (gfs2_check_range(sdp, block)) {
+	if (!valid_block(sdp, block)) {
 		log_err( _("Extended attributes indirect block #%llu"
 			" (0x%llx) for inode #%llu"
-			" (0x%llx) out of range...removing\n"),
+			" (0x%llx) is invalid...removing\n"),
 			(unsigned long long)block,
 			(unsigned long long)block,
 			(unsigned long long)ip->i_di.di_num.no_addr,
@@ -89,7 +89,7 @@ static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block,
 	if (q != gfs2_indir_blk) {
 		log_err( _("Extended attributes indirect block #%llu"
 			" (0x%llx) for inode #%llu"
-			" (0x%llx) invalid.\n"),
+			" (0x%llx) is invalid.\n"),
 			(unsigned long long)block,
 			(unsigned long long)block,
 			(unsigned long long)ip->i_di.di_num.no_addr,
@@ -110,9 +110,9 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
 	struct gfs2_sbd *sdp = ip->i_sbd;
 	uint8_t q;
 
-	if (gfs2_check_range(sdp, block)) {
+	if (!valid_block(sdp, block)) {
 		log_err( _("Extended attributes block for inode #%llu"
-			" (0x%llx) out of range.\n"),
+			" (0x%llx) is invalid.\n"),
 			(unsigned long long)ip->i_di.di_num.no_addr,
 			(unsigned long long)ip->i_di.di_num.no_addr);
 		return ask_remove_eattr(ip);
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index af26988..de91a0d 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -197,9 +197,9 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 	else
 		strncpy(tmp_name, filename, MAX_FILENAME - 1);
 
-	if (gfs2_check_range(ip->i_sbd, entryblock)) {
+	if (!valid_block(ip->i_sbd, entryblock)) {
 		log_err( _("Block # referenced by directory entry %s in inode "
-			   "%lld (0x%llx) is out of range\n"),
+			   "%lld (0x%llx) is invalid\n"),
 			 tmp_name, (unsigned long long)ip->i_di.di_num.no_addr,
 			 (unsigned long long)ip->i_di.di_num.no_addr);
 		if (query( _("Clear directory entry to out of range block? "
diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c
index 1bddacf..52cc529 100644
--- a/gfs2/fsck/rgrepair.c
+++ b/gfs2/fsck/rgrepair.c
@@ -706,7 +706,7 @@ static int expect_rindex_sanity(struct gfs2_sbd *sdp, osi_list_t *ret_list,
 	osi_list_t *tmp;
 	struct rgrp_list *exp, *rgd; /* expected, actual */
 
-	*num_rgs = sdp->md.riinode->i_di.di_size / sizeof(struct gfs2_rindex);
+	*num_rgs = sdp->md.riinode->i_di.di_size / sizeof(struct gfs2_rindex) ;
 	osi_list_init(ret_list);
 	for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
 		rgd = osi_list_entry(tmp, struct rgrp_list, list);
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index 2645a55..b71fc98 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -201,7 +201,7 @@ int add_duplicate_ref(struct gfs2_inode *ip, uint64_t block,
 	struct inode_with_dups *id, *found_id;
 	struct duptree *dt;
 
-	if (gfs2_check_range(ip->i_sbd, block) != 0)
+	if (!valid_block(ip->i_sbd, block) != 0)
 		return 0;
 	/* If this is not the first reference (i.e. all calls from pass1) we
 	   need to create the duplicate reference. If this is pass1b, we want
diff --git a/gfs2/libgfs2/fs_bits.c b/gfs2/libgfs2/fs_bits.c
index 38ef92c..b39effe 100644
--- a/gfs2/libgfs2/fs_bits.c
+++ b/gfs2/libgfs2/fs_bits.c
@@ -143,7 +143,24 @@ int gfs2_check_range(struct gfs2_sbd *sdp, uint64_t blkno)
 }
 
 /*
- * fs_set_bitmap
+ * valid_block - check if blkno is valid and not part of our rgrps or bitmaps
+ * @sdp: super block
+ * @blkno: block number
+ *
+ * Returns: 1 if ok, 0 if out of bounds
+ */
+int valid_block(struct gfs2_sbd *sdp, uint64_t blkno)
+{
+	if((blkno > sdp->fssize) || (blkno <= sdp->sb_addr))
+		return 0;
+	/* Check if the block is one of our rgrp or bitmap blocks */
+	if (gfs2_get_bitmap(sdp, blkno, NULL) < 0)
+		return 0;
+	return 1;
+}
+
+/*
+ * gfs2_set_bitmap
  * @sdp: super block
  * @blkno: block number relative to file system
  * @state: one of three possible states
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index c7d5977..0ddb48f 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -406,6 +406,7 @@ extern uint32_t gfs2_blkalloc_internal(struct rgrp_list *rgd, uint32_t goal,
 extern int gfs2_check_range(struct gfs2_sbd *sdp, uint64_t blkno);
 
 /* functions with blk #'s that are file system relative */
+extern int valid_block(struct gfs2_sbd *sdp, uint64_t blkno);
 extern int gfs2_get_bitmap(struct gfs2_sbd *sdp, uint64_t blkno,
 			   struct rgrp_list *rgd);
 extern int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int state);
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 07/66] fsck.gfs2: Rename check_leaf to check_ealeaf_block
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (5 preceding siblings ...)
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 06/66] fsck.gfs2: Check for blocks wrongly inside resource groups rpeterso
@ 2012-01-20 15:09 ` rpeterso
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 08/66] fsck.gfs2: fsck.gfs2: Delete vestigial buffer_head in check_leaf rpeterso
                   ` (58 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:09 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch renames function check_leaf_block to check_ealeaf_block to
avoid confusion between directory leaf block handling and extended
attribute leaf block handling.

rhbz#675723
---
 gfs2/fsck/pass1.c |   11 +++++++----
 1 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 59c7f66..40f1f73 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -634,8 +634,11 @@ static int finish_eattr_indir(struct gfs2_inode *ip, int leaf_pointers,
 	return 1;
 }
 
-static int check_leaf_block(struct gfs2_inode *ip, uint64_t block, int btype,
-			    struct gfs2_buffer_head **bh, void *private)
+/* check_ealeaf_block
+ *      checks an extended attribute (not directory) leaf block
+ */
+static int check_ealeaf_block(struct gfs2_inode *ip, uint64_t block, int btype,
+			      struct gfs2_buffer_head **bh, void *private)
 {
 	struct gfs2_buffer_head *leaf_bh = NULL;
 	struct gfs2_sbd *sdp = ip->i_sbd;
@@ -726,7 +729,7 @@ static int check_extended_leaf_eattr(struct gfs2_inode *ip, uint64_t *data_ptr,
 				  gfs2_bad_block);
 		return 1;
 	}
-	error = check_leaf_block(ip, el_blk, GFS2_METATYPE_ED, &bh, private);
+	error = check_ealeaf_block(ip, el_blk, GFS2_METATYPE_ED, &bh, private);
 	if (bh)
 		brelse(bh);
 	return error;
@@ -767,7 +770,7 @@ static int check_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
 				    "Attribute leaf"), gfs2_bad_block);
 		return 1;
 	}
-	return check_leaf_block(ip, block, GFS2_METATYPE_EA, bh, private);
+	return check_ealeaf_block(ip, block, GFS2_METATYPE_EA, bh, private);
 }
 
 static int check_eattr_entries(struct gfs2_inode *ip,
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 08/66] fsck.gfs2: fsck.gfs2: Delete vestigial buffer_head in check_leaf
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (6 preceding siblings ...)
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 07/66] fsck.gfs2: Rename check_leaf to check_ealeaf_block rpeterso
@ 2012-01-20 15:09 ` rpeterso
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 09/66] fsck.gfs2: fsck.gfs2: Rename nlink functions to be intuitive rpeterso
                   ` (57 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:09 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch eliminates a variable bh from all the check_leaf metawalk
functions because it is no longer referenced.

rhbzs#675723
---
 gfs2/fsck/metawalk.c |   10 ++++------
 gfs2/fsck/metawalk.h |    5 ++---
 gfs2/fsck/pass1.c    |   14 ++++++--------
 3 files changed, 12 insertions(+), 17 deletions(-)

diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index a06bcf2..541e468 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -687,7 +687,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 			}
 			gfs2_leaf_in(&leaf, lbh);
 			if (pass->check_leaf)
-				error = pass->check_leaf(ip, leaf_no, lbh,
+				error = pass->check_leaf(ip, leaf_no,
 							 pass->private);
 
 			/*
@@ -1461,10 +1461,9 @@ int delete_metadata(struct gfs2_inode *ip, uint64_t block,
 	return delete_block_if_notdup(ip, block, bh, _("metadata"), private);
 }
 
-int delete_leaf(struct gfs2_inode *ip, uint64_t block,
-		struct gfs2_buffer_head *bh, void *private)
+int delete_leaf(struct gfs2_inode *ip, uint64_t block, void *private)
 {
-	return delete_block_if_notdup(ip, block, &bh, _("leaf"), private);
+	return delete_block_if_notdup(ip, block, NULL, _("leaf"), private);
 }
 
 int delete_data(struct gfs2_inode *ip, uint64_t block, void *private)
@@ -1527,8 +1526,7 @@ static int alloc_data(struct gfs2_inode *ip, uint64_t block, void *private)
 	return 0;
 }
 
-static int alloc_leaf(struct gfs2_inode *ip, uint64_t block,
-		      struct gfs2_buffer_head *bh, void *private)
+static int alloc_leaf(struct gfs2_inode *ip, uint64_t block, void *private)
 {
 	uint8_t q;
 
diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h
index c1e61fb..ea023b6 100644
--- a/gfs2/fsck/metawalk.h
+++ b/gfs2/fsck/metawalk.h
@@ -20,8 +20,7 @@ extern int delete_block(struct gfs2_inode *ip, uint64_t block,
 		 void *private);
 extern int delete_metadata(struct gfs2_inode *ip, uint64_t block,
 			   struct gfs2_buffer_head **bh, int h, void *private);
-extern int delete_leaf(struct gfs2_inode *ip, uint64_t block,
-		struct gfs2_buffer_head *bh, void *private);
+extern int delete_leaf(struct gfs2_inode *ip, uint64_t block, void *private);
 extern int delete_data(struct gfs2_inode *ip, uint64_t block, void *private);
 extern int delete_eattr_indir(struct gfs2_inode *ip, uint64_t block, uint64_t parent,
 		       struct gfs2_buffer_head **bh, void *private);
@@ -60,7 +59,7 @@ extern struct gfs2_inode *fsck_system_inode(struct gfs2_sbd *sdp,
 struct metawalk_fxns {
 	void *private;
 	int (*check_leaf) (struct gfs2_inode *ip, uint64_t block,
-			   struct gfs2_buffer_head *bh, void *private);
+			   void *private);
 	int (*check_metalist) (struct gfs2_inode *ip, uint64_t block,
 			       struct gfs2_buffer_head **bh, int h,
 			       void *private);
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 40f1f73..8f399e1 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -32,8 +32,7 @@ struct block_count {
 	uint64_t ea_count;
 };
 
-static int leaf(struct gfs2_inode *ip, uint64_t block,
-		struct gfs2_buffer_head *bh, void *private);
+static int leaf(struct gfs2_inode *ip, uint64_t block, void *private);
 static int check_metalist(struct gfs2_inode *ip, uint64_t block,
 			  struct gfs2_buffer_head **bh, int h, void *private);
 static int undo_check_metalist(struct gfs2_inode *ip, uint64_t block,
@@ -64,7 +63,7 @@ static int invalidate_metadata(struct gfs2_inode *ip, uint64_t block,
 			       struct gfs2_buffer_head **bh, int h,
 			       void *private);
 static int invalidate_leaf(struct gfs2_inode *ip, uint64_t block,
-			   struct gfs2_buffer_head *bh, void *private);
+			   void *private);
 static int invalidate_data(struct gfs2_inode *ip, uint64_t block,
 			   void *private);
 static int invalidate_eattr_indir(struct gfs2_inode *ip, uint64_t block,
@@ -198,8 +197,7 @@ struct metawalk_fxns sysdir_fxns = {
 	.check_dentry = resuscitate_dentry,
 };
 
-static int leaf(struct gfs2_inode *ip, uint64_t block,
-		struct gfs2_buffer_head *bh, void *private)
+static int leaf(struct gfs2_inode *ip, uint64_t block, void *private)
 {
 	struct block_count *bc = (struct block_count *) private;
 
@@ -854,7 +852,7 @@ static int invalidate_metadata(struct gfs2_inode *ip, uint64_t block,
 }
 
 static int invalidate_leaf(struct gfs2_inode *ip, uint64_t block,
-			   struct gfs2_buffer_head *bh, void *private)
+			   void *private)
 {
 	return mark_block_invalid(ip, block, ref_as_meta, _("leaf"));
 }
@@ -937,9 +935,9 @@ static int rangecheck_metadata(struct gfs2_inode *ip, uint64_t block,
 }
 
 static int rangecheck_leaf(struct gfs2_inode *ip, uint64_t block,
-			   struct gfs2_buffer_head *bh, void *private)
+			   void *private)
 {
-	return rangecheck_block(ip, block, &bh, _("leaf"), private);
+	return rangecheck_block(ip, block, NULL, _("leaf"), private);
 }
 
 static int rangecheck_data(struct gfs2_inode *ip, uint64_t block,
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 09/66] fsck.gfs2: fsck.gfs2: Rename nlink functions to be intuitive
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (7 preceding siblings ...)
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 08/66] fsck.gfs2: fsck.gfs2: Delete vestigial buffer_head in check_leaf rpeterso
@ 2012-01-20 15:09 ` rpeterso
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 10/66] fsck.gfs2: fsck.gfs2: Sync di_nlink adding links for lost+found rpeterso
                   ` (56 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:09 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

Part of fsck's checks is to verify the count of links for directories,
but the variable names and function names are too confusing to understand
without in-depth analysis of what the code is doing.

This patch renames the structure variable "link_count" to something that
makes more intuitive sense: di_nlink, which matches the variable name in
the dinode.  That distinguishes it from the number of links that fsck is
trying to count manually.  It also renames the link count functions to
make them more intuitively obvious as well: set_di_nlink sets the di_nlink
based on the value passed in from the dinode, and incr_link_count and
decr_link_count increment and decrement the counted links respectively.

rhbz#675723
---
 gfs2/fsck/fsck.h         |    4 ++--
 gfs2/fsck/link.c         |   14 ++++++++------
 gfs2/fsck/link.h         |   10 +++++-----
 gfs2/fsck/lost_n_found.c |   29 ++++++++++++++---------------
 gfs2/fsck/pass1.c        |    2 +-
 gfs2/fsck/pass2.c        |   20 ++++++++++----------
 gfs2/fsck/pass3.c        |    4 ++--
 gfs2/fsck/pass4.c        |   18 ++++++++++--------
 8 files changed, 52 insertions(+), 49 deletions(-)

diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h
index 25bc3b9..6353dfc 100644
--- a/gfs2/fsck/fsck.h
+++ b/gfs2/fsck/fsck.h
@@ -29,8 +29,8 @@ struct inode_info
 {
         struct osi_node node;
         uint64_t   inode;
-        uint16_t   link_count;   /* the number of links the inode
-                                  * thinks it has */
+        uint16_t   di_nlink;   /* the number of links the inode
+				* thinks it has */
         uint16_t   counted_links; /* the number of links we've found */
 };
 
diff --git a/gfs2/fsck/link.c b/gfs2/fsck/link.c
index 24d5134..18aeeb9 100644
--- a/gfs2/fsck/link.c
+++ b/gfs2/fsck/link.c
@@ -11,9 +11,11 @@
 #include "inode_hash.h"
 #include "link.h"
 
-int set_link_count(uint64_t inode_no, uint32_t count)
+int set_di_nlink(struct gfs2_inode *ip)
 {
 	struct inode_info *ii;
+	uint64_t inode_no = ip->i_di.di_num.no_addr;
+
 	/*log_debug( _("Setting link count to %u for %" PRIu64
 	  " (0x%" PRIx64 ")\n"), count, inode_no, inode_no);*/
 	/* If the list has entries, look for one that matches inode_no */
@@ -21,14 +23,14 @@ int set_link_count(uint64_t inode_no, uint32_t count)
 	if (!ii)
 		ii = inodetree_insert(inode_no);
 	if (ii)
-		ii->link_count = count;
+		ii->di_nlink = ip->i_di.di_nlink;
 	else
 		return -1;
 	return 0;
 }
 
-int increment_link(uint64_t inode_no, uint64_t referenced_from,
-		   const char *why)
+int incr_link_count(uint64_t inode_no, uint64_t referenced_from,
+		    const char *why)
 {
 	struct inode_info *ii = NULL;
 
@@ -59,8 +61,8 @@ int increment_link(uint64_t inode_no, uint64_t referenced_from,
 	return 0;
 }
 
-int decrement_link(uint64_t inode_no, uint64_t referenced_from,
-		   const char *why)
+int decr_link_count(uint64_t inode_no, uint64_t referenced_from,
+		    const char *why)
 {
 	struct inode_info *ii = NULL;
 
diff --git a/gfs2/fsck/link.h b/gfs2/fsck/link.h
index f890575..ad040e6 100644
--- a/gfs2/fsck/link.h
+++ b/gfs2/fsck/link.h
@@ -1,10 +1,10 @@
 #ifndef _LINK_H
 #define _LINK_H
 
-int set_link_count(uint64_t inode_no, uint32_t count);
-int increment_link(uint64_t inode_no, uint64_t referenced_from,
-		   const char *why);
-int decrement_link(uint64_t inode_no, uint64_t referenced_from,
-		   const char *why);
+int set_di_nlink(struct gfs2_inode *ip);
+int incr_link_count(uint64_t inode_no, uint64_t referenced_from,
+		    const char *why);
+int decr_link_count(uint64_t inode_no, uint64_t referenced_from,
+		    const char *why);
 
 #endif /* _LINK_H */
diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index 1cadab9..684792a 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -42,8 +42,7 @@ int add_inode_to_lf(struct gfs2_inode *ip){
 		   the root directory.  We must increment the nlink value
 		   in the hash table to keep them in sync so that pass4 can
 		   detect and fix any descrepancies. */
-		set_link_count(sdp->sd_sb.sb_root_dir.no_addr,
-			       sdp->md.rooti->i_di.di_nlink);
+		set_di_nlink(sdp->md.rooti);
 
 		q = block_type(lf_dip->i_di.di_num.no_addr);
 		if (q != gfs2_inode_dir) {
@@ -59,15 +58,15 @@ int add_inode_to_lf(struct gfs2_inode *ip){
 					  _("lost+found dinode"),
 					  gfs2_inode_dir);
 			/* root inode links to lost+found */
-			increment_link(sdp->md.rooti->i_di.di_num.no_addr,
+			incr_link_count(sdp->md.rooti->i_di.di_num.no_addr,
 				       lf_dip->i_di.di_num.no_addr, _("root"));
 			/* lost+found link for '.' from itself */
-			increment_link(lf_dip->i_di.di_num.no_addr,
-				       lf_dip->i_di.di_num.no_addr, "\".\"");
+			incr_link_count(lf_dip->i_di.di_num.no_addr,
+					lf_dip->i_di.di_num.no_addr, "\".\"");
 			/* lost+found link for '..' back to root */
-			increment_link(lf_dip->i_di.di_num.no_addr,
-				       sdp->md.rooti->i_di.di_num.no_addr,
-				       "\"..\"");
+			incr_link_count(lf_dip->i_di.di_num.no_addr,
+					sdp->md.rooti->i_di.di_num.no_addr,
+					"\"..\"");
 		}
 		log_info( _("lost+found directory is dinode %lld (0x%llx)\n"),
 			  (unsigned long long)lf_dip->i_di.di_num.no_addr,
@@ -104,9 +103,9 @@ int add_inode_to_lf(struct gfs2_inode *ip){
 				  (unsigned long long)ip->i_di.di_num.no_addr,
 				  (unsigned long long)di->dotdot_parent,
 				  (unsigned long long)di->dotdot_parent);
-			decrement_link(di->dotdot_parent,
-				       ip->i_di.di_num.no_addr,
-				       _(".. unlinked, moving to lost+found"));
+			decr_link_count(di->dotdot_parent,
+					ip->i_di.di_num.no_addr,
+					_(".. unlinked, moving to lost+found"));
 			dip = fsck_load_inode(sdp, di->dotdot_parent);
 			if (dip->i_di.di_nlink > 0) {
 				dip->i_di.di_nlink--;
@@ -183,12 +182,12 @@ int add_inode_to_lf(struct gfs2_inode *ip){
 		reprocess_inode(lf_dip, "lost+found");
 
 	/* This inode is linked from lost+found */
-	increment_link(ip->i_di.di_num.no_addr, lf_dip->i_di.di_num.no_addr,
-		       _("from lost+found"));
+	incr_link_count(ip->i_di.di_num.no_addr, lf_dip->i_di.di_num.no_addr,
+			_("from lost+found"));
 	/* If it's a directory, lost+found is back-linked to it via .. */
 	if (S_ISDIR(ip->i_di.di_mode))
-		increment_link(lf_dip->i_di.di_num.no_addr,
-			       ip->i_di.di_mode, _("to lost+found"));
+		incr_link_count(lf_dip->i_di.di_num.no_addr,
+				ip->i_di.di_mode, _("to lost+found"));
 
 	log_notice( _("Added inode #%llu (0x%llx) to lost+found dir\n"),
 		    (unsigned long long)ip->i_di.di_num.no_addr,
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 8f399e1..477242c 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -1058,7 +1058,7 @@ static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip)
 			goto bad_dinode;
 		return 0;
 	}
-	if (set_link_count(ip->i_di.di_num.no_addr, ip->i_di.di_nlink))
+	if (set_di_nlink(ip))
 		goto bad_dinode;
 
 	if (S_ISDIR(ip->i_di.di_mode) &&
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index de91a0d..3e2e31e 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -210,7 +210,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 			(*count)++;
 			ds->entry_count++;
 			/* can't do this because the block is out of range:
-			   increment_link(entryblock); */
+			   incr_link_count(entryblock); */
 			return 0;
 		}
 	}
@@ -297,7 +297,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 
 		/* Don't decrement the link here: Here in pass2, we increment
 		   only when we know it's okay.
-		   decrement_link(ip->i_di.di_num.no_addr); */
+		   decr_link_count(ip->i_di.di_num.no_addr); */
 		/* If it was previously marked invalid (i.e. known
 		   to be bad, not just a free block, etc.) then the temptation
 		   would be to delete any metadata it holds.  The trouble is:
@@ -495,8 +495,8 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 	}
 dentry_is_valid:
 	/* This directory inode links to this inode via this dentry */
-	increment_link(entryblock, ip->i_di.di_num.no_addr,
-		       _("valid reference"));
+	incr_link_count(entryblock, ip->i_di.di_num.no_addr,
+			_("valid reference"));
 	(*count)++;
 	ds->entry_count++;
 	/* End of checks */
@@ -587,9 +587,9 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
 			if (cur_blks != sysinode->i_di.di_blocks)
 				reprocess_inode(sysinode, dirname);
 			/* This system inode is linked to itself via '.' */
-			increment_link(sysinode->i_di.di_num.no_addr,
-				       sysinode->i_di.di_num.no_addr,
-				       "sysinode \".\"");
+			incr_link_count(sysinode->i_di.di_num.no_addr,
+					sysinode->i_di.di_num.no_addr,
+					"sysinode \".\"");
 			ds.entry_count++;
 			free(filename);
 		} else
@@ -800,9 +800,9 @@ int pass2(struct gfs2_sbd *sdp)
 					reprocess_inode(ip, dirname);
 				}
 				/* directory links to itself via '.' */
-				increment_link(ip->i_di.di_num.no_addr,
-					       ip->i_di.di_num.no_addr,
-					       _("\". (itself)\""));
+				incr_link_count(ip->i_di.di_num.no_addr,
+						ip->i_di.di_num.no_addr,
+						_("\". (itself)\""));
 				ds.entry_count++;
 				free(filename);
 				log_err( _("The directory was fixed.\n"));
diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c
index f6cbbc2..580c662 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -50,7 +50,7 @@ static int attach_dotdot_to(struct gfs2_sbd *sdp, uint64_t newdotdot,
 	if (gfs2_dirent_del(ip, filename, filename_len))
 		log_warn( _("Unable to remove \"..\" directory entry.\n"));
 	else
-		decrement_link(olddotdot, block, _("old \"..\""));
+		decr_link_count(olddotdot, block, _("old \"..\""));
 	cur_blks = ip->i_di.di_blocks;
 	dir_add(ip, filename, filename_len, &pip->i_di.di_num, DT_DIR);
 	if (cur_blks != ip->i_di.di_blocks) {
@@ -61,7 +61,7 @@ static int attach_dotdot_to(struct gfs2_sbd *sdp, uint64_t newdotdot,
 			(unsigned long long)ip->i_di.di_num.no_addr);
 		reprocess_inode(ip, dirname);
 	}
-	increment_link(newdotdot, block, _("new \"..\""));
+	incr_link_count(newdotdot, block, _("new \"..\""));
 	fsck_inode_put(&ip);
 	fsck_inode_put(&pip);
 	free(filename);
diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c
index 1e52c3f..04fb075 100644
--- a/gfs2/fsck/pass4.c
+++ b/gfs2/fsck/pass4.c
@@ -140,11 +140,11 @@ static int scan_inode_list(struct gfs2_sbd *sdp) {
 				log_err( _("Unlinked inode left unlinked\n"));
 			fsck_inode_put(&ip);
 		} /* if (ii->counted_links == 0) */
-		else if (ii->link_count != ii->counted_links) {
+		else if (ii->di_nlink != ii->counted_links) {
 			log_err( _("Link count inconsistent for inode %llu"
 				" (0x%llx) has %u but fsck found %u.\n"),
 				(unsigned long long)ii->inode, 
-				(unsigned long long)ii->inode, ii->link_count,
+				(unsigned long long)ii->inode, ii->di_nlink,
 				ii->counted_links);
 			/* Read in the inode, adjust the link count,
 			 * and write it back out */
@@ -154,19 +154,21 @@ static int scan_inode_list(struct gfs2_sbd *sdp) {
 				  (unsigned long long)ii->inode)) {
 				ip = fsck_load_inode(sdp, ii->inode); /* bread, inode_get */
 				fix_link_count(ii, ip);
-				ii->link_count = ii->counted_links;
+				ii->di_nlink = ii->counted_links;
 				fsck_inode_put(&ip); /* out, brelse, free */
 				log_warn( _("Link count updated to %d for "
-					    "inode %" PRIu64 " (0x%"
-					    PRIx64 ") \n"), ii->link_count,
-					  ii->inode, ii->inode);
+					    "inode %llu (0x%llx)\n"),
+					  ii->di_nlink,
+					  (unsigned long long)ii->inode,
+					  (unsigned long long)ii->inode);
 			} else {
 				log_err( _("Link count for inode %" PRIu64 " (0x%" PRIx64
 						") still incorrect\n"), ii->inode, ii->inode);
 			}
 		}
-		log_debug( _("block %" PRIu64 " (0x%" PRIx64 ") has link count %d\n"),
-				  ii->inode, ii->inode, ii->link_count);
+		log_debug( _("block %llu (0x%llx) has link count %d\n"),
+			 (unsigned long long)ii->inode,
+			 (unsigned long long)ii->inode, ii->di_nlink);
 	} /* osi_list_foreach(tmp, list) */
 
 	if (lf_addition) {
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 10/66] fsck.gfs2: fsck.gfs2: Sync di_nlink adding links for lost+found
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (8 preceding siblings ...)
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 09/66] fsck.gfs2: fsck.gfs2: Rename nlink functions to be intuitive rpeterso
@ 2012-01-20 15:09 ` rpeterso
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 11/66] fsck.gfs2: fsck.gfs2: Make dir entry count 32 bits rpeterso
                   ` (55 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:09 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

When adding a ".." entry to a directory newly linked to lost+found
fsck.gfs2 needs to update its di_nlink value to account for the new
link.  If not, it can "correct" the di_nlink value to the wrong
value and not find the error until a second fsck.gfs2 is done.
This only happens in the rare case where there is no pre-existing
".." entry that may be reused to re-link to lost+found.

rhbz#675723
---
 gfs2/fsck/lost_n_found.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index 684792a..e5d7571 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -109,6 +109,7 @@ int add_inode_to_lf(struct gfs2_inode *ip){
 			dip = fsck_load_inode(sdp, di->dotdot_parent);
 			if (dip->i_di.di_nlink > 0) {
 				dip->i_di.di_nlink--;
+				set_di_nlink(dip); /* keep inode tree in sync */
 				log_debug(_("Decrementing its links to %d\n"),
 					  dip->i_di.di_nlink);
 				bmodified(dip->i_bh);
@@ -119,6 +120,7 @@ int add_inode_to_lf(struct gfs2_inode *ip){
 					    "Changing it to 0.\n"),
 					  dip->i_di.di_nlink);
 				dip->i_di.di_nlink = 0;
+				set_di_nlink(dip); /* keep inode tree in sync */
 				bmodified(dip->i_bh);
 			}
 			fsck_inode_put(&dip);
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 11/66] fsck.gfs2: fsck.gfs2: Make dir entry count 32 bits
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (9 preceding siblings ...)
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 10/66] fsck.gfs2: fsck.gfs2: Sync di_nlink adding links for lost+found rpeterso
@ 2012-01-20 15:09 ` rpeterso
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 12/66] fsck.gfs2: get rid of triple negative logic rpeterso
                   ` (54 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:09 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

When counting directory links, fsck.gfs2 was using a 16-bit integer.
Therefore, if a directory had more than 65535 links, it would wrap to
zero and the counts would be damaged by fsck.gfs2.  Subsequent runs would
not find the corruption, but it was there nonetheless.  You would
encounter it if you tried to delete enough entries to cause the count
to become negative.

rhbz#675723
---
 gfs2/fsck/fsck.h     |    6 +++---
 gfs2/fsck/metawalk.c |    8 ++++----
 gfs2/fsck/metawalk.h |    2 +-
 gfs2/fsck/pass1.c    |    2 +-
 gfs2/fsck/pass1b.c   |    4 ++--
 gfs2/fsck/pass2.c    |    2 +-
 6 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h
index 6353dfc..0fed06b 100644
--- a/gfs2/fsck/fsck.h
+++ b/gfs2/fsck/fsck.h
@@ -29,9 +29,9 @@ struct inode_info
 {
         struct osi_node node;
         uint64_t   inode;
-        uint16_t   di_nlink;   /* the number of links the inode
-				* thinks it has */
-        uint16_t   counted_links; /* the number of links we've found */
+        uint32_t   di_nlink;    /* the number of links the inode
+				 * thinks it has */
+        uint32_t   counted_links; /* the number of links we've found */
 };
 
 struct dir_info
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 541e468..2db389f 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -300,7 +300,7 @@ static void dirblk_truncate(struct gfs2_inode *ip, struct gfs2_dirent *fixb,
  *         -1 - error occurred
  */
 static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
-		  int type, uint16_t *count, struct metawalk_fxns *pass)
+		  int type, uint32_t *count, struct metawalk_fxns *pass)
 {
 	struct gfs2_leaf *leaf = NULL;
 	struct gfs2_dirent *dent;
@@ -597,7 +597,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 	struct gfs2_buffer_head *lbh;
 	int lindex;
 	struct gfs2_sbd *sdp = ip->i_sbd;
-	uint16_t count;
+	uint32_t count;
 	int ref_count = 0, exp_count = 0;
 
 	/* Find the first valid leaf pointer in range and use it as our "old"
@@ -1372,7 +1372,7 @@ int check_linear_dir(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
 		     struct metawalk_fxns *pass)
 {
 	int error = 0;
-	uint16_t count = 0;
+	uint32_t count = 0;
 
 	error = check_entries(ip, bh, DIR_LINEAR, &count, pass);
 	if (error < 0) {
@@ -1405,7 +1405,7 @@ int check_dir(struct gfs2_sbd *sdp, uint64_t block, struct metawalk_fxns *pass)
 static int remove_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 			 struct gfs2_dirent *prev_de,
 			 struct gfs2_buffer_head *bh,
-			 char *filename, uint16_t *count, void *private)
+			 char *filename, uint32_t *count, void *private)
 {
 	/* the metawalk_fxn's private field must be set to the dentry
 	 * block we want to clear */
diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h
index ea023b6..c15d7b7 100644
--- a/gfs2/fsck/metawalk.h
+++ b/gfs2/fsck/metawalk.h
@@ -74,7 +74,7 @@ struct metawalk_fxns {
 	int (*check_dentry) (struct gfs2_inode *ip, struct gfs2_dirent *de,
 			     struct gfs2_dirent *prev,
 			     struct gfs2_buffer_head *bh,
-			     char *filename, uint16_t *count, void *private);
+			     char *filename, uint32_t *count, void *private);
 	int (*check_eattr_entry) (struct gfs2_inode *ip,
 				  struct gfs2_buffer_head *leaf_bh,
 				  struct gfs2_ea_header *ea_hdr,
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 477242c..49a8f4e 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -145,7 +145,7 @@ static int resuscitate_metalist(struct gfs2_inode *ip, uint64_t block,
 static int resuscitate_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 			      struct gfs2_dirent *prev_de,
 			      struct gfs2_buffer_head *bh, char *filename,
-			      uint16_t *count, void *priv)
+			      uint32_t *count, void *priv)
 {
 	struct gfs2_sbd *sdp = ip->i_sbd;
 	struct gfs2_dirent dentry, *de;
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index b4580bf..ce358c4 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -47,7 +47,7 @@ static int check_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr,
 				void *private);
 static int find_dentry(struct gfs2_inode *ip, struct gfs2_dirent *de,
 		       struct gfs2_dirent *prev, struct gfs2_buffer_head *bh,
-		       char *filename, uint16_t *count, void *priv);
+		       char *filename, uint32_t *count, void *priv);
 
 struct metawalk_fxns find_refs = {
 	.private = NULL,
@@ -166,7 +166,7 @@ static int check_dir_dup_ref(struct gfs2_inode *ip,  struct gfs2_dirent *de,
 static int find_dentry(struct gfs2_inode *ip, struct gfs2_dirent *de,
 		       struct gfs2_dirent *prev,
 		       struct gfs2_buffer_head *bh, char *filename,
-		       uint16_t *count, void *priv)
+		       uint32_t *count, void *priv)
 {
 	struct osi_node *n, *next = NULL;
 	osi_list_t *tmp2;
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 3e2e31e..abb77c3 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -166,7 +166,7 @@ struct metawalk_fxns pass2_fxns_delete = {
 static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 		 struct gfs2_dirent *prev_de,
 		 struct gfs2_buffer_head *bh, char *filename,
-		 uint16_t *count, void *priv)
+		 uint32_t *count, void *priv)
 {
 	struct gfs2_sbd *sdp = ip->i_sbd;
 	uint8_t q;
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 12/66] fsck.gfs2: get rid of triple negative logic
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (10 preceding siblings ...)
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 11/66] fsck.gfs2: fsck.gfs2: Make dir entry count 32 bits rpeterso
@ 2012-01-20 15:09 ` rpeterso
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 13/66] dirent_repair needs to mark the buffer as modified rpeterso
                   ` (53 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:09 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch changes the logic of the code from being triple-negative
to single-negative so it won't twist your brain into knots.

rhbz#675723
---
 gfs2/fsck/metawalk.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 2db389f..888acec 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -930,7 +930,7 @@ static int delete_block_if_notdup(struct gfs2_inode *ip, uint64_t block,
 	uint8_t q;
 	struct duptree *d;
 
-	if (!valid_block(ip->i_sbd, block) != 0)
+	if (!valid_block(ip->i_sbd, block))
 		return -EFAULT;
 
 	q = block_type(block);
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 13/66] dirent_repair needs to mark the buffer as modified
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (11 preceding siblings ...)
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 12/66] fsck.gfs2: get rid of triple negative logic rpeterso
@ 2012-01-20 15:09 ` rpeterso
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 14/66] fsck.gfs2: fsck.gfs2: Ask to reclaim unlinked meta per-rgrp only rpeterso
                   ` (52 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:09 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch adds a call to bmodified to function dirent_repair.  Without
setting the modified bit, directory repairs may be forgotten and never
written back to disk, leaving the damage in place.

rhbz#675723
---
 gfs2/fsck/metawalk.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 888acec..94de22a 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -264,6 +264,7 @@ static int dirent_repair(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
 		de->de_rec_len = GFS2_DIRENT_SIZE(de->de_name_len);
 	}
 	gfs2_dirent_out(de, (char *)dent);
+	bmodified(bh);
 	return 0;
 }
 
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 14/66] fsck.gfs2: fsck.gfs2: Ask to reclaim unlinked meta per-rgrp only
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (12 preceding siblings ...)
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 13/66] dirent_repair needs to mark the buffer as modified rpeterso
@ 2012-01-20 15:09 ` rpeterso
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 15/66] fsck.gfs2: fsck.gfs2: Refactor add_dotdot function in lost+found rpeterso
                   ` (51 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:09 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

Before this patch, fsck.gfs2 would ask for every unlinked metadata bit
whether you wanted to reclaim it as free space.  This patch makes it
ask only once per resource group, and reports which resource group
so that the user doesn't think it's stuck in an infinite loop.

rhbz#675723
---
 gfs2/fsck/initialize.c |   16 ++++++++++++----
 1 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 29e4560..08da24f 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -192,7 +192,7 @@ static void check_rgrp_integrity(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
 				 int *this_rg_bad)
 {
 	uint32_t rg_free, rg_reclaimed;
-	int rgb, x, y, off, bytes_to_check, total_bytes_to_check;
+	int rgb, x, y, off, bytes_to_check, total_bytes_to_check, asked = 0;
 	unsigned int state;
 
 	rg_free = rg_reclaimed = 0;
@@ -231,9 +231,17 @@ static void check_rgrp_integrity(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
 				}
 				/* GFS2_BLKST_UNLINKED */
 				*this_rg_bad = 1;
-				if (!(*fixit)) {
-					if (query(_("Okay to reclaim unlinked "
-						    "inodes? (y/n)")))
+				if (!asked) {
+					char msg[256];
+
+					asked = 1;
+					sprintf(msg,
+						_("Okay to reclaim unlinked "
+						  "inodes in resource group "
+						  "%lld (0x%llx)? (y/n)"),
+						(unsigned long long)rgd->ri.ri_addr,
+						(unsigned long long)rgd->ri.ri_addr);
+					if (query("%s", msg))
 						*fixit = 1;
 				}
 				if (!(*fixit))
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 15/66] fsck.gfs2: fsck.gfs2: Refactor add_dotdot function in lost+found
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (13 preceding siblings ...)
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 14/66] fsck.gfs2: fsck.gfs2: Ask to reclaim unlinked meta per-rgrp only rpeterso
@ 2012-01-20 15:09 ` rpeterso
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 16/66] libgfs2: libgfs2: Use __FUNCTION__ rather than __FILE__ rpeterso
                   ` (50 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:09 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This function factors out a section of code from function add_inode_to_lf.
This makes it easier to read and gives it the ability to print better
messages regarding where the block was previously linked.

rhbz#675723
---
 gfs2/fsck/lost_n_found.c |  113 ++++++++++++++++++++++++++--------------------
 1 files changed, 64 insertions(+), 49 deletions(-)

diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index e5d7571..7886625 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -15,6 +15,69 @@
 #include "metawalk.h"
 #include "util.h"
 
+static void add_dotdot(struct gfs2_inode *ip)
+{
+	struct dir_info *di;
+	struct gfs2_sbd *sdp = ip->i_sbd;
+
+	log_info( _("Adding .. entry to directory %llu (0x%llx) pointing back "
+		    "to lost+found\n"),
+		  (unsigned long long)ip->i_di.di_num.no_addr,
+		  (unsigned long long)ip->i_di.di_num.no_addr);
+
+	/* If there's a pre-existing .. directory entry, we have to
+	   back out the links. */
+	di = dirtree_find(ip->i_di.di_num.no_addr);
+	if (di && !valid_block(sdp, di->dotdot_parent) == 0) {
+		struct gfs2_inode *dip;
+
+		log_debug(_("Directory %lld (0x%llx) already had a "
+			    "\"..\" link to %lld (0x%llx).\n"),
+			  (unsigned long long)ip->i_di.di_num.no_addr,
+			  (unsigned long long)ip->i_di.di_num.no_addr,
+			  (unsigned long long)di->dotdot_parent,
+			  (unsigned long long)di->dotdot_parent);
+		decr_link_count(di->dotdot_parent, ip->i_di.di_num.no_addr,
+				_(".. unlinked, moving to lost+found"));
+		dip = fsck_load_inode(sdp, di->dotdot_parent);
+		if (dip->i_di.di_nlink > 0) {
+			dip->i_di.di_nlink--;
+			set_di_nlink(dip); /* keep inode tree in sync */
+			log_debug(_("Decrementing its links to %d\n"),
+				  dip->i_di.di_nlink);
+			bmodified(dip->i_bh);
+		} else if (!dip->i_di.di_nlink) {
+			log_debug(_("Its link count is zero.\n"));
+		} else {
+			log_debug(_("Its link count is %d!  Changing "
+				    "it to 0.\n"), dip->i_di.di_nlink);
+			dip->i_di.di_nlink = 0;
+			set_di_nlink(dip); /* keep inode tree in sync */
+			bmodified(dip->i_bh);
+		}
+		fsck_inode_put(&dip);
+		di = NULL;
+	} else {
+		if (di)
+			log_debug(_("Couldn't find a valid \"..\" entry "
+				    "for orphan directory %lld (0x%llx): "
+				    "'..' = 0x%llx\n"),
+				  (unsigned long long)ip->i_di.di_num.no_addr,
+				  (unsigned long long)ip->i_di.di_num.no_addr,
+				  (unsigned long long)di->dotdot_parent);
+		else
+			log_debug(_("Couldn't find a valid \"..\" entry "
+				    "for orphan directory %lld (0x%llx)\n"),
+				  (unsigned long long)ip->i_di.di_num.no_addr,
+				  (unsigned long long)ip->i_di.di_num.no_addr);
+	}
+	if (gfs2_dirent_del(ip, "..", 2))
+		log_warn( _("add_inode_to_lf:  Unable to remove "
+			    "\"..\" directory entry.\n"));
+
+	dir_add(ip, "..", 2, &(lf_dip->i_di.di_num), DT_DIR);
+}
+
 /* add_inode_to_lf - Add dir entry to lost+found for the inode
  * @ip: inode to add to lost + found
  *
@@ -86,55 +149,7 @@ int add_inode_to_lf(struct gfs2_inode *ip){
 
 	switch(ip->i_di.di_mode & S_IFMT){
 	case S_IFDIR:
-		log_info( _("Adding .. entry pointing to lost+found for "
-			    "directory %llu (0x%llx)\n"),
-			  (unsigned long long)ip->i_di.di_num.no_addr,
-			  (unsigned long long)ip->i_di.di_num.no_addr);
-
-		/* If there's a pre-existing .. directory entry, we have to
-		   back out the links. */
-		di = dirtree_find(ip->i_di.di_num.no_addr);
-		if (di && !valid_block(sdp, di->dotdot_parent) == 0) {
-			struct gfs2_inode *dip;
-
-			log_debug(_("Directory %lld (0x%llx) already had a "
-				    "\"..\" link to %lld (0x%llx).\n"),
-				  (unsigned long long)ip->i_di.di_num.no_addr,
-				  (unsigned long long)ip->i_di.di_num.no_addr,
-				  (unsigned long long)di->dotdot_parent,
-				  (unsigned long long)di->dotdot_parent);
-			decr_link_count(di->dotdot_parent,
-					ip->i_di.di_num.no_addr,
-					_(".. unlinked, moving to lost+found"));
-			dip = fsck_load_inode(sdp, di->dotdot_parent);
-			if (dip->i_di.di_nlink > 0) {
-				dip->i_di.di_nlink--;
-				set_di_nlink(dip); /* keep inode tree in sync */
-				log_debug(_("Decrementing its links to %d\n"),
-					  dip->i_di.di_nlink);
-				bmodified(dip->i_bh);
-			} else if (!dip->i_di.di_nlink) {
-				log_debug(_("Its link count is zero.\n"));
-			} else {
-				log_debug(_("Its link count is %d!  "
-					    "Changing it to 0.\n"),
-					  dip->i_di.di_nlink);
-				dip->i_di.di_nlink = 0;
-				set_di_nlink(dip); /* keep inode tree in sync */
-				bmodified(dip->i_bh);
-			}
-			fsck_inode_put(&dip);
-			di = NULL;
-		} else
-			log_debug(_("Couldn't find a valid \"..\" entry "
-				    "for orphan directory %lld (0x%llx)\n"),
-				  (unsigned long long)ip->i_di.di_num.no_addr,
-				  (unsigned long long)ip->i_di.di_num.no_addr);
-		if (gfs2_dirent_del(ip, "..", 2))
-			log_warn( _("add_inode_to_lf:  Unable to remove "
-				    "\"..\" directory entry.\n"));
-
-		dir_add(ip, "..", 2, &(lf_dip->i_di.di_num), DT_DIR);
+		add_dotdot(ip);
 		sprintf(tmp_name, "lost_dir_%llu",
 			(unsigned long long)ip->i_di.di_num.no_addr);
 		inode_type = DT_DIR;
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 16/66] libgfs2: libgfs2: Use __FUNCTION__ rather than __FILE__
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (14 preceding siblings ...)
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 15/66] fsck.gfs2: fsck.gfs2: Refactor add_dotdot function in lost+found rpeterso
@ 2012-01-20 15:09 ` rpeterso
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 17/66] fsck.gfs2: fsck.gfs2: Don't stop invalidating blocks on invalid rpeterso
                   ` (49 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:09 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch changes the debug output of gfs2-utils to use __FUNCTION__
rather than __FILE__.  The output file is much smaller.  Digging through
a 6.5GB output is better and faster than a 9GB output file.

rhbz#675723
---
 gfs2/fsck/metawalk.c   |   13 +++----------
 gfs2/fsck/metawalk.h   |    2 +-
 gfs2/libgfs2/libgfs2.h |    2 +-
 3 files changed, 5 insertions(+), 12 deletions(-)

diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 94de22a..dd0b929 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -98,17 +98,10 @@ int _fsck_blockmap_set(struct gfs2_inode *ip, uint64_t bblock,
 	int error;
 
 	if (print_level >= MSG_DEBUG) {
-		const char *p;
-
-		p = strrchr(caller, '/');
-		if (p)
-			p++;
-		else
-			p = caller;
 		/* I'm circumventing the log levels here on purpose to make the
 		   output easier to debug. */
 		if (ip->i_di.di_num.no_addr == bblock) {
-			print_fsck_log(MSG_DEBUG, p, fline,
+			print_fsck_log(MSG_DEBUG, caller, fline,
 				       _("%s inode found at block %lld "
 					 "(0x%llx): marking as '%s'\n"),
 				       btype, (unsigned long long)
@@ -117,7 +110,7 @@ int _fsck_blockmap_set(struct gfs2_inode *ip, uint64_t bblock,
 				       ip->i_di.di_num.no_addr,
 				       block_type_string(mark));
 		} else if (mark == gfs2_bad_block || mark == gfs2_meta_inval) {
-			print_fsck_log(MSG_DEBUG, p, fline,
+			print_fsck_log(MSG_DEBUG, caller, fline,
 				       _("inode %lld (0x%llx) references "
 					 "%s block %lld (0x%llx): "
 					 "marking as '%s'\n"),
@@ -129,7 +122,7 @@ int _fsck_blockmap_set(struct gfs2_inode *ip, uint64_t bblock,
 				       (unsigned long long)bblock,
 				       block_type_string(mark));
 		} else {
-			print_fsck_log(MSG_DEBUG, p, fline,
+			print_fsck_log(MSG_DEBUG, caller, fline,
 				       _("inode %lld (0x%llx) references "
 					 "%s block %lld (0x%llx): "
 					 "marking as '%s'\n"),
diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h
index c15d7b7..d705726 100644
--- a/gfs2/fsck/metawalk.h
+++ b/gfs2/fsck/metawalk.h
@@ -39,7 +39,7 @@ extern struct gfs2_inode *fsck_system_inode(struct gfs2_sbd *sdp,
 #define is_duplicate(dblock) ((dupfind(dblock)) ? 1 : 0)
 
 #define fsck_blockmap_set(ip, b, bt, m) _fsck_blockmap_set(ip, b, bt, m, \
-							   __FILE__, __LINE__)
+							   __FUNCTION__, __LINE__)
 
 /* metawalk_fxns: function pointers to check various parts of the fs
  *
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 0ddb48f..9bae01b 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -693,7 +693,7 @@ extern int print_level;
 #define MSG_NULL        1
 
 #define print_log(priority, format...) \
-	do { print_fsck_log(priority, __FILE__, __LINE__, ## format); } while(0)
+	do { print_fsck_log(priority, __FUNCTION__, __LINE__, ## format); } while(0)
 
 #define log_debug(format...) \
 	do { if(print_level >= MSG_DEBUG) print_log(MSG_DEBUG, format); } while(0)
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 17/66] fsck.gfs2: fsck.gfs2: Don't stop invalidating blocks on invalid
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (15 preceding siblings ...)
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 16/66] libgfs2: libgfs2: Use __FUNCTION__ rather than __FILE__ rpeterso
@ 2012-01-20 15:09 ` rpeterso
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 18/66] fsck.gfs2: fsck.gfs2: Find and clear duplicate leaf blocks refs rpeterso
                   ` (48 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:09 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

When fsck found a duplicate reference to a block it invalidated the dinode's
metadata.  But if it encountered an invalid block, for example, out of range,
the invalidating would stop.  If we encounter a block that isn't valid, we
obviously can't invalidate it.  However, if we return an error, all future
invalidating will stop for that dinode.  That's wrong because we need it to
continue to invalidate the other valid blocks.  If we don't do this, block
references that follow the bad one that are also referenced elsewhere
(duplicates) won't be flagged as such.  As a result, they'll be freed when
this corrupt dinode is deleted, despite being used by another dinode as a
valid block.  This patch makes it return a good return code so the invalidating
continues.

rhbz#675723
---
 gfs2/fsck/pass1.c |   11 +++++++++--
 1 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 49a8f4e..271075c 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -825,8 +825,15 @@ static int mark_block_invalid(struct gfs2_inode *ip, uint64_t block,
 {
 	uint8_t q;
 
-	if (!valid_block(ip->i_sbd, block) != 0)
-		return -EFAULT;
+	/* If the block isn't valid, we obviously can't invalidate it.
+	 * However, if we return an error, invalidating will stop, and
+	 * we want it to continue to invalidate the valid blocks.  If we
+	 * don't do this, block references that follow that are also
+	 * referenced elsewhere (duplicates) won't be flagged as such,
+	 * and as a result, they'll be freed when this dinode is deleted,
+	 * despite being used by another dinode as a valid block. */
+	if (!valid_block(ip->i_sbd, block))
+		return 0;
 
 	q = block_type(block);
 	if (q != gfs2_block_free) {
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 18/66] fsck.gfs2: fsck.gfs2: Find and clear duplicate leaf blocks refs
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (16 preceding siblings ...)
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 17/66] fsck.gfs2: fsck.gfs2: Don't stop invalidating blocks on invalid rpeterso
@ 2012-01-20 15:09 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 19/66] fsck.gfs2: fsck.gfs2: Move check_num_ptrs from metawalk to pass1 rpeterso
                   ` (47 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:09 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

Duplicate references that were in leaf blocks were never found nor
cleared.  This patch adds that capability.

rhbz#675723
---
 gfs2/fsck/pass1b.c |   15 +++++++++++++--
 1 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index ce358c4..65e6de9 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -26,6 +26,7 @@ struct dup_handler {
 	int ref_count;
 };
 
+static int check_leaf(struct gfs2_inode *ip, uint64_t block, void *private);
 static int check_metalist(struct gfs2_inode *ip, uint64_t block,
 			  struct gfs2_buffer_head **bh, int h, void *private);
 static int check_data(struct gfs2_inode *ip, uint64_t block, void *private);
@@ -51,7 +52,7 @@ static int find_dentry(struct gfs2_inode *ip, struct gfs2_dirent *de,
 
 struct metawalk_fxns find_refs = {
 	.private = NULL,
-	.check_leaf = NULL,
+	.check_leaf = check_leaf,
 	.check_metalist = check_metalist,
 	.check_data = check_data,
 	.check_eattr_indir = check_eattr_indir,
@@ -73,6 +74,11 @@ struct metawalk_fxns find_dirents = {
 	.check_eattr_extentry = NULL,
 };
 
+static int check_leaf(struct gfs2_inode *ip, uint64_t block, void *private)
+{
+	return add_duplicate_ref(ip, block, ref_as_meta, 1, INODE_VALID);
+}
+
 static int check_metalist(struct gfs2_inode *ip, uint64_t block,
 			  struct gfs2_buffer_head **bh, int h, void *private)
 {
@@ -250,6 +256,11 @@ static int clear_dup_data(struct gfs2_inode *ip, uint64_t block, void *private)
 	return clear_dup_metalist(ip, block, NULL, 0, private);
 }
 
+static int clear_leaf(struct gfs2_inode *ip, uint64_t block, void *private)
+{
+	return clear_dup_metalist(ip, block, NULL, 0, private);
+}
+
 static int clear_dup_eattr_indir(struct gfs2_inode *ip, uint64_t block,
 				 uint64_t parent, struct gfs2_buffer_head **bh,
 				 void *private)
@@ -392,7 +403,7 @@ static int clear_a_reference(struct gfs2_sbd *sdp, struct duptree *b,
 	osi_list_t *tmp, *x;
 	struct metawalk_fxns clear_dup_fxns = {
 		.private = NULL,
-		.check_leaf = NULL,
+		.check_leaf = clear_leaf,
 		.check_metalist = clear_dup_metalist,
 		.check_data = clear_dup_data,
 		.check_eattr_indir = clear_dup_eattr_indir,
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 19/66] fsck.gfs2: fsck.gfs2: Move check_num_ptrs from metawalk to pass1
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (17 preceding siblings ...)
  2012-01-20 15:09 ` [Cluster-devel] [PATCH 18/66] fsck.gfs2: fsck.gfs2: Find and clear duplicate leaf blocks refs rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 20/66] fsck.gfs2: fsck.gfs2: Duplicate ref processing for leaf blocks rpeterso
                   ` (46 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch moves function check_num_ptrs from metawalk.c to pass1.c
and also its helper function fix_leaf_pointers.  This function checks
that the number of pointers in a leaf block is a factor of 2, and sane.
This should only happen once, when leaf blocks are initially checked.
Previously it was wasting a lot of time doing this check from every pass.

rhbz#675723
---
 gfs2/fsck/metawalk.c |  129 +++-------------------------------------------
 gfs2/fsck/metawalk.h |    3 +
 gfs2/fsck/pass1.c    |  140 ++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 148 insertions(+), 124 deletions(-)

diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index dd0b929..cf75164 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -464,123 +464,6 @@ static void warn_and_patch(struct gfs2_inode *ip, uint64_t *leaf_no,
 	*leaf_no = old_leaf;
 }
 
-/*
- * fix_leaf_pointers - fix a directory dinode that has a number of pointers
- *                     that is not a multiple of 2.
- * dip - the directory inode having the problem
- * lindex - the index of the leaf right after the problem (need to back up)
- * cur_numleafs - current (incorrect) number of instances of the leaf block
- * correct_numleafs - the correct number instances of the leaf block
- */
-static int fix_leaf_pointers(struct gfs2_inode *dip, int *lindex,
-			     int cur_numleafs, int correct_numleafs)
-{
-	int count;
-	char *ptrbuf;
-	int start_lindex = *lindex - cur_numleafs; /* start of bad ptrs */
-	int tot_num_ptrs = (1 << dip->i_di.di_depth) - start_lindex;
-	int bufsize = tot_num_ptrs * sizeof(uint64_t);
-	int off_by = cur_numleafs - correct_numleafs;
-
-	ptrbuf = malloc(bufsize);
-	if (!ptrbuf) {
-		log_err( _("Error: Cannot allocate memory to fix the leaf "
-			   "pointers.\n"));
-		return -1;
-	}
-	/* Read all the pointers, starting with the first bad one */
-	count = gfs2_readi(dip, ptrbuf, start_lindex * sizeof(uint64_t),
-			   bufsize);
-	if (count != bufsize) {
-		log_err( _("Error: bad read while fixing leaf pointers.\n"));
-		free(ptrbuf);
-		return -1;
-	}
-
-	bufsize -= off_by * sizeof(uint64_t); /* We need to write fewer */
-	/* Write the same pointers, but offset them so they fit within the
-	   smaller factor of 2. So if we have 12 pointers, write out only
-	   the last 8 of them.  If we have 7, write the last 4, etc.
-	   We need to write these starting at the current lindex and adjust
-	   lindex accordingly. */
-	count = gfs2_writei(dip, ptrbuf + (off_by * sizeof(uint64_t)),
-			    start_lindex * sizeof(uint64_t), bufsize);
-	if (count != bufsize) {
-		log_err( _("Error: bad read while fixing leaf pointers.\n"));
-		free(ptrbuf);
-		return -1;
-	}
-	/* Now zero out the hole left at the end */
-	memset(ptrbuf, 0, off_by * sizeof(uint64_t));
-	gfs2_writei(dip, ptrbuf, (start_lindex * sizeof(uint64_t)) +
-		    bufsize, off_by * sizeof(uint64_t));
-	free(ptrbuf);
-	*lindex -= off_by; /* adjust leaf index to account for the change */
-	return 0;
-}
-
-/* check_num_ptrs - check a previously processed leaf's pointer count */
-static int check_num_ptrs(struct gfs2_inode *ip, uint64_t old_leaf,
-			  int *ref_count, int *exp_count, int *lindex,
-			  struct gfs2_leaf *oldleaf)
-{
-	int factor = 0, divisor = *ref_count, multiple = 1, error = 0;
-	struct gfs2_buffer_head *lbh;
-
-	/* Check to see if the number of pointers we found is a power of 2.
-	   It needs to be and if it's not we need to fix it.*/
-	while (divisor > 1) {
-		factor++;
-		divisor /= 2;
-		multiple = multiple << 1;
-	}
-	if (*ref_count != multiple) {
-		log_err( _("Directory #%llu (0x%llx) has an "
-			   "invalid number of pointers to "
-			   "leaf #%llu (0x%llx)\n\tFound: %u, "
-			   "which is not a factor of 2.\n"),
-			 (unsigned long long)ip->i_di.di_num.no_addr,
-			 (unsigned long long)ip->i_di.di_num.no_addr,
-			 (unsigned long long)old_leaf,
-			 (unsigned long long)old_leaf, *ref_count);
-		if (!query( _("Attempt to fix it? (y/n) "))) {
-			log_err( _("Directory inode was not fixed.\n"));
-			return 1;
-		}
-		error = fix_leaf_pointers(ip, lindex, *ref_count, multiple);
-		if (error)
-			return error;
-		*ref_count = multiple;
-		log_err( _("Directory inode was fixed.\n"));
-	}
-	/* Check to see if the counted number of leaf pointers is what we
-	   expect. */
-	if (*ref_count != *exp_count) {
-		log_err( _("Directory #%llu (0x%llx) has an "
-			   "incorrect number of pointers to "
-			   "leaf #%llu (0x%llx)\n\tFound: "
-			   "%u,  Expected: %u\n"),
-			 (unsigned long long)ip->i_di.di_num.no_addr,
-			 (unsigned long long)ip->i_di.di_num.no_addr,
-			 (unsigned long long)old_leaf,
-			 (unsigned long long)old_leaf, *ref_count, *exp_count);
-		if (!query( _("Attempt to fix it? (y/n) "))) {
-			log_err( _("Directory leaf was not fixed.\n"));
-			return 1;
-		}
-		lbh = bread(ip->i_sbd, old_leaf);
-		gfs2_leaf_in(oldleaf, lbh);
-		log_err( _("Leaf depth was %d, changed to %d\n"),
-			 oldleaf->lf_depth, ip->i_di.di_depth - factor);
-		oldleaf->lf_depth = ip->i_di.di_depth - factor;
-		gfs2_leaf_out(oldleaf, lbh);
-		brelse(lbh);
-		*exp_count = *ref_count;
-		log_err( _("Directory leaf was fixed.\n"));
-	}
-	return 0;
-}
-
 /* Checks exhash directory entries */
 static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 {
@@ -639,10 +522,14 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 		}
 
 		do {
-			if (!valid_block(ip->i_sbd, old_leaf) == 0) {
-				error = check_num_ptrs(ip, old_leaf,
-						       &ref_count, &exp_count,
-						       &lindex, &oldleaf);
+			if (fsck_abort)
+				return 0;
+			if (pass->check_num_ptrs &&
+			    valid_block(ip->i_sbd, old_leaf)) {
+				error = pass->check_num_ptrs(ip, old_leaf,
+							     &ref_count,
+							     &lindex,
+							     &oldleaf);
 				if (error)
 					return error;
 			}
diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h
index d705726..7a8ae4c 100644
--- a/gfs2/fsck/metawalk.h
+++ b/gfs2/fsck/metawalk.h
@@ -89,6 +89,9 @@ struct metawalk_fxns {
 	int (*finish_eattr_indir) (struct gfs2_inode *ip, int leaf_pointers,
 				   int leaf_pointer_errors, void *private);
 	void (*big_file_msg) (struct gfs2_inode *ip, uint64_t blks_checked);
+	int (*check_num_ptrs) (struct gfs2_inode *ip, uint64_t leafno,
+			       int *ref_count, int *lindex,
+			       struct gfs2_leaf *leaf);
 };
 
 #endif /* _METAWALK_H */
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 271075c..26883d3 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -32,7 +32,7 @@ struct block_count {
 	uint64_t ea_count;
 };
 
-static int leaf(struct gfs2_inode *ip, uint64_t block, void *private);
+static int check_leaf(struct gfs2_inode *ip, uint64_t block, void *private);
 static int check_metalist(struct gfs2_inode *ip, uint64_t block,
 			  struct gfs2_buffer_head **bh, int h, void *private);
 static int undo_check_metalist(struct gfs2_inode *ip, uint64_t block,
@@ -57,6 +57,8 @@ static int check_extended_leaf_eattr(struct gfs2_inode *ip, uint64_t *data_ptr,
 				     struct gfs2_ea_header *ea_hdr,
 				     struct gfs2_ea_header *ea_hdr_prev,
 				     void *private);
+static int check_num_ptrs(struct gfs2_inode *ip, uint64_t leafno,
+			  int *ref_count, int *lindex, struct gfs2_leaf *leaf);
 static int finish_eattr_indir(struct gfs2_inode *ip, int leaf_pointers,
 			      int leaf_pointer_errors, void *private);
 static int invalidate_metadata(struct gfs2_inode *ip, uint64_t block,
@@ -77,7 +79,7 @@ static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip);
 
 struct metawalk_fxns pass1_fxns = {
 	.private = NULL,
-	.check_leaf = leaf,
+	.check_leaf = check_leaf,
 	.check_metalist = check_metalist,
 	.check_data = check_data,
 	.check_eattr_indir = check_eattr_indir,
@@ -87,6 +89,7 @@ struct metawalk_fxns pass1_fxns = {
 	.check_eattr_extentry = check_extended_leaf_eattr,
 	.finish_eattr_indir = finish_eattr_indir,
 	.big_file_msg = big_file_comfort,
+	.check_num_ptrs = check_num_ptrs,
 };
 
 struct metawalk_fxns undo_fxns = {
@@ -197,7 +200,138 @@ struct metawalk_fxns sysdir_fxns = {
 	.check_dentry = resuscitate_dentry,
 };
 
-static int leaf(struct gfs2_inode *ip, uint64_t block, void *private)
+/*
+ * fix_leaf_pointers - fix a directory dinode that has a number of pointers
+ *                     that is not a multiple of 2.
+ * dip - the directory inode having the problem
+ * lindex - the index of the leaf right after the problem (need to back up)
+ * cur_numleafs - current (incorrect) number of instances of the leaf block
+ * correct_numleafs - the correct number instances of the leaf block
+ */
+static int fix_leaf_pointers(struct gfs2_inode *dip, int *lindex,
+			     int cur_numleafs, int correct_numleafs)
+{
+	int count;
+	char *ptrbuf;
+	int start_lindex = *lindex - cur_numleafs; /* start of bad ptrs */
+	int tot_num_ptrs = (1 << dip->i_di.di_depth) - start_lindex;
+	int bufsize = tot_num_ptrs * sizeof(uint64_t);
+	int off_by = cur_numleafs - correct_numleafs;
+
+	ptrbuf = malloc(bufsize);
+	if (!ptrbuf) {
+		log_err( _("Error: Cannot allocate memory to fix the leaf "
+			   "pointers.\n"));
+		return -1;
+	}
+	/* Read all the pointers, starting with the first bad one */
+	count = gfs2_readi(dip, ptrbuf, start_lindex * sizeof(uint64_t),
+			   bufsize);
+	if (count != bufsize) {
+		log_err( _("Error: bad read while fixing leaf pointers.\n"));
+		free(ptrbuf);
+		return -1;
+	}
+
+	bufsize -= off_by * sizeof(uint64_t); /* We need to write fewer */
+	/* Write the same pointers, but offset them so they fit within the
+	   smaller factor of 2. So if we have 12 pointers, write out only
+	   the last 8 of them.  If we have 7, write the last 4, etc.
+	   We need to write these starting at the current lindex and adjust
+	   lindex accordingly. */
+	count = gfs2_writei(dip, ptrbuf + (off_by * sizeof(uint64_t)),
+			    start_lindex * sizeof(uint64_t), bufsize);
+	if (count != bufsize) {
+		log_err( _("Error: bad read while fixing leaf pointers.\n"));
+		free(ptrbuf);
+		return -1;
+	}
+	/* Now zero out the hole left at the end */
+	memset(ptrbuf, 0, off_by * sizeof(uint64_t));
+	gfs2_writei(dip, ptrbuf, (start_lindex * sizeof(uint64_t)) +
+		    bufsize, off_by * sizeof(uint64_t));
+	free(ptrbuf);
+	*lindex -= off_by; /* adjust leaf index to account for the change */
+	return 0;
+}
+
+/**
+ * check_num_ptrs - check a previously processed leaf's pointer count in the
+ *                  hash table.
+ *
+ * The number of pointers in a directory hash table that point to any given
+ * leaf block should always be a factor of two.  The difference between the
+ * leaf block's depth and the dinode's di_depth gives us the factor.
+ * This function makes sure the leaf follows the rules properly.
+ *
+ * ip - pointer to the in-core inode structure
+ * leafno - the leaf number we're operating on
+ * ref_count - the number of pointers to this leaf we actually counted.
+ * exp_count - the number of pointers to this leaf we expect based on
+ *             ip depth minus leaf depth.
+ * lindex - leaf index number
+ * leaf - the leaf structure for the leaf block to check
+ */
+static int check_num_ptrs(struct gfs2_inode *ip, uint64_t leafno,
+			  int *ref_count, int *lindex, struct gfs2_leaf *leaf)
+{
+	int factor = 0, divisor = *ref_count, multiple = 1, error = 0;
+	struct gfs2_buffer_head *lbh;
+	int exp_count;
+
+	/* Check to see if the number of pointers we found is a power of 2.
+	   It needs to be and if it's not we need to fix it.*/
+	while (divisor > 1) {
+		factor++;
+		divisor /= 2;
+		multiple = multiple << 1;
+	}
+	if (*ref_count != multiple) {
+		log_err( _("Directory #%llu (0x%llx) has an invalid number of "
+			   "pointers to leaf #%llu (0x%llx)\n\tFound: %u, "
+			   "which is not a factor of 2.\n"),
+			 (unsigned long long)ip->i_di.di_num.no_addr,
+			 (unsigned long long)ip->i_di.di_num.no_addr,
+			 (unsigned long long)leafno,
+			 (unsigned long long)leafno, *ref_count);
+		if (!query( _("Attempt to fix it? (y/n) "))) {
+			log_err( _("Directory inode was not fixed.\n"));
+			return 1;
+		}
+		error = fix_leaf_pointers(ip, lindex, *ref_count, multiple);
+		if (error)
+			return error;
+		*ref_count = multiple;
+		log_err( _("Directory inode was fixed.\n"));
+	}
+	/* Check to see if the counted number of leaf pointers is what we
+	   expect based on the leaf depth. */
+	exp_count = (1 << (ip->i_di.di_depth - leaf->lf_depth));
+	if (*ref_count != exp_count) {
+		log_err( _("Directory #%llu (0x%llx) has an incorrect number "
+			   "of pointers to leaf #%llu (0x%llx)\n\tFound: "
+			   "%u,  Expected: %u\n"),
+			 (unsigned long long)ip->i_di.di_num.no_addr,
+			 (unsigned long long)ip->i_di.di_num.no_addr,
+			 (unsigned long long)leafno,
+			 (unsigned long long)leafno, *ref_count, exp_count);
+		if (!query( _("Attempt to fix it? (y/n) "))) {
+			log_err( _("Directory leaf was not fixed.\n"));
+			return 1;
+		}
+		lbh = bread(ip->i_sbd, leafno);
+		gfs2_leaf_in(leaf, lbh);
+		log_err( _("Leaf depth was %d, changed to %d\n"),
+			 leaf->lf_depth, ip->i_di.di_depth - factor);
+		leaf->lf_depth = ip->i_di.di_depth - factor;
+		gfs2_leaf_out(leaf, lbh);
+		brelse(lbh);
+		log_err( _("Directory leaf was fixed.\n"));
+	}
+	return 0;
+}
+
+static int check_leaf(struct gfs2_inode *ip, uint64_t block, void *private)
 {
 	struct block_count *bc = (struct block_count *) private;
 
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 20/66] fsck.gfs2: fsck.gfs2: Duplicate ref processing for leaf blocks
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (18 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 19/66] fsck.gfs2: fsck.gfs2: Move check_num_ptrs from metawalk to pass1 rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 21/66] fsck.gfs2: fsck.gfs2: split check_leaf_blks to be more readable rpeterso
                   ` (45 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch adds checks for duplicate block references to the leaf block
processing.

rhbz#675723
---
 gfs2/fsck/pass1.c |   20 ++++++++++++++++++++
 1 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 26883d3..a1f4232 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -334,7 +334,27 @@ static int check_num_ptrs(struct gfs2_inode *ip, uint64_t leafno,
 static int check_leaf(struct gfs2_inode *ip, uint64_t block, void *private)
 {
 	struct block_count *bc = (struct block_count *) private;
+	uint8_t q;
 
+	/* Note if we've gotten this far, the block has already passed the
+	   check in metawalk: gfs2_check_meta(lbh, GFS2_METATYPE_LF).
+	   So we know it's a leaf block. */
+	q = block_type(block);
+	if (q != gfs2_block_free) {
+		log_err( _("Found duplicate block %llu (0x%llx) referenced "
+			   "as a directory leaf in dinode "
+			   "%llu (0x%llx) - was marked %d (%s)\n"),
+			 (unsigned long long)block,
+			 (unsigned long long)block,
+			 (unsigned long long)ip->i_di.di_num.no_addr,
+			 (unsigned long long)ip->i_di.di_num.no_addr, q,
+			 block_type_string(q));
+		add_duplicate_ref(ip, block, ref_as_meta, 0, INODE_VALID);
+		if (q == gfs2_leaf_blk) /* If the previous reference also saw
+					   this as a leaf, it was already
+					   checked, so don't check again. */
+			return -EEXIST;
+	}
 	fsck_blockmap_set(ip, block, _("directory leaf"), gfs2_leaf_blk);
 	bc->indir_count++;
 	return 0;
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 21/66] fsck.gfs2: fsck.gfs2: split check_leaf_blks to be more readable
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (19 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 20/66] fsck.gfs2: fsck.gfs2: Duplicate ref processing for leaf blocks rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 22/66] fsck.gfs2: Shorten output rpeterso
                   ` (44 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch splits function check_leaf_blks into two functions to make it
more understandable.  Before, it had way too many levels of indentation and
spanned multiple screens.  This makes it a lot more clear.

rhbz#675723
---
 gfs2/fsck/metawalk.c |  255 +++++++++++++++++++++++++++-----------------------
 1 files changed, 138 insertions(+), 117 deletions(-)

diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index cf75164..9252aec 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -436,10 +436,12 @@ static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
 /* so that they replace the bad ones.  We have to hack up the old    */
 /* leaf a bit, but it's better than deleting the whole directory,    */
 /* which is what used to happen before.                              */
-static void warn_and_patch(struct gfs2_inode *ip, uint64_t *leaf_no, 
-			   uint64_t *bad_leaf, uint64_t old_leaf,
-			   uint64_t first_ok_leaf, int pindex, const char *msg)
+static int warn_and_patch(struct gfs2_inode *ip, uint64_t *leaf_no,
+			  uint64_t *bad_leaf, uint64_t old_leaf,
+			  uint64_t first_ok_leaf, int pindex, const char *msg)
 {
+	int okay_to_fix = 0;
+
 	if (*bad_leaf != *leaf_no) {
 		log_err( _("Directory Inode %llu (0x%llx) points to leaf %llu"
 			" (0x%llx) %s.\n"),
@@ -449,7 +451,7 @@ static void warn_and_patch(struct gfs2_inode *ip, uint64_t *leaf_no,
 			(unsigned long long)*leaf_no, msg);
 	}
 	if (*leaf_no == *bad_leaf ||
-	    query( _("Attempt to patch around it? (y/n) "))) {
+	    (okay_to_fix = query( _("Attempt to patch around it? (y/n) ")))) {
 		if (!valid_block(ip->i_sbd, old_leaf) == 0)
 			gfs2_put_leaf_nr(ip, pindex, old_leaf);
 		else
@@ -462,6 +464,133 @@ static void warn_and_patch(struct gfs2_inode *ip, uint64_t *leaf_no,
 		log_err( _("Bad leaf left in place.\n"));
 	*bad_leaf = *leaf_no;
 	*leaf_no = old_leaf;
+	return okay_to_fix;
+}
+
+/**
+ * check_leaf - check a leaf block for errors
+ */
+static int check_leaf(struct gfs2_inode *ip, int lindex,
+		      struct metawalk_fxns *pass, int *ref_count,
+		      uint64_t *leaf_no, uint64_t old_leaf, uint64_t *bad_leaf,
+		      uint64_t first_ok_leaf, struct gfs2_leaf *leaf,
+		      struct gfs2_leaf *oldleaf)
+{
+	int error = 0, fix;
+	struct gfs2_buffer_head *lbh = NULL;
+	uint32_t count = 0;
+	struct gfs2_sbd *sdp = ip->i_sbd;
+	const char *msg;
+
+	*ref_count = 1;
+	/* Make sure the block number is in range. */
+	if (!valid_block(ip->i_sbd, *leaf_no)) {
+		log_err( _("Leaf block #%llu (0x%llx) is out of range for "
+			   "directory #%llu (0x%llx).\n"),
+			 (unsigned long long)*leaf_no,
+			 (unsigned long long)*leaf_no,
+			 (unsigned long long)ip->i_di.di_num.no_addr,
+			 (unsigned long long)ip->i_di.di_num.no_addr);
+		msg = _("that is out of range");
+		goto out_copy_old_leaf;
+	}
+
+	/* Try to read in the leaf block. */
+	lbh = bread(sdp, *leaf_no);
+	/* Make sure it's really a valid leaf block. */
+	if (gfs2_check_meta(lbh, GFS2_METATYPE_LF)) {
+		msg = _("that is not really a leaf");
+		goto out_copy_old_leaf;
+	}
+	if (pass->check_leaf) {
+		error = pass->check_leaf(ip, *leaf_no, pass->private);
+		if (error) {
+			log_info(_("Previous reference to leaf %lld (0x%llx) "
+				   "has already checked it; skipping.\n"),
+				 (unsigned long long)*leaf_no,
+				 (unsigned long long)*leaf_no);
+			brelse(lbh);
+			return error;
+		}
+	}
+	/* Early versions of GFS2 had an endianess bug in the kernel that set
+	   lf_dirent_format to cpu_to_be16(GFS2_FORMAT_DE).  This was fixed
+	   to use cpu_to_be32(), but we should check for incorrect values and
+	   replace them with the correct value. */
+
+	gfs2_leaf_in(leaf, lbh);
+	if (leaf->lf_dirent_format == (GFS2_FORMAT_DE << 16)) {
+		log_debug( _("incorrect lf_dirent_format@leaf #%" PRIu64
+			     "\n"), *leaf_no);
+		leaf->lf_dirent_format = GFS2_FORMAT_DE;
+		gfs2_leaf_out(leaf, lbh);
+		log_debug( _("Fixing lf_dirent_format.\n"));
+	}
+
+	/* Make sure it's really a leaf. */
+	if (leaf->lf_header.mh_type != GFS2_METATYPE_LF) {
+		log_err( _("Inode %llu (0x%llx) points to bad leaf %llu"
+			   " (0x%llx).\n"),
+			 (unsigned long long)ip->i_di.di_num.no_addr,
+			 (unsigned long long)ip->i_di.di_num.no_addr,
+			 (unsigned long long)*leaf_no,
+			 (unsigned long long)*leaf_no);
+		msg = _("that is not a leaf");
+		goto out_copy_old_leaf;
+	}
+
+	if (pass->check_dentry && S_ISDIR(ip->i_di.di_mode)) {
+		error = check_entries(ip, lbh, DIR_EXHASH, &count, pass);
+
+		if (skip_this_pass || fsck_abort)
+			goto out;
+
+		if (error < 0) {
+			stack;
+			goto out;
+		}
+
+		if (count != leaf->lf_entries) {
+			/* release and re-read the leaf in case check_entries
+			   changed it. */
+			brelse(lbh);
+			lbh = bread(sdp, *leaf_no);
+			gfs2_leaf_in(leaf, lbh);
+
+			log_err( _("Leaf %llu (0x%llx) entry count in "
+				   "directory %llu (0x%llx) does not match "
+				   "number of entries found - is %u, found %u\n"),
+				 (unsigned long long)*leaf_no,
+				 (unsigned long long)*leaf_no,
+				 (unsigned long long)ip->i_di.di_num.no_addr,
+				 (unsigned long long)ip->i_di.di_num.no_addr,
+				 leaf->lf_entries, count);
+			if (query( _("Update leaf entry count? (y/n) "))) {
+				leaf->lf_entries = count;
+				gfs2_leaf_out(leaf, lbh);
+				log_warn( _("Leaf entry count updated\n"));
+			} else
+				log_err( _("Leaf entry count left in "
+					   "inconsistant state\n"));
+		}
+	}
+out:
+	brelse(lbh);
+	return 0;
+
+out_copy_old_leaf:
+	/* The leaf we read in is bad.  So we'll copy the old leaf into the
+	 * new one.  However, that will make us shift our ref count. */
+	fix = warn_and_patch(ip, leaf_no, bad_leaf, old_leaf,
+			     first_ok_leaf, lindex, msg);
+	(*ref_count)++;
+	memcpy(leaf, oldleaf, sizeof(struct gfs2_leaf));
+	if (lbh) {
+		if (fix)
+			bmodified(lbh);
+		brelse(lbh);
+	}
+	return 1;
 }
 
 /* Checks exhash directory entries */
@@ -474,8 +603,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 	struct gfs2_buffer_head *lbh;
 	int lindex;
 	struct gfs2_sbd *sdp = ip->i_sbd;
-	uint32_t count;
-	int ref_count = 0, exp_count = 0;
+	int ref_count = 0;
 
 	/* Find the first valid leaf pointer in range and use it as our "old"
 	   leaf. That way, bad blocks at the beginning will be overwritten
@@ -533,119 +661,12 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 				if (error)
 					return error;
 			}
-			ref_count = 1;
-			count = 0;
-			if (fsck_abort)
-				break;
-			/* Make sure the block number is in range. */
-			if (!valid_block(ip->i_sbd, leaf_no)){
-				log_err( _("Leaf block #%llu (0x%llx) is out "
-					"of range for directory #%llu (0x%llx"
-					").\n"), (unsigned long long)leaf_no,
-					(unsigned long long)leaf_no,
-					(unsigned long long)
-					ip->i_di.di_num.no_addr,
-					(unsigned long long)
-					ip->i_di.di_num.no_addr);
-				warn_and_patch(ip, &leaf_no, &bad_leaf,
-					       old_leaf, first_ok_leaf, lindex,
-					       _("that is out of range"));
-				memcpy(&leaf, &oldleaf, sizeof(oldleaf));
-				break;
-			}
-
-			/* Try to read in the leaf block. */
-			lbh = bread(sdp, leaf_no);
-			/* Make sure it's really a valid leaf block. */
-			if (gfs2_check_meta(lbh, GFS2_METATYPE_LF)) {
-				warn_and_patch(ip, &leaf_no, &bad_leaf,
-					       old_leaf, first_ok_leaf, lindex,
-					       _("that is not really a leaf"));
-				memcpy(&leaf, &oldleaf, sizeof(oldleaf));
-				bmodified(lbh);
-				brelse(lbh);
-				break;
-			}
-			gfs2_leaf_in(&leaf, lbh);
-			if (pass->check_leaf)
-				error = pass->check_leaf(ip, leaf_no,
-							 pass->private);
-
-			/*
-			 * Early versions of GFS2 had an endianess bug in the
-			 * kernel that set lf_dirent_format to
-			 * cpu_to_be16(GFS2_FORMAT_DE).  This was fixed to use
-			 * cpu_to_be32(), but we should check for incorrect 
-			 * values and replace them with the correct value. */
-
-			if (leaf.lf_dirent_format == (GFS2_FORMAT_DE << 16)) {
-				log_debug( _("incorrect lf_dirent_format@leaf #%" PRIu64 "\n"), leaf_no);
-				leaf.lf_dirent_format = GFS2_FORMAT_DE;
-				gfs2_leaf_out(&leaf, lbh);
-				log_debug( _("Fixing lf_dirent_format.\n"));
-			}
-
-			/* Make sure it's really a leaf. */
-			if (leaf.lf_header.mh_type != GFS2_METATYPE_LF) {
-				log_err( _("Inode %llu (0x%llx"
-					") points to bad leaf %llu"
-					" (0x%llx).\n"),
-					(unsigned long long)
-					ip->i_di.di_num.no_addr,
-					(unsigned long long)
-					ip->i_di.di_num.no_addr,
-					(unsigned long long)leaf_no,
-					(unsigned long long)leaf_no);
-				brelse(lbh);
-				break;
-			}
-			exp_count = (1 << (ip->i_di.di_depth - leaf.lf_depth));
-			/*log_debug( _("expected count %u - di_depth %u,
-			  leaf depth %u\n"),
-			  exp_count, ip->i_di.di_depth, leaf.lf_depth);*/
-
-			if (pass->check_dentry && S_ISDIR(ip->i_di.di_mode)) {
-				error = check_entries(ip, lbh, DIR_EXHASH,
-						      &count, pass);
-
-				if (skip_this_pass || fsck_abort)
-					return 0;
-
-				if (error < 0) {
-					stack;
-					brelse(lbh);
-					return -1;
-				}
-
-				if (count != leaf.lf_entries) {
-					brelse(lbh);
-					lbh = bread(sdp, leaf_no);
-					gfs2_leaf_in(&leaf, lbh);
-
-					log_err( _("Leaf %llu (0x%llx) entry "
-						"count in directory %llu"
-						" (0x%llx) doesn't match "
-						"number of entries found "
-						"- is %u, found %u\n"),
-						(unsigned long long)leaf_no,
-						(unsigned long long)leaf_no,
-						(unsigned long long)
-						ip->i_di.di_num.no_addr,
-						(unsigned long long)
-						ip->i_di.di_num.no_addr,
-						leaf.lf_entries, count);
-					if (query( _("Update leaf entry count? (y/n) "))) {
-						leaf.lf_entries = count;
-						gfs2_leaf_out(&leaf, lbh);
-						log_warn( _("Leaf entry count updated\n"));
-					} else
-						log_err( _("Leaf entry count left in inconsistant state\n"));
-				}
-			}
-			brelse(lbh);
+			error = check_leaf(ip, lindex, pass, &ref_count,
+					   &leaf_no, old_leaf, &bad_leaf,
+					   first_ok_leaf, &leaf, &oldleaf);
 			old_leaf = leaf_no;
 			memcpy(&oldleaf, &leaf, sizeof(oldleaf));
-			if (!leaf.lf_next)
+			if (!leaf.lf_next || error)
 				break;
 			leaf_no = leaf.lf_next;
 			log_debug( _("Leaf chain 0x%llx detected.\n"),
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 22/66] fsck.gfs2: Shorten output
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (20 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 21/66] fsck.gfs2: fsck.gfs2: split check_leaf_blks to be more readable rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 23/66] fsck.gfs2: Make output messages more sensible rpeterso
                   ` (43 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch shortens some of the output of fsck.gfs2, thereby making
the output files smaller and more manageable.

rhbz#675723
---
 gfs2/fsck/lost_n_found.c |    6 +++---
 gfs2/fsck/metawalk.c     |    7 ++++---
 gfs2/fsck/pass5.c        |   13 +++++++------
 3 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index 7886625..0de4f8e 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -66,8 +66,8 @@ static void add_dotdot(struct gfs2_inode *ip)
 				  (unsigned long long)ip->i_di.di_num.no_addr,
 				  (unsigned long long)di->dotdot_parent);
 		else
-			log_debug(_("Couldn't find a valid \"..\" entry "
-				    "for orphan directory %lld (0x%llx)\n"),
+			log_debug(_("Couldn't find directory %lld (0x%llx) "
+				    "in directory tree.\n"),
 				  (unsigned long long)ip->i_di.di_num.no_addr,
 				  (unsigned long long)ip->i_di.di_num.no_addr);
 	}
@@ -206,7 +206,7 @@ int add_inode_to_lf(struct gfs2_inode *ip){
 		incr_link_count(lf_dip->i_di.di_num.no_addr,
 				ip->i_di.di_mode, _("to lost+found"));
 
-	log_notice( _("Added inode #%llu (0x%llx) to lost+found dir\n"),
+	log_notice( _("Added inode #%llu (0x%llx) to lost+found\n"),
 		    (unsigned long long)ip->i_di.di_num.no_addr,
 		    (unsigned long long)ip->i_di.di_num.no_addr);
 	gfs2_dinode_out(&lf_dip->i_di, lf_dip->i_bh);
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 9252aec..af27432 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -45,12 +45,13 @@ int check_n_fix_bitmap(struct gfs2_sbd *sdp, uint64_t blk,
 		const char *allocdesc[] = {"free space", "data", "unlinked",
 					   "inode", "reserved"};
 
-		log_err( _("Block %llu (0x%llx) seems to be %s, but is "
-			   "marked as %s in the bitmap.\n"),
+		/* Keep these messages as short as possible, or the output
+		   gets to be huge and unmanageable. */
+		log_err( _("Block %llu (0x%llx) was '%s', should be %s.\n"),
 			 (unsigned long long)blk, (unsigned long long)blk,
 			 allocdesc[new_bitmap_state],
 			 allocdesc[old_bitmap_state]);
-		if (query( _("Okay to fix the bitmap? (y/n)"))) {
+		if (query( _("Fix the bitmap? (y/n)"))) {
 			/* If the new bitmap state is free (and therefore the
 			   old state was not) we have to add to the free
 			   space in the rgrp. If the old bitmap state was
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index 1811e5a..028515b 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -79,8 +79,8 @@ static int check_block_status(struct gfs2_sbd *sdp, char *buffer, unsigned int b
 		   So we ignore it. */
 		if (rg_status == GFS2_BLKST_UNLINKED &&
 		    block_status == GFS2_BLKST_FREE) {
-			log_err( _("Unlinked inode block found at "
-				   "block %llu (0x%llx).\n"),
+			log_err( _("Unlinked inode found at block %llu "
+				   "(0x%llx).\n"),
 				 (unsigned long long)block,
 				 (unsigned long long)block);
 			if (query(_("Do you want to fix the bitmap? (y/n) "))) {
@@ -109,16 +109,17 @@ static int check_block_status(struct gfs2_sbd *sdp, char *buffer, unsigned int b
 			log_err( _("Ondisk status is %u (%s) but FSCK thinks it should be "),
 					rg_status, blockstatus[rg_status]);
 			log_err("%u (%s)\n", block_status, blockstatus[block_status]);
-			log_err( _("Metadata type is %u (%s)\n"), q,
-					block_type_string(q));
+			if (q) /* Don't print redundant "free" */
+				log_err( _("Metadata type is %u (%s)\n"), q,
+					 block_type_string(q));
 
 			if (query(_("Fix bitmap for block %llu (0x%llx) ? (y/n) "),
 				 (unsigned long long)block,
 				 (unsigned long long)block)) {
 				if (gfs2_set_bitmap(sdp, block, block_status))
-					log_err( _("Failed.\n"));
+					log_err( _("Repair failed.\n"));
 				else
-					log_err( _("Succeeded.\n"));
+					log_err( _("Fixed.\n"));
 			} else
 				log_err( _("Bitmap at block %"PRIu64" (0x%" PRIx64
 						") left inconsistent\n"), block, block);
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 23/66] fsck.gfs2: Make output messages more sensible
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (21 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 22/66] fsck.gfs2: Shorten output rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 24/66] fsck.gfs pass2: Refactor function set_dotdot_dir rpeterso
                   ` (42 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch changes several fsck output messages so that they make more
sense.  Digging through very big and complex fsck.gfs2 output, I found
myself lost in many occasions.  This patch makes it a lot easier to see
what decisions are made by fsck.gfs2 and why.

rhbz#675723
---
 gfs2/fsck/initialize.c |   21 +++++++++++++++------
 gfs2/fsck/metawalk.c   |    2 +-
 gfs2/fsck/pass1.c      |    4 ++++
 gfs2/fsck/pass1b.c     |    5 +++--
 gfs2/fsck/pass2.c      |   18 ++++++++++++++----
 gfs2/fsck/pass5.c      |   21 +++++++++++++--------
 gfs2/fsck/util.c       |    3 ++-
 7 files changed, 52 insertions(+), 22 deletions(-)

diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 08da24f..d7586de 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -460,14 +460,14 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
 	uint64_t addl_mem_needed;
 	const char *level_desc[] = {
 		_("Checking if all rgrp and rindex values are good"),
-		_("Checking if rindex values are ascending and evenly spaced"),
+		_("Checking if rindex values may be easily repaired"),
 		_("Calculating where the rgrps should be if evenly spaced"),
 		_("Trying to rebuild rindex assuming evenly spaced rgrps"),
 		_("Trying to rebuild rindex assuming unevenly spaced rgrps"),
 	};
 	const char *fail_desc[] = {
 		_("Some damage was found; we need to take remedial measures"),
-		_("rindex is unevenly spaced: converted from gfs1 or corrupt"),
+		_("rindex is unevenly spaced: either gfs1-style or corrupt"),
 		_("rindex calculations don't match: uneven rgrp boundaries"),
 		_("Too many rgrp misses: rgrps must be unevenly spaced"),
 		_("Too much damage found: we cannot rebuild this rindex"),
@@ -513,16 +513,25 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
 	 *******************************************************************/
 	log_warn( _("Validating Resource Group index.\n"));
 	for (trust_lvl = blind_faith; trust_lvl <= indignation; trust_lvl++) {
+		int ret;
+
 		log_warn( _("Level %d rgrp check: %s.\n"), trust_lvl + 1,
 			  level_desc[trust_lvl]);
 		if ((rg_repair(sdp, trust_lvl, &rgcount, &sane) == 0) &&
-		    (ri_update(sdp, 0, &rgcount, &sane) == 0)) {
+		    ((ret = ri_update(sdp, 0, &rgcount, &sane)) == 0)) {
 			log_warn( _("(level %d passed)\n"), trust_lvl + 1);
 			break;
+		} else {
+			if (ret < 0)
+				log_err( _("(level %d failed: %s)\n"),
+					 trust_lvl + 1, fail_desc[trust_lvl]);
+			else
+				log_err( _("(level %d failed@block %lld "
+					   "(0x%llx): %s)\n"), trust_lvl + 1,
+					 (unsigned long long)ret,
+					 (unsigned long long)ret,
+					 fail_desc[trust_lvl]);
 		}
-		else
-			log_err( _("(level %d failed: %s)\n"), trust_lvl + 1,
-				 fail_desc[trust_lvl]);
 		if (fsck_abort)
 			break;
 	}
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index af27432..92973ae 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -336,7 +336,7 @@ static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
 		    de.de_name_len ||
 		    (de.de_inum.no_formal_ino && !de.de_name_len && !first)) {
 			log_err( _("Directory block %llu (0x%llx"
-				"), entry %d of directory %llu"
+				"), entry %d of directory %llu "
 				"(0x%llx) is corrupt.\n"),
 				(unsigned long long)bh->b_blocknr,
 				(unsigned long long)bh->b_blocknr,
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index a1f4232..7077272 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -1213,6 +1213,10 @@ static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip)
 		   words, we would introduce file system corruption. So we
 		   need to keep track of the fact that it's invalid and
 		   skip parts that we can't be sure of based on dinode type. */
+		log_debug("Invalid mode dinode found at block %lld (0x%llx): "
+			  "Invalidating all its metadata.\n",
+			  (unsigned long long)ip->i_di.di_num.no_addr,
+			  (unsigned long long)ip->i_di.di_num.no_addr);
 		check_metatree(ip, &invalidate_fxns);
 		if (fsck_blockmap_set(ip, block, _("invalid mode"),
 				      gfs2_inode_invalid))
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index 65e6de9..259eb7a 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -426,7 +426,7 @@ static int clear_a_reference(struct gfs2_sbd *sdp, struct duptree *b,
 			log_warn( _("The bad inode was not cleared...\n"));
 			continue;
 		}
-		log_warn( _("Clearing inode %lld (0x%llx)....\n"),
+		log_warn( _("Clearing inode %lld (0x%llx)...\n"),
 			  (unsigned long long)id->block_no,
 			  (unsigned long long)id->block_no);
 		clear_dup_fxns.private = (void *) dh;
@@ -597,7 +597,8 @@ static int handle_dup_blk(struct gfs2_sbd *sdp, struct duptree *b)
 					  gfs2_meta_eattr);
 		fsck_inode_put(&ip); /* out, brelse, free */
 	} else {
-		log_debug( _("All duplicate references were resolved.\n"));
+		/* They may have answered no and not fixed all references. */
+		log_debug( _("All duplicate references were processed.\n"));
 	}
 	return 0;
 }
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index abb77c3..0424241 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -258,7 +258,10 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 		/* This entry's inode has bad blocks in it */
 
 		/* Handle bad blocks */
-		log_err( _("Found a bad directory entry: %s\n"), tmp_name);
+		log_err( _("Found directory entry '%s' pointing to invalid "
+			   "block %lld (0x%llx)\n"), tmp_name,
+			 (unsigned long long)entryblock,
+			 (unsigned long long)entryblock);
 
 		if (!query( _("Delete inode containing bad blocks? (y/n)"))) {
 			log_warn( _("Entry to inode containing bad blocks remains\n"));
@@ -275,6 +278,9 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 			fsck_inode_put(&entry_ip);
 		fsck_blockmap_set(ip, entryblock,
 				  _("bad directory entry"), gfs2_block_free);
+		log_err( _("Inode %lld (0x%llx) was deleted.\n"),
+			 (unsigned long long)entryblock,
+			 (unsigned long long)entryblock);
 		goto nuke_dentry;
 	}
 	if (q < gfs2_inode_dir || q > gfs2_inode_sock) {
@@ -350,7 +356,9 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 	}
 
 	if (!strcmp(".", tmp_name)) {
-		log_debug( _("Found . dentry\n"));
+		log_debug( _("Found . dentry in directory %lld (0x%llx)\n"),
+			     (unsigned long long)ip->i_di.di_num.no_addr,
+			     (unsigned long long)ip->i_di.di_num.no_addr);
 
 		if (ds->dotdir) {
 			log_err( _("Already found '.' entry in directory %llu"
@@ -408,9 +416,11 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 		goto dentry_is_valid;
 	}
 	if (!strcmp("..", tmp_name)) {
-		log_debug( _("Found .. dentry\n"));
+		log_debug( _("Found '..' dentry in directory %lld (0x%llx)\n"),
+			     (unsigned long long)ip->i_di.di_num.no_addr,
+			     (unsigned long long)ip->i_di.di_num.no_addr);
 		if (ds->dotdotdir) {
-			log_err( _("Already found '..' entry in directory %llu"
+			log_err( _("Already had a '..' entry in directory %llu"
 				"(0x%llx)\n"),
 				(unsigned long long)ip->i_di.di_num.no_addr,
 				(unsigned long long)ip->i_di.di_num.no_addr);
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index 028515b..b71b2b6 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -83,7 +83,8 @@ static int check_block_status(struct gfs2_sbd *sdp, char *buffer, unsigned int b
 				   "(0x%llx).\n"),
 				 (unsigned long long)block,
 				 (unsigned long long)block);
-			if (query(_("Do you want to fix the bitmap? (y/n) "))) {
+			if (query(_("Do you want to reclaim the block? "
+				   "(y/n) "))) {
 				if (gfs2_set_bitmap(sdp, block, block_status))
 					log_err(_("Unlinked block %llu "
 						  "(0x%llx) bitmap not fixed."
@@ -104,11 +105,12 @@ static int check_block_status(struct gfs2_sbd *sdp, char *buffer, unsigned int b
 			const char *blockstatus[] = {"Free", "Data",
 						     "Unlinked", "inode"};
 
-			log_err( _("Ondisk and fsck bitmaps differ at"
-					" block %"PRIu64" (0x%" PRIx64 ") \n"), block, block);
-			log_err( _("Ondisk status is %u (%s) but FSCK thinks it should be "),
-					rg_status, blockstatus[rg_status]);
-			log_err("%u (%s)\n", block_status, blockstatus[block_status]);
+			log_err( _("Block %llu (0x%llx) bitmap says %u (%s) "
+				   "but FSCK saw %u (%s)\n"),
+				 (unsigned long long)block,
+				 (unsigned long long)block, rg_status,
+				 blockstatus[rg_status], block_status,
+				 blockstatus[block_status]);
 			if (q) /* Don't print redundant "free" */
 				log_err( _("Metadata type is %u (%s)\n"), q,
 					 block_type_string(q));
@@ -164,8 +166,11 @@ static void update_rgrp(struct gfs2_sbd *sdp, struct rgrp_list *rgp,
 		update = 1;
 	}
 	if (rgp->rg.rg_dinodes != count[1]) {
-		log_err( _("Inode count inconsistent: is %u should be %u\n"),
-				rgp->rg.rg_dinodes, count[1]);
+		log_err( _("RG #%llu (0x%llx) Inode count inconsistent: is "
+			   "%u should be %u\n"),
+			 (unsigned long long)rgp->ri.ri_addr,
+			 (unsigned long long)rgp->ri.ri_addr,
+			 rgp->rg.rg_dinodes, count[1]);
 		rgp->rg.rg_dinodes = count[1];
 		update = 1;
 	}
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index b71fc98..9930624 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -286,7 +286,8 @@ int add_duplicate_ref(struct gfs2_inode *ip, uint64_t block,
 	if (first)
 		log_info( _("This is the original reference.\n"));
 	else
-		log_info( _("This brings the total to: %d\n"), dt->refs);
+		log_info( _("This brings the total to: %d duplicate "
+			    "references\n"), dt->refs);
 	return 0;
 }
 
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 24/66] fsck.gfs pass2: Refactor function set_dotdot_dir
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (22 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 23/66] fsck.gfs2: Make output messages more sensible rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 25/66] fsck.gfs2 pass2: Delete extended attributes with inode rpeterso
                   ` (41 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch refactors function set_dotdot_dir to make it more readable.

rhbz#675723
---
 gfs2/fsck/pass2.c |   46 ++++++++++++++++++++++++++--------------------
 1 files changed, 26 insertions(+), 20 deletions(-)

diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 0424241..b31d293 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -57,34 +57,40 @@ static int set_parent_dir(struct gfs2_sbd *sdp, uint64_t childblock,
 
 /* Set's the child's '..' directory inode number in dir_info structure */
 static int set_dotdot_dir(struct gfs2_sbd *sdp, uint64_t childblock,
-				   uint64_t parentblock)
+			  uint64_t parentblock)
 {
 	struct dir_info *di;
 
 	di = dirtree_find(childblock);
-	if (di) {
-		if (di->dinode == childblock) {
-			/* Special case for root inode because we set
-			 * it earlier */
-			if (di->dotdot_parent && sdp->md.rooti->i_di.di_num.no_addr
-			   != di->dinode) {
-				/* This should never happen */
-				log_crit( _("Dotdot parent already set for"
-						 " block %"PRIu64" (0x%" PRIx64 ") -> %" PRIu64
-						 " (0x%" PRIx64 ")\n"), childblock, childblock,
-						 di->dotdot_parent, di->dotdot_parent);
-				return -1;
-			}
-			di->dotdot_parent = parentblock;
-		}
-	} else {
+	if (!di) {
 		log_err( _("Unable to find block %"PRIu64" (0x%" PRIx64
-				") in dir_info list\n"), childblock, childblock);
+			   ") in dir_info tree\n"), childblock, childblock);
 		return -1;
 	}
-
+	if (di->dinode != childblock) {
+		log_debug("'..' doesn't point to what we found: childblock "
+			  "0x%llx != dinode 0x%llx\n",
+			  (unsigned long long)childblock,
+			  (unsigned long long)di->dinode);
+		return -1;
+	}
+	/* Special case for root inode because we set it earlier */
+	if (di->dotdot_parent &&
+	    sdp->md.rooti->i_di.di_num.no_addr != di->dinode) {
+		/* This should never happen */
+		log_crit( _("Dotdot parent already set for block %llu (0x%llx)"
+			    "-> %llu (0x%llx)\n"),
+			  (unsigned long long)childblock,
+			  (unsigned long long)childblock,
+			  (unsigned long long)di->dotdot_parent,
+			  (unsigned long long)di->dotdot_parent);
+		return -1;
+	}
+	log_debug("Setting '..' for directory block 0x%llx to parent 0x%llx\n",
+		  (unsigned long long)childblock,
+		  (unsigned long long)parentblock);
+	di->dotdot_parent = parentblock;
 	return 0;
-
 }
 
 static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block,
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 25/66] fsck.gfs2 pass2: Delete extended attributes with inode
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (23 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 24/66] fsck.gfs pass2: Refactor function set_dotdot_dir rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 26/66] fsck.gfs2 pass2: Don't delete invalid inode metadata rpeterso
                   ` (40 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

When pass2 decided to delete a bad/corrupt dinode from disk, it was
not deleting extended attributes associated with that dinode.  Oops.
This patch corrects the situation and allows it to delete them.

rhbz#675723
---
 gfs2/fsck/pass2.c |   55 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 55 insertions(+), 0 deletions(-)

diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index b31d293..bcd9355 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -158,6 +158,59 @@ static int check_file_type(uint8_t de_type, uint8_t blk_type)
 	return 0;
 }
 
+static int delete_eattr_entry (struct gfs2_inode *ip,
+			       struct gfs2_buffer_head *leaf_bh,
+			       struct gfs2_ea_header *ea_hdr,
+			       struct gfs2_ea_header *ea_hdr_prev,
+			       void *private)
+{
+	struct gfs2_sbd *sdp = ip->i_sbd;
+	char ea_name[256];
+
+	if (!ea_hdr->ea_name_len){
+		/* Skip this entry for now */
+		return 1;
+	}
+
+	memset(ea_name, 0, sizeof(ea_name));
+	strncpy(ea_name, (char *)ea_hdr + sizeof(struct gfs2_ea_header),
+		ea_hdr->ea_name_len);
+
+	if (!GFS2_EATYPE_VALID(ea_hdr->ea_type) &&
+	   ((ea_hdr_prev) || (!ea_hdr_prev && ea_hdr->ea_type))){
+		/* Skip invalid entry */
+		return 1;
+	}
+
+	if (ea_hdr->ea_num_ptrs){
+		uint32_t avail_size;
+		int max_ptrs;
+
+		avail_size = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header);
+		max_ptrs = (be32_to_cpu(ea_hdr->ea_data_len) + avail_size - 1) /
+			avail_size;
+
+		if (max_ptrs > ea_hdr->ea_num_ptrs)
+			return 1;
+		else {
+			log_debug( _("  Pointers Required: %d\n  Pointers Reported: %d\n"),
+					  max_ptrs, ea_hdr->ea_num_ptrs);
+		}
+	}
+	return 0;
+}
+
+static int delete_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr,
+				 struct gfs2_buffer_head *leaf_bh,
+				 struct gfs2_ea_header *ea_hdr,
+				 struct gfs2_ea_header *ea_hdr_prev,
+				 void *private)
+{
+        uint64_t block = be64_to_cpu(*ea_data_ptr);
+
+        return delete_metadata(ip, block, NULL, 0, private);
+}
+
 struct metawalk_fxns pass2_fxns_delete = {
 	.private = NULL,
 	.check_metalist = delete_metadata,
@@ -165,6 +218,8 @@ struct metawalk_fxns pass2_fxns_delete = {
 	.check_leaf = delete_leaf,
 	.check_eattr_indir = delete_eattr_indir,
 	.check_eattr_leaf = delete_eattr_leaf,
+	.check_eattr_entry = delete_eattr_entry,
+	.check_eattr_extentry = delete_eattr_extentry,
 };
 
 /* FIXME: should maybe refactor this a bit - but need to deal with
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 26/66] fsck.gfs2 pass2: Don't delete invalid inode metadata
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (24 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 25/66] fsck.gfs2 pass2: Delete extended attributes with inode rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 27/66] fsck.gfs2 pass3: Refactor mark_and_return_parent rpeterso
                   ` (39 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

In pass2, all metadata was deleted for inodes that were marked either
"bad" or "invalid" but that is wrong, and here is why:
Blocks marked "invalid" were invalidated due to duplicate block references.
Pass1b should have already taken care of deleting their metadata, so in pass2
we only need to delete the directory entries pointing to them.  We delete the
metadata in pass1b because we need to eliminate the inode referencing the
duplicate-referenced block from the list of candidates to keep.  So we have a
delete-as-we-go policy.  Blocks marked "bad" need to have their entire
metadata tree deleted.

rhbz#675723
---
 gfs2/fsck/pass2.c |   30 ++++++++++++++++++++++--------
 1 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index bcd9355..5fe5454 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -315,6 +315,18 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 
 	q = block_type(entryblock);
 	/* Get the status of the directory inode */
+	/**
+	 * 1. Blocks marked "invalid" were invalidated due to duplicate
+	 * block references.  Pass1b should have already taken care of deleting
+	 * their metadata, so here we only need to delete the directory entries
+	 * pointing to them.  We delete the metadata in pass1b because we need
+	 * to eliminate the inode referencing the duplicate-referenced block
+	 * from the list of candidates to keep.  So we have a delete-as-we-go
+	 * policy.
+	 *
+	 * 2. Blocks marked "bad" need to have their entire
+	 * metadata tree deleted.
+	*/
 	if (q == gfs2_inode_invalid || q == gfs2_bad_block) {
 		/* This entry's inode has bad blocks in it */
 
@@ -329,14 +341,16 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 			goto dentry_is_valid;
 		}
 
-		if (ip->i_di.di_num.no_addr == entryblock)
-			entry_ip = ip;
-		else
-			entry_ip = fsck_load_inode(sdp, entryblock);
-		check_inode_eattr(entry_ip, &pass2_fxns_delete);
-		check_metatree(entry_ip, &pass2_fxns_delete);
-		if (entry_ip != ip)
-			fsck_inode_put(&entry_ip);
+		if (q == gfs2_bad_block) {
+			if (ip->i_di.di_num.no_addr == entryblock)
+				entry_ip = ip;
+			else
+				entry_ip = fsck_load_inode(sdp, entryblock);
+			check_inode_eattr(entry_ip, &pass2_fxns_delete);
+			check_metatree(entry_ip, &pass2_fxns_delete);
+			if (entry_ip != ip)
+				fsck_inode_put(&entry_ip);
+		}
 		fsck_blockmap_set(ip, entryblock,
 				  _("bad directory entry"), gfs2_block_free);
 		log_err( _("Inode %lld (0x%llx) was deleted.\n"),
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 27/66] fsck.gfs2 pass3: Refactor mark_and_return_parent
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (25 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 26/66] fsck.gfs2 pass2: Don't delete invalid inode metadata rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 28/66] fsck.gfs2: misc cosmetic changes rpeterso
                   ` (38 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch refactors pass3 function "mark_and_return_parent".  Before
it was so complex and indented you could hardly interpret it.  Now you
can actually follow the logic.

rhbz#675723
---
 gfs2/fsck/pass3.c |  162 ++++++++++++++++++++++++++---------------------------
 1 files changed, 79 insertions(+), 83 deletions(-)

diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c
index 580c662..b904814 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -73,102 +73,98 @@ static struct dir_info *mark_and_return_parent(struct gfs2_sbd *sdp,
 {
 	struct dir_info *pdi;
 	uint8_t q_dotdot, q_treewalk;
+	int error = 0;
 
 	di->checked = 1;
 
 	if (!di->treewalk_parent)
 		return NULL;
 
-	if (di->dotdot_parent != di->treewalk_parent) {
-		log_warn( _("Directory '..' and treewalk connections disagree for inode %llu"
-				 " (0x%llx)\n"), (unsigned long long)di->dinode,
-			(unsigned long long)di->dinode);
-		log_notice( _("'..' has %llu (0x%llx), treewalk has %llu"
-			      " (0x%llx)\n"),
-			   (unsigned long long)di->dotdot_parent,
-			   (unsigned long long)di->dotdot_parent,
-			   (unsigned long long)di->treewalk_parent,
-			   (unsigned long long)di->treewalk_parent);
+	if (di->dotdot_parent == di->treewalk_parent) {
 		q_dotdot = block_type(di->dotdot_parent);
-		q_treewalk = block_type(di->treewalk_parent);
-		/* if the dotdot entry isn't a directory, but the
-		 * treewalk is, treewalk is correct - if the treewalk
-		 * entry isn't a directory, but the dotdot is, dotdot
-		 * is correct - if both are directories, which do we
-		 * choose? if neither are directories, we have a
-		 * problem - need to move this directory into lost+found
-		 */
 		if (q_dotdot != gfs2_inode_dir) {
-			if (q_treewalk != gfs2_inode_dir) {
-				log_err( _("Orphaned directory, move to lost+found\n"));
-				return NULL;
-			}
-			else {
-				log_warn( _("Treewalk parent is correct,"
-					    " fixing dotdot -> %llu (0x%llx)\n"),
-					 (unsigned long long)di->treewalk_parent,
-					 (unsigned long long)di->treewalk_parent);
-				attach_dotdot_to(sdp, di->treewalk_parent,
-						 di->dotdot_parent, di->dinode);
-				di->dotdot_parent = di->treewalk_parent;
-			}
-		} else {
-			if (q_treewalk != gfs2_inode_dir) {
-				int error = 0;
-				log_warn( _(".. parent is valid, but treewalk"
-						 "is bad - reattaching to lost+found"));
-
-				/* FIXME: add a dinode for this entry instead? */
-
-				if (query( _("Remove directory entry for bad"
-					    " inode %llu (0x%llx) in %llu"
-					    " (0x%llx)? (y/n)"),
-					(unsigned long long)di->dinode,
-					(unsigned long long)di->dinode,
-					(unsigned long long)di->treewalk_parent,
-					(unsigned long long)di->treewalk_parent)) {
-					error = remove_dentry_from_dir(sdp, di->treewalk_parent,
-												   di->dinode);
-					if (error < 0) {
-						stack;
-						return NULL;
-					}
-					if (error > 0) {
-						log_warn( _("Unable to find dentry for block %llu"
-							" (0x%llx) in %llu (0x%llx)\n"),
-							 (unsigned long long)di->dinode,
-							(unsigned long long)di->dinode,
-							(unsigned long long)di->treewalk_parent,
-							(unsigned long long)di->treewalk_parent);
-					}
-					log_warn( _("Directory entry removed\n"));
-				} else {
-					log_err( _("Directory entry to invalid inode remains\n"));
-				}
-				log_info( _("Marking directory unlinked\n"));
-
-				return NULL;
-			}
-			else {
-				log_err( _("Both .. and treewalk parents are "
-					   "directories, going with treewalk "
-					   "for now...\n"));
-				attach_dotdot_to(sdp, di->treewalk_parent,
-						 di->dotdot_parent,
-						 di->dinode);
-				di->dotdot_parent = di->treewalk_parent;
-			}
+			log_err( _("Orphaned directory at block %llu (0x%llx) "
+				   "moved to lost+found\n"),
+				 (unsigned long long)di->dinode,
+				 (unsigned long long)di->dinode);
+			return NULL;
 		}
+		goto out;
 	}
-	else {
-		q_dotdot = block_type(di->dotdot_parent);
-		if (q_dotdot != gfs2_inode_dir) {
-			log_err( _("Orphaned directory at block %llu (0x%llx) moved to lost+found\n"),
-				(unsigned long long)di->dinode,
-				(unsigned long long)di->dinode);
+
+	log_warn( _("Directory '..' and treewalk connections disagree for "
+		    "inode %llu (0x%llx)\n"), (unsigned long long)di->dinode,
+		  (unsigned long long)di->dinode);
+	log_notice( _("'..' has %llu (0x%llx), treewalk has %llu (0x%llx)\n"),
+		    (unsigned long long)di->dotdot_parent,
+		    (unsigned long long)di->dotdot_parent,
+		    (unsigned long long)di->treewalk_parent,
+		    (unsigned long long)di->treewalk_parent);
+	q_dotdot = block_type(di->dotdot_parent);
+	q_treewalk = block_type(di->treewalk_parent);
+	/* if the dotdot entry isn't a directory, but the
+	 * treewalk is, treewalk is correct - if the treewalk
+	 * entry isn't a directory, but the dotdot is, dotdot
+	 * is correct - if both are directories, which do we
+	 * choose? if neither are directories, we have a
+	 * problem - need to move this directory into lost+found
+	 */
+	if (q_dotdot != gfs2_inode_dir) {
+		if (q_treewalk != gfs2_inode_dir) {
+			log_err( _("Orphaned directory, move to "
+				   "lost+found\n"));
 			return NULL;
+		} else {
+			log_warn( _("Treewalk parent is correct, fixing "
+				    "dotdot -> %llu (0x%llx)\n"),
+				  (unsigned long long)di->treewalk_parent,
+				  (unsigned long long)di->treewalk_parent);
+			attach_dotdot_to(sdp, di->treewalk_parent,
+					 di->dotdot_parent, di->dinode);
+			di->dotdot_parent = di->treewalk_parent;
 		}
+		goto out;
+	}
+	if (q_treewalk == gfs2_inode_dir) {
+		log_err( _("Both .. and treewalk parents are directories, "
+			   "going with treewalk...\n"));
+		attach_dotdot_to(sdp, di->treewalk_parent,
+				 di->dotdot_parent, di->dinode);
+		di->dotdot_parent = di->treewalk_parent;
+		goto out;
 	}
+	log_warn( _(".. parent is valid, but treewalk is bad - reattaching to "
+		    "lost+found"));
+
+	/* FIXME: add a dinode for this entry instead? */
+
+	if (!query( _("Remove directory entry for bad inode %llu (0x%llx) in "
+		      "%llu (0x%llx)? (y/n)"),
+		    (unsigned long long)di->dinode,
+		    (unsigned long long)di->dinode,
+		    (unsigned long long)di->treewalk_parent,
+		    (unsigned long long)di->treewalk_parent)) {
+		log_err( _("Directory entry to invalid inode remains\n"));
+		return NULL;
+	}
+	error = remove_dentry_from_dir(sdp, di->treewalk_parent, di->dinode);
+	if (error < 0) {
+		stack;
+		return NULL;
+	}
+	if (error > 0)
+		log_warn( _("Unable to find dentry for block %llu"
+			    " (0x%llx) in %llu (0x%llx)\n"),
+			  (unsigned long long)di->dinode,
+			  (unsigned long long)di->dinode,
+			  (unsigned long long)di->treewalk_parent,
+			  (unsigned long long)di->treewalk_parent);
+	log_warn( _("Directory entry removed\n"));
+	log_info( _("Marking directory unlinked\n"));
+
+	return NULL;
+
+out:
 	pdi = dirtree_find(di->dotdot_parent);
 
 	return pdi;
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 28/66] fsck.gfs2: misc cosmetic changes
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (26 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 27/66] fsck.gfs2 pass3: Refactor mark_and_return_parent rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 29/66] fsck.gfs2: Don't use old_leaf if it was a duplicate rpeterso
                   ` (37 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch is just cosmetic changes.  It cleans up comments and code
but there should be no logic changes.

rhbz#675723
---
 gfs2/fsck/metawalk.c |   17 +++++++----------
 gfs2/fsck/pass1.c    |    8 ++++----
 gfs2/fsck/pass1b.c   |    9 +++++----
 gfs2/fsck/pass2.c    |    2 +-
 gfs2/fsck/pass5.c    |   10 ++++++----
 5 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 92973ae..9b68de8 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -453,15 +453,14 @@ static int warn_and_patch(struct gfs2_inode *ip, uint64_t *leaf_no,
 	}
 	if (*leaf_no == *bad_leaf ||
 	    (okay_to_fix = query( _("Attempt to patch around it? (y/n) ")))) {
-		if (!valid_block(ip->i_sbd, old_leaf) == 0)
+		if (valid_block(ip->i_sbd, old_leaf))
 			gfs2_put_leaf_nr(ip, pindex, old_leaf);
 		else
 			gfs2_put_leaf_nr(ip, pindex, first_ok_leaf);
 		log_err( _("Directory Inode %llu (0x%llx) repaired.\n"),
 			 (unsigned long long)ip->i_di.di_num.no_addr,
 			 (unsigned long long)ip->i_di.di_num.no_addr);
-	}
-	else
+	} else
 		log_err( _("Bad leaf left in place.\n"));
 	*bad_leaf = *leaf_no;
 	*leaf_no = old_leaf;
@@ -610,9 +609,9 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 	   leaf. That way, bad blocks at the beginning will be overwritten
 	   with the first valid leaf. */
 	first_ok_leaf = leaf_no = -1;
-	for(lindex = 0; lindex < (1 << ip->i_di.di_depth); lindex++) {
+	for (lindex = 0; lindex < (1 << ip->i_di.di_depth); lindex++) {
 		gfs2_get_leaf_nr(ip, lindex, &leaf_no);
-		if (!valid_block(ip->i_sbd, leaf_no) == 0) {
+		if (valid_block(ip->i_sbd, leaf_no)) {
 			lbh = bread(sdp, leaf_no);
 			/* Make sure it's really a valid leaf block. */
 			if (gfs2_check_meta(lbh, GFS2_METATYPE_LF) == 0) {
@@ -638,11 +637,9 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 		gfs2_get_leaf_nr(ip, lindex, &leaf_no);
 
 		/* GFS has multiple indirect pointers to the same leaf
-		 * until those extra pointers are needed, so skip the
-		 * dups */
+		 * until those extra pointers are needed, so skip the dups */
 		if (leaf_no == bad_leaf) {
-			gfs2_put_leaf_nr(ip, lindex, old_leaf); /* fill w/old
-								  leaf info */
+			gfs2_put_leaf_nr(ip, lindex, old_leaf);
 			ref_count++;
 			continue;
 		} else if (old_leaf == leaf_no) {
@@ -812,7 +809,7 @@ int delete_block(struct gfs2_inode *ip, uint64_t block,
 		 struct gfs2_buffer_head **bh, const char *btype,
 		 void *private)
 {
-	if (!valid_block(ip->i_sbd, block) == 0) {
+	if (valid_block(ip->i_sbd, block)) {
 		fsck_blockmap_set(ip, block, btype, gfs2_block_free);
 		return 0;
 	}
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 7077272..f5ec37a 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -371,7 +371,7 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block,
 
 	*bh = NULL;
 
-	if (!valid_block(ip->i_sbd, block)){ /* blk outside of FS */
+	if (!valid_block(ip->i_sbd, block)) { /* blk outside of FS */
 		fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
 				  _("itself"), gfs2_bad_block);
 		log_debug( _("Bad indirect block (invalid/out of range) "
@@ -445,7 +445,7 @@ static int undo_check_metalist(struct gfs2_inode *ip, uint64_t block,
 
 	*bh = NULL;
 
-	if (!valid_block(ip->i_sbd, block)){ /* blk outside of FS */
+	if (!valid_block(ip->i_sbd, block)) { /* blk outside of FS */
 		fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
 				  _("itself"), gfs2_block_free);
 		return 1;
@@ -866,7 +866,7 @@ static int check_extended_leaf_eattr(struct gfs2_inode *ip, uint64_t *data_ptr,
 	struct gfs2_buffer_head *bh = NULL;
 	int error;
 
-	if (!valid_block(sdp, el_blk)){
+	if (!valid_block(sdp, el_blk)) {
 		log_err( _("Inode #%llu (0x%llx): Extended Attribute block "
 			   "%llu (0x%llx) has an extended leaf block #%llu "
 			   "(0x%llx) that is invalid or out of range.\n"),
@@ -1058,7 +1058,7 @@ static int rangecheck_block(struct gfs2_inode *ip, uint64_t block,
 	long *bad_pointers = (long *)private;
 	uint8_t q;
 
-	if (!valid_block(ip->i_sbd, block) != 0) {
+	if (!valid_block(ip->i_sbd, block)) {
 		(*bad_pointers)++;
 		log_info( _("Bad %s block pointer (invalid or out of range "
 			    "#%ld) found in inode %lld (0x%llx).\n"),
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index 259eb7a..67b8d14 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -209,7 +209,7 @@ static int clear_dup_metalist(struct gfs2_inode *ip, uint64_t block,
 	struct dup_handler *dh = (struct dup_handler *) private;
 	struct duptree *d;
 
-	if (!valid_block(ip->i_sbd, block) != 0)
+	if (!valid_block(ip->i_sbd, block))
 		return 0;
 
 	/* This gets tricky. We're traversing a metadata tree trying to
@@ -625,9 +625,10 @@ int pass1b(struct gfs2_sbd *sdp)
 	/* Rescan the fs looking for pointers to blocks that are in
 	 * the duplicate block map */
 	log_info( _("Scanning filesystem for inodes containing duplicate blocks...\n"));
-	log_debug( _("Filesystem has %"PRIu64" (0x%" PRIx64 ") blocks total\n"),
-			  last_fs_block, last_fs_block);
-	for(i = 0; i < last_fs_block; i++) {
+	log_debug( _("Filesystem has %llu (0x%llx) blocks total\n"),
+		  (unsigned long long)last_fs_block,
+		  (unsigned long long)last_fs_block);
+	for (i = 0; i < last_fs_block; i++) {
 		if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
 			goto out;
 
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 5fe5454..7f32903 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -767,7 +767,7 @@ int pass2(struct gfs2_sbd *sdp)
 		return FSCK_OK;
 	log_info( _("Checking directory inodes.\n"));
 	/* Grab each directory inode, and run checks on it */
-	for(dirblk = 0; dirblk < last_fs_block; dirblk++) {
+	for (dirblk = 0; dirblk < last_fs_block; dirblk++) {
 		warm_fuzzy_stuff(dirblk);
 		if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
 			return FSCK_OK;
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index b71b2b6..814f202 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -43,13 +43,14 @@ static int convert_mark(uint8_t q, uint32_t *count)
 
 	default:
 		log_err( _("Invalid block type %d found\n"), q);
-		return -1;
 	}
 	return -1;
 }
 
-static int check_block_status(struct gfs2_sbd *sdp, char *buffer, unsigned int buflen,
-					   uint64_t *rg_block, uint64_t rg_data, uint32_t *count)
+
+static int check_block_status(struct gfs2_sbd *sdp, char *buffer,
+			      unsigned int buflen, uint64_t *rg_block,
+			      uint64_t rg_data, uint32_t *count)
 {
 	unsigned char *byte, *end;
 	unsigned int bit;
@@ -150,7 +151,8 @@ static void update_rgrp(struct gfs2_sbd *sdp, struct rgrp_list *rgp,
 
 		/* update the bitmaps */
 		check_block_status(sdp, rgp->bh[i]->b_data + bits->bi_offset,
-						   bits->bi_len, &rg_block, rgp->ri.ri_data0, count);
+				   bits->bi_len, &rg_block, rgp->ri.ri_data0,
+				   count);
 		if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
 			return;
 	}
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 29/66] fsck.gfs2: Don't use old_leaf if it was a duplicate
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (27 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 28/66] fsck.gfs2: misc cosmetic changes rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 30/66] fsck.gfs2: Add find_remove_dup, free_block_if_notdup rpeterso
                   ` (36 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

In function check_leaf_blks fsck.gfs2 keeps track of the current leaf
and the previous leaf.  It can only check the number of pointers is
correct for the old leaf after it finds a new leaf block.  However,
it was getting confused if the old leaf was a duplicate reference.
If the old leaf was a duplicate referenced by a different dinode, we
can't check the number of pointers because the number of pointers may
be for that other dinode's reference, not this one.  The other dinode
referencing this leaf block may have the correct depth and this one
may not.  This patch adds an extra check for the old leaf block being
a duplicate before checking the number of pointers.

rhbz#675723
---
 gfs2/fsck/metawalk.c |   12 +++++++++---
 1 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 9b68de8..a5de1c8 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -603,7 +603,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 	struct gfs2_buffer_head *lbh;
 	int lindex;
 	struct gfs2_sbd *sdp = ip->i_sbd;
-	int ref_count = 0;
+	int ref_count = 0, old_was_dup;
 
 	/* Find the first valid leaf pointer in range and use it as our "old"
 	   leaf. That way, bad blocks at the beginning will be overwritten
@@ -631,7 +631,8 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 	}
 	old_leaf = -1;
 	memset(&oldleaf, 0, sizeof(oldleaf));
-	for(lindex = 0; lindex < (1 << ip->i_di.di_depth); lindex++) {
+	old_was_dup = 0;
+	for (lindex = 0; lindex < (1 << ip->i_di.di_depth); lindex++) {
 		if (fsck_abort)
 			break;
 		gfs2_get_leaf_nr(ip, lindex, &leaf_no);
@@ -650,7 +651,11 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 		do {
 			if (fsck_abort)
 				return 0;
-			if (pass->check_num_ptrs &&
+			/* If the old leaf was a duplicate referenced by a
+			   previous dinode, we can't check the number of
+			   pointers because the number of pointers may be for
+			   that other dinode's reference, not this one. */
+			if (pass->check_num_ptrs && !old_was_dup &&
 			    valid_block(ip->i_sbd, old_leaf)) {
 				error = pass->check_num_ptrs(ip, old_leaf,
 							     &ref_count,
@@ -662,6 +667,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 			error = check_leaf(ip, lindex, pass, &ref_count,
 					   &leaf_no, old_leaf, &bad_leaf,
 					   first_ok_leaf, &leaf, &oldleaf);
+			old_was_dup = (error == -EEXIST);
 			old_leaf = leaf_no;
 			memcpy(&oldleaf, &leaf, sizeof(oldleaf));
 			if (!leaf.lf_next || error)
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 30/66] fsck.gfs2: Add find_remove_dup, free_block_if_notdup
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (28 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 29/66] fsck.gfs2: Don't use old_leaf if it was a duplicate rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 31/66] fsck.gfs2: don't free prev rgrp list repairing rgrps rpeterso
                   ` (35 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch adds a couple new functions to util.c: find_remove_dup
and free_block_if_notdup.  This is a centralized function that
is used to remove a duplicate reference.  Each reference needs to be
removed to determine when all duplicate references have been resolved.
The object is to get down to one reference, so we can set the proper
type based on the remaining reference.  However, if the very last
reference is deleted as well, the block may be freed.
These functions present one consistent way to do all this rather than
before when the it wasn't very consistent and various bitmap
inaccuracies were sometimes left in the file system.

rhbz#675723
---
 gfs2/fsck/metawalk.c |   64 ++++++++++++++++++++++++-------
 gfs2/fsck/metawalk.h |    4 ++
 gfs2/fsck/pass1.c    |   34 +----------------
 gfs2/fsck/util.c     |  101 ++++++++++++++++++++++++++-----------------------
 gfs2/fsck/util.h     |    4 ++
 5 files changed, 113 insertions(+), 94 deletions(-)

diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index a5de1c8..b25b40d 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -823,6 +823,54 @@ int delete_block(struct gfs2_inode *ip, uint64_t block,
 }
 
 /**
+ * find_remove_dup - find out if this is a duplicate ref.  If so, remove it.
+ * Returns: 0 if not a duplicate reference, 1 if it is.
+ */
+int find_remove_dup(struct gfs2_inode *ip, uint64_t block, const char *btype)
+{
+	struct duptree *d;
+	struct inode_with_dups *id;
+
+	d = dupfind(block);
+	if (!d)
+		return 0;
+
+	/* remove the inode reference id structure for this reference. */
+	id = find_dup_ref_inode(d, ip);
+	if (!id)
+		return 0;
+
+	dup_listent_delete(id);
+	log_err( _("Removing duplicate status of block %llu (0x%llx) "
+		   "referenced as %s by dinode %llu (0x%llx)\n"),
+		 (unsigned long long)block, (unsigned long long)block,
+		 btype, (unsigned long long)ip->i_di.di_num.no_addr,
+		 (unsigned long long)ip->i_di.di_num.no_addr);
+	d->refs--; /* one less reference */
+	if (d->refs == 1) {
+		log_info( _("This leaves only one reference: it's "
+			    "no longer a duplicate.\n"));
+		dup_delete(d); /* not duplicate now */
+	} else
+		log_info( _("%d block reference(s) remain.\n"),
+			  d->refs);
+	return 1; /* but the original ref still exists so do not free it. */
+}
+
+/**
+ * free_block_if_notdup - free blocks associated with an inode, but if it's a
+ *                        duplicate, just remove that designation instead.
+ * Returns: 0 if the block was freed, 1 if a duplicate reference was removed
+ */
+int free_block_if_notdup(struct gfs2_inode *ip, uint64_t block,
+			 const char *btype)
+{
+	if (!find_remove_dup(ip, block, btype))
+		fsck_blockmap_set(ip, block, btype, gfs2_block_free);
+	return 0;
+}
+
+/**
  * delete_block_if_notdup - delete blocks associated with an inode
  *
  * Ignore blocks that are already marked free.
@@ -834,7 +882,6 @@ static int delete_block_if_notdup(struct gfs2_inode *ip, uint64_t block,
 				  const char *btype, void *private)
 {
 	uint8_t q;
-	struct duptree *d;
 
 	if (!valid_block(ip->i_sbd, block))
 		return -EFAULT;
@@ -849,20 +896,7 @@ static int delete_block_if_notdup(struct gfs2_inode *ip, uint64_t block,
 			  (unsigned long long)ip->i_di.di_num.no_addr);
 		return 0;
 	}
-	d = dupfind(block);
-	if (d) {
-		log_info( _("Removing duplicate reference %d "
-			    "to block %lld (0x%llx).\n"), d->refs,
-			  (unsigned long long)block,
-			  (unsigned long long)block);
-		d->refs--; /* one less reference */
-		if (d->refs == 1) /* If down to the last reference */
-			dup_delete(d); /* not duplicate now */
-		return 1; /* but the original ref still exists
-			     so return (do not free it). */
-	}
-	fsck_blockmap_set(ip, block, btype, gfs2_block_free);
-	return 0;
+	return free_block_if_notdup(ip, block, btype);
 }
 
 /**
diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h
index 7a8ae4c..719bbd9 100644
--- a/gfs2/fsck/metawalk.h
+++ b/gfs2/fsck/metawalk.h
@@ -35,6 +35,10 @@ extern void reprocess_inode(struct gfs2_inode *ip, const char *desc);
 extern struct duptree *dupfind(uint64_t block);
 extern struct gfs2_inode *fsck_system_inode(struct gfs2_sbd *sdp,
 					    uint64_t block);
+extern int find_remove_dup(struct gfs2_inode *ip, uint64_t block,
+			   const char *btype);
+extern int free_block_if_notdup(struct gfs2_inode *ip, uint64_t block,
+				const char *btype);
 
 #define is_duplicate(dblock) ((dupfind(dblock)) ? 1 : 0)
 
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index f5ec37a..64220f0 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -438,7 +438,6 @@ static int undo_check_metalist(struct gfs2_inode *ip, uint64_t block,
 			       struct gfs2_buffer_head **bh, int h,
 			       void *private)
 {
-	struct duptree *d;
 	int found_dup = 0, iblk_type;
 	struct gfs2_buffer_head *nbh;
 	struct block_count *bc = (struct block_count *)private;
@@ -455,20 +454,7 @@ static int undo_check_metalist(struct gfs2_inode *ip, uint64_t block,
 	else
 		iblk_type = GFS2_METATYPE_IN;
 
-	d = dupfind(block);
-	if (d) {
-		log_err( _("Reversing duplicate status of block %llu (0x%llx) "
-			   "referenced as metadata in indirect block for "
-			   "dinode %llu (0x%llx)\n"),
-			 (unsigned long long)block,
-			 (unsigned long long)block,
-			 (unsigned long long)ip->i_di.di_num.no_addr,
-			 (unsigned long long)ip->i_di.di_num.no_addr);
-		d->refs--; /* one less reference */
-		if (d->refs == 1)
-			dup_delete(d);
-		found_dup = 1;
-	}
+	found_dup = find_remove_dup(ip, block, _("Metadata"));
 	nbh = bread(ip->i_sbd, block);
 
 	if (gfs2_check_meta(nbh, iblk_type)) {
@@ -548,7 +534,6 @@ static int check_data(struct gfs2_inode *ip, uint64_t block, void *private)
 static int undo_check_data(struct gfs2_inode *ip, uint64_t block,
 			   void *private)
 {
-	struct duptree *d;
 	struct block_count *bc = (struct block_count *) private;
 
 	if (!valid_block(ip->i_sbd, block)) {
@@ -560,23 +545,8 @@ static int undo_check_data(struct gfs2_inode *ip, uint64_t block,
 				  gfs2_block_free);
 		return 1;
 	}
-	d = dupfind(block);
-	if (d) {
-		log_err( _("Reversing duplicate status of block %llu (0x%llx) "
-			   "referenced as data by dinode %llu (0x%llx)\n"),
-			 (unsigned long long)block,
-			 (unsigned long long)block,
-			 (unsigned long long)ip->i_di.di_num.no_addr,
-			 (unsigned long long)ip->i_di.di_num.no_addr);
-		d->refs--; /* one less reference */
-		if (d->refs == 1)
-			dup_delete(d);
-		bc->data_count--;
-		return 1;
-	}
-	fsck_blockmap_set(ip, block, _("data"), gfs2_block_free);
 	bc->data_count--;
-	return 0;
+	return free_block_if_notdup(ip, block, _("data"));
 }
 
 static int remove_inode_eattr(struct gfs2_inode *ip, struct block_count *bc)
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index 9930624..569f25a 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -185,6 +185,30 @@ static struct duptree *gfs2_dup_set(uint64_t dblock, int create)
 	return data;
 }
 
+/**
+ * find_dup_ref_inode - find a duplicate reference inode entry for an inode
+ */
+struct inode_with_dups *find_dup_ref_inode(struct duptree *dt,
+					   struct gfs2_inode *ip)
+{
+	osi_list_t *ref;
+	struct inode_with_dups *id;
+
+	osi_list_foreach(ref, &dt->ref_invinode_list) {
+		id = osi_list_entry(ref, struct inode_with_dups, list);
+
+		if (id->block_no == ip->i_di.di_num.no_addr)
+			return id;
+	}
+	osi_list_foreach(ref, &dt->ref_inode_list) {
+		id = osi_list_entry(ref, struct inode_with_dups, list);
+
+		if (id->block_no == ip->i_di.di_num.no_addr)
+			return id;
+	}
+	return NULL;
+}
+
 /*
  * add_duplicate_ref - Add a duplicate reference to the duplicates tree list
  * A new element of the tree will be created as needed
@@ -193,15 +217,19 @@ static struct duptree *gfs2_dup_set(uint64_t dblock, int create)
  * So we need to recreate the duplicate reference structure if it's not there.
  * Later, in pass1b, it has to go back through the file system
  * and figure out those original references in order to resolve them.
+ *
+ * first - if 1, we're being called from pass1b, in which case we're trying
+ *         to find the first reference to this block.  If 0, we're being
+ *         called from pass1, which is the second reference, which determined
+ *         it was a duplicate..
  */
 int add_duplicate_ref(struct gfs2_inode *ip, uint64_t block,
 		      enum dup_ref_type reftype, int first, int inode_valid)
 {
-	osi_list_t *ref;
-	struct inode_with_dups *id, *found_id;
+	struct inode_with_dups *id;
 	struct duptree *dt;
 
-	if (!valid_block(ip->i_sbd, block) != 0)
+	if (!valid_block(ip->i_sbd, block))
 		return 0;
 	/* If this is not the first reference (i.e. all calls from pass1) we
 	   need to create the duplicate reference. If this is pass1b, we want
@@ -221,65 +249,42 @@ int add_duplicate_ref(struct gfs2_inode *ip, uint64_t block,
 	   reference, we don't want to increment the reference count because
 	   it's already accounted for. */
 	if (first) {
-		if (!dt->first_ref_found) {
-			dt->first_ref_found = 1;
-			dups_found_first++; /* We found another first ref. */
-		}
+		dt->first_ref_found = 1;
+		dups_found_first++; /* We found another first ref. */
 	} else {
 		dt->refs++;
 	}
 
-	/* Check for a previous reference to this duplicate on the "invalid
-	   inode" reference list. */
-	found_id = NULL;
-	osi_list_foreach(ref, &dt->ref_invinode_list) {
-		id = osi_list_entry(ref, struct inode_with_dups, list);
-
-		if (id->block_no == ip->i_di.di_num.no_addr) {
-			found_id = id;
-			break;
-		}
-	}
-	if (found_id == NULL) {
-		osi_list_foreach(ref, &dt->ref_inode_list) {
-			id = osi_list_entry(ref, struct inode_with_dups, list);
-
-			if (id->block_no == ip->i_di.di_num.no_addr) {
-				found_id = id;
-				break;
-			}
-		}
-	}
-	if (found_id == NULL) {
+	/* Check for a previous reference to this duplicate */
+	id = find_dup_ref_inode(dt, ip);
+	if (id == NULL) {
 		/* Check for the inode on the invalid inode reference list. */
 		uint8_t q;
 
-		if (!(found_id = malloc(sizeof(*found_id)))) {
+		if (!(id = malloc(sizeof(*id)))) {
 			log_crit( _("Unable to allocate "
 				    "inode_with_dups structure\n"));
 			return -1;
 		}
-		if (!(memset(found_id, 0, sizeof(*found_id)))) {
+		if (!(memset(id, 0, sizeof(*id)))) {
 			log_crit( _("Unable to zero inode_with_dups "
 				    "structure\n"));
 			return -1;
 		}
-		found_id->block_no = ip->i_di.di_num.no_addr;
+		id->block_no = ip->i_di.di_num.no_addr;
 		q = block_type(ip->i_di.di_num.no_addr);
 		/* If it's an invalid dinode, put it first on the invalid
 		   inode reference list otherwise put it on the normal list. */
 		if (!inode_valid || q == gfs2_inode_invalid)
-			osi_list_add_prev(&found_id->list,
-					  &dt->ref_invinode_list);
+			osi_list_add_prev(&id->list, &dt->ref_invinode_list);
 		else
-			osi_list_add_prev(&found_id->list,
-					  &dt->ref_inode_list);
+			osi_list_add_prev(&id->list, &dt->ref_inode_list);
 	}
-	found_id->reftypecount[reftype]++;
-	found_id->dup_count++;
+	id->reftypecount[reftype]++;
+	id->dup_count++;
 	log_info( _("Found %d reference(s) to block %llu"
 		    " (0x%llx) as %s in inode #%llu (0x%llx)\n"),
-		  found_id->dup_count, (unsigned long long)block,
+		  id->dup_count, (unsigned long long)block,
 		  (unsigned long long)block, reftypes[reftype],
 		  (unsigned long long)ip->i_di.di_num.no_addr,
 		  (unsigned long long)ip->i_di.di_num.no_addr);
@@ -343,6 +348,14 @@ struct dir_info *dirtree_find(uint64_t block)
 	return NULL;
 }
 
+void dup_listent_delete(struct inode_with_dups *id)
+{
+	if (id->name)
+		free(id->name);
+	osi_list_del(&id->list);
+	free(id);
+}
+
 void dup_delete(struct duptree *b)
 {
 	struct inode_with_dups *id;
@@ -351,18 +364,12 @@ void dup_delete(struct duptree *b)
 	while (!osi_list_empty(&b->ref_invinode_list)) {
 		tmp = (&b->ref_invinode_list)->next;
 		id = osi_list_entry(tmp, struct inode_with_dups, list);
-		if (id->name)
-			free(id->name);
-		osi_list_del(&id->list);
-		free(id);
+		dup_listent_delete(id);
 	}
 	while (!osi_list_empty(&b->ref_inode_list)) {
 		tmp = (&b->ref_inode_list)->next;
 		id = osi_list_entry(tmp, struct inode_with_dups, list);
-		if (id->name)
-			free(id->name);
-		osi_list_del(&id->list);
-		free(id);
+		dup_listent_delete(id);
 	}
 	osi_erase(&b->node, &dup_blocks);
 	free(b);
diff --git a/gfs2/fsck/util.h b/gfs2/fsck/util.h
index d2c81db..56b83fe 100644
--- a/gfs2/fsck/util.h
+++ b/gfs2/fsck/util.h
@@ -15,6 +15,10 @@ void big_file_comfort(struct gfs2_inode *ip, uint64_t blks_checked);
 void warm_fuzzy_stuff(uint64_t block);
 int add_duplicate_ref(struct gfs2_inode *ip, uint64_t block,
 		      enum dup_ref_type reftype, int first, int inode_valid);
+extern struct inode_with_dups *find_dup_ref_inode(struct duptree *dt,
+						  struct gfs2_inode *ip);
+extern void dup_listent_delete(struct inode_with_dups *id);
+
 extern const char *reftypes[3];
 
 static inline uint8_t block_type(uint64_t bblock)
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 31/66] fsck.gfs2: don't free prev rgrp list repairing rgrps
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (29 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 30/66] fsck.gfs2: Add find_remove_dup, free_block_if_notdup rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 32/66] libgfs2: eliminate gfs1_readi in favor of gfs2_readi rpeterso
                   ` (34 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

In cases where fsck.gfs2 is trying to repair damaged resource groups or
rindex, it tries several levels of repair.  Some of those levels build a
list of expected resource groups and check them against the actual ones,
and the previous list is freed before the next level is attempted.
However, in the case of minor damage, such as one bitmap block that was
overwritten, we can often repair the damage by reading in the resource
groups at the first level, then at the second level of repair (called
"ye_of_little_faith") use those values to compare against.  This patch
allows the second level of repair to use the first level's list.

rhbz#675723
---
 gfs2/fsck/rgrepair.c |   17 +++++++++++++----
 1 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c
index 52cc529..c01aaa6 100644
--- a/gfs2/fsck/rgrepair.c
+++ b/gfs2/fsck/rgrepair.c
@@ -780,12 +780,12 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count, int *sane)
 	osi_list_t *exp, *act; /* expected, actual */
 	struct gfs2_rindex buf;
 
-	/* Free previous incarnations in memory, if any. */
-	gfs2_rgrp_free(&sdp->rglist);
-
 	if (trust_lvl == blind_faith)
 		return 0;
-	else if (trust_lvl == ye_of_little_faith) { /* if rindex seems sane */
+	if (trust_lvl == ye_of_little_faith) { /* if rindex seems sane */
+		/* Don't free previous incarnations in memory, if any.
+		 * We need them to copy in the next function:
+		 * gfs2_rgrp_free(&sdp->rglist); */
 		if (!(*sane)) {
 			log_err(_("The rindex file does not meet our "
 				  "expectations.\n"));
@@ -798,6 +798,9 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count, int *sane)
 			return error;
 		}
 	} else if (trust_lvl == open_minded) { /* If we can't trust RG index */
+		/* Free previous incarnations in memory, if any. */
+		gfs2_rgrp_free(&sdp->rglist);
+
 		/* Calculate our own RG index for comparison */
 		error = gfs2_rindex_calculate(sdp, &expected_rglist,
 					      &calc_rg_count);
@@ -807,6 +810,9 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count, int *sane)
 		}
 	}
 	else if (trust_lvl == distrust) { /* If we can't trust RG index */
+		/* Free previous incarnations in memory, if any. */
+		gfs2_rgrp_free(&sdp->rglist);
+
 		error = gfs2_rindex_rebuild(sdp, &expected_rglist,
 					    &calc_rg_count, 0);
 		if (error) {
@@ -817,6 +823,9 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count, int *sane)
 		sdp->rgrps = calc_rg_count;
 	}
 	else if (trust_lvl == indignation) { /* If we can't trust anything */
+		/* Free previous incarnations in memory, if any. */
+		gfs2_rgrp_free(&sdp->rglist);
+
 		error = gfs2_rindex_rebuild(sdp, &expected_rglist,
 					    &calc_rg_count, 1);
 		if (error) {
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 32/66] libgfs2: eliminate gfs1_readi in favor of gfs2_readi
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (30 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 31/66] fsck.gfs2: don't free prev rgrp list repairing rgrps rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 33/66] libgfs2: Mark buffer modified adding a new GFS1 block rpeterso
                   ` (33 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch eliminates function gfs1_readi because it's nearly
identical to gfs2_readi.  The gfs1-specific bits have been made
generic in gfs2_readi based on the sdp->gfs1 setting.

rhbz#675723
---
 gfs2/edit/extended.c   |    8 +----
 gfs2/libgfs2/fs_ops.c  |   21 ++++++++++----
 gfs2/libgfs2/gfs1.c    |   68 +-----------------------------------------------
 gfs2/libgfs2/libgfs2.h |    2 -
 gfs2/libgfs2/super.c   |    5 ---
 5 files changed, 18 insertions(+), 86 deletions(-)

diff --git a/gfs2/edit/extended.c b/gfs2/edit/extended.c
index 366dfc6..6326ec3 100644
--- a/gfs2/edit/extended.c
+++ b/gfs2/edit/extended.c
@@ -515,12 +515,8 @@ static int parse_rindex(struct gfs2_inode *dip, int print_rindex)
 
 		roff = print_entry_ndx * sizeof(struct gfs2_rindex);
 
-		if (sbd.gfs1)
-			error = gfs1_readi(dip, (void *)&rbuf, roff,
-					   sizeof(struct gfs2_rindex));
-		else
-			error = gfs2_readi(dip, (void *)&rbuf, roff,
-					   sizeof(struct gfs2_rindex));
+		error = gfs2_readi(dip, (void *)&rbuf, roff,
+				   sizeof(struct gfs2_rindex));
 		if (!error) /* end of file */
 			break;
 		gfs2_rindex_in(&ri, rbuf);
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index 3d57b97..6ffee9d 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -508,6 +508,7 @@ int gfs2_readi(struct gfs2_inode *ip, void *buf,
 	unsigned int amount;
 	int not_new = 0;
 	int isdir = !!(S_ISDIR(ip->i_di.di_mode));
+	int journaled = ip->i_di.di_flags & GFS2_DIF_JDATA;
 	int copied = 0;
 
 	if (offset >= ip->i_di.di_size)
@@ -519,7 +520,7 @@ int gfs2_readi(struct gfs2_inode *ip, void *buf,
 	if (!size)
 		return 0;
 
-	if (isdir) {
+	if ((sdp->gfs1 && journaled) || (!sdp->gfs1 && isdir)) {
 		lblock = offset;
 		o = lblock % sdp->sd_jbsize;
 		lblock /= sdp->sd_jbsize;
@@ -530,7 +531,7 @@ int gfs2_readi(struct gfs2_inode *ip, void *buf,
 
 	if (inode_is_stuffed(ip))
 		o += sizeof(struct gfs2_dinode);
-	else if (isdir)
+	else if ((sdp->gfs1 && journaled) || (!sdp->gfs1 && isdir))
 		o += sizeof(struct gfs2_meta_header);
 
 	while (copied < size) {
@@ -538,9 +539,14 @@ int gfs2_readi(struct gfs2_inode *ip, void *buf,
 		if (amount > sdp->bsize - o)
 			amount = sdp->bsize - o;
 
-		if (!extlen)
-			block_map(ip, lblock, &not_new, &dblock, &extlen,
-				  FALSE);
+		if (!extlen) {
+			if (sdp->gfs1)
+				gfs1_block_map(ip, lblock, &not_new, &dblock,
+					       &extlen, FALSE);
+			else
+				block_map(ip, lblock, &not_new, &dblock,
+					  &extlen, FALSE);
+		}
 
 		if (dblock) {
 			if (dblock == ip->i_di.di_num.no_addr)
@@ -559,7 +565,10 @@ int gfs2_readi(struct gfs2_inode *ip, void *buf,
 		copied += amount;
 		lblock++;
 
-		o = (isdir) ? sizeof(struct gfs2_meta_header) : 0;
+		if (sdp->gfs1)
+			o = (journaled) ? sizeof(struct gfs2_meta_header) : 0;
+		else
+			o = (isdir) ? sizeof(struct gfs2_meta_header) : 0;
 	}
 
 	return copied;
diff --git a/gfs2/libgfs2/gfs1.c b/gfs2/libgfs2/gfs1.c
index 5018334..2bdf57f 100644
--- a/gfs2/libgfs2/gfs1.c
+++ b/gfs2/libgfs2/gfs1.c
@@ -154,72 +154,6 @@ void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
 	free(mp);
 }
 
-int gfs1_readi(struct gfs2_inode *ip, void *bufin,
-	       uint64_t offset, unsigned int size)
-{
-	struct gfs2_sbd *sdp = ip->i_sbd;
-	struct gfs2_buffer_head *bh;
-	uint64_t lblock, dblock = 0;
-	uint32_t extlen = 0;
-	unsigned int amount;
-	int not_new = 0;
-	int journaled = fs_is_jdata(ip);
-	int copied = 0;
-	char *buf = bufin;
-
-	if (offset >= ip->i_di.di_size)
-		return 0;
-
-	if ((offset + size) > ip->i_di.di_size)
-		size = ip->i_di.di_size - offset;
-
-	if (!size)
-		return 0;
-
-	if (journaled) {
-		lblock = offset / sdp->sd_jbsize;
-		offset %= sdp->sd_jbsize;
-	} else {
-		lblock = offset >> sdp->sd_sb.sb_bsize_shift;
-		offset &= sdp->sd_sb.sb_bsize - 1;
-	}
-
-	if (!ip->i_di.di_height) /* stuffed */
-		offset += sizeof(struct gfs_dinode);
-	else if (journaled)
-		offset += sizeof(struct gfs2_meta_header);
-
-	while (copied < size) {
-		amount = size - copied;
-		if (amount > sdp->bsize - offset)
-			amount = sdp->bsize - offset;
-
-		if (!extlen)
-			gfs1_block_map(ip, lblock, &not_new, &dblock,
-				       &extlen, FALSE);
-
-		if (dblock) {
-			bh = bread(sdp, dblock);
-			dblock++;
-			extlen--;
-		} else
-			bh = NULL;
-
-
-		if (bh) {
-			memcpy(buf+copied, bh->b_data + offset, amount);
-			brelse(bh);
-		} else
-			memset(buf+copied, 0, amount);
-		copied += amount;
-		lblock++;
-
-		offset = (journaled) ? sizeof(struct gfs2_meta_header) : 0;
-	}
-
-	return copied;
-}
-
 /**
  * gfs1_rindex_read - read in the rg index file
  *                  Stolen from libgfs2/super.c, but modified to handle gfs1.
@@ -244,7 +178,7 @@ int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1)
 		if (fd > 0)
 			error = read(fd, &buf, sizeof(struct gfs2_rindex));
 		else
-			error = gfs1_readi(sdp->md.riinode, (char *)&buf,
+			error = gfs2_readi(sdp->md.riinode, (char *)&buf,
 					   (rg * sizeof(struct gfs2_rindex)),
 					   sizeof(struct gfs2_rindex));
 		if (!error)
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 9bae01b..cc71bd3 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -665,8 +665,6 @@ extern void gfs1_lookup_block(struct gfs2_inode *ip,
 			      int create, int *new, uint64_t *block);
 extern void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
 			   uint64_t *dblock, uint32_t *extlen, int prealloc);
-extern int gfs1_readi(struct gfs2_inode *ip, void *buf, uint64_t offset,
-		      unsigned int size);
 extern int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1);
 extern int gfs1_ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int quiet);
 extern struct gfs2_inode *gfs_inode_get(struct gfs2_sbd *sdp,
diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c
index d902ba2..0fac740 100644
--- a/gfs2/libgfs2/super.c
+++ b/gfs2/libgfs2/super.c
@@ -158,11 +158,6 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *sane)
 	for (rg = 0; ; rg++) {
 		if (fd > 0)
 			error = read(fd, &buf, sizeof(struct gfs2_rindex));
-		else if (sdp->gfs1)
-			error = gfs1_readi(sdp->md.riinode,
-					   (char *)&buf.bufgfs1,
-					   rg * sizeof(struct gfs2_rindex),
-					   sizeof(struct gfs2_rindex));
 		else
 			error = gfs2_readi(sdp->md.riinode,
 					   (char *)&buf.bufgfs2,
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 33/66] libgfs2: Mark buffer modified adding a new GFS1 block
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (31 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 32/66] libgfs2: eliminate gfs1_readi in favor of gfs2_readi rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 34/66] libgfs2: Use dinode buffer to map gfs1 dinode blocks rpeterso
                   ` (32 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

When adding new blocks to the file system for GFS1, function
gfs1_lookup_block was not marking the buffer and dinode buffer
as modified like gfs2_lookup_block does.  This patch fixes that.

rhbz#675723
---
 gfs2/libgfs2/gfs1.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/gfs2/libgfs2/gfs1.c b/gfs2/libgfs2/gfs1.c
index 2bdf57f..59eaa8d 100644
--- a/gfs2/libgfs2/gfs1.c
+++ b/gfs2/libgfs2/gfs1.c
@@ -54,7 +54,9 @@ void gfs1_lookup_block(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
 		*block = meta_alloc(ip);
 
 	*ptr = cpu_to_be64(*block);
+	bmodified(bh);
 	ip->i_di.di_blocks++;
+	bmodified(ip->i_bh);
 
 	*new = 1;
 }
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 34/66] libgfs2: Use dinode buffer to map gfs1 dinode blocks
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (32 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 33/66] libgfs2: Mark buffer modified adding a new GFS1 block rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 35/66] libgfs2: move block_map functions to fsck.gfs2 rpeterso
                   ` (31 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

When function gfs1_block_map found a block for a stuffed file it
wasn't returning the dinode buffer, it was returning the block as a
new buffer.  The problem is, if changes are made to the block, they
will be overwritten by the dinode buffer when that is released.
The result is a fixed block that doesn't get fixed.  This patch
changes the code to return the block properly like gfs2_block_map.

rhbz#675723
---
 gfs2/libgfs2/gfs1.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/gfs2/libgfs2/gfs1.c b/gfs2/libgfs2/gfs1.c
index 59eaa8d..2ace124 100644
--- a/gfs2/libgfs2/gfs1.c
+++ b/gfs2/libgfs2/gfs1.c
@@ -118,7 +118,10 @@ void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
 			mh.mh_format = GFS2_FORMAT_IN;
 			gfs2_meta_header_out(&mh, bh);
 		} else {
-			bh = bread(sdp, *dblock);
+			if (*dblock == ip->i_di.di_num.no_addr)
+				bh = ip->i_bh;
+			else
+				bh = bread(sdp, *dblock);
 		}
 	}
 
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 35/66] libgfs2: move block_map functions to fsck.gfs2
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (33 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 34/66] libgfs2: Use dinode buffer to map gfs1 dinode blocks rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 36/66] libgfs2: eliminate gfs1_rindex_read rpeterso
                   ` (30 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

Since the "blockmap" functions were only used in fsck.gfs2 they don't
have a place in libgfs2.  This patch moves them to fsck.gfs2.

rhbz#675723
---
 gfs2/fsck/metawalk.h      |    2 +
 gfs2/fsck/util.c          |   72 ++++++++++++++++++++++++++++++++++++++
 gfs2/fsck/util.h          |   84 +++++++++++++++++++++++++++++++++++++++++++++
 gfs2/libgfs2/block_list.c |   72 --------------------------------------
 gfs2/libgfs2/libgfs2.h    |   82 -------------------------------------------
 5 files changed, 158 insertions(+), 154 deletions(-)

diff --git a/gfs2/fsck/metawalk.h b/gfs2/fsck/metawalk.h
index 719bbd9..e114427 100644
--- a/gfs2/fsck/metawalk.h
+++ b/gfs2/fsck/metawalk.h
@@ -4,6 +4,8 @@
 #define DIR_LINEAR 1
 #define DIR_EXHASH 2
 
+#include "util.h"
+
 struct metawalk_fxns;
 
 extern int check_inode_eattr(struct gfs2_inode *ip,
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index 569f25a..4075aec 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -380,3 +380,75 @@ void dirtree_delete(struct dir_info *b)
 	osi_erase(&b->node, &dirtree);
 	free(b);
 }
+
+static int gfs2_blockmap_create(struct gfs2_bmap *bmap, uint64_t size)
+{
+	bmap->size = size;
+
+	/* Have to add 1 to BLOCKMAP_SIZE since it's 0-based and mallocs
+	 * must be 1-based */
+	bmap->mapsize = BLOCKMAP_SIZE4(size);
+
+	if (!(bmap->map = malloc(sizeof(char) * bmap->mapsize)))
+		return -ENOMEM;
+	if (!memset(bmap->map, 0, sizeof(char) * bmap->mapsize)) {
+		free(bmap->map);
+		bmap->map = NULL;
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+static void gfs2_blockmap_destroy(struct gfs2_bmap *bmap)
+{
+	if (bmap->map)
+		free(bmap->map);
+	bmap->size = 0;
+	bmap->mapsize = 0;
+}
+
+struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
+				   uint64_t *addl_mem_needed)
+{
+	struct gfs2_bmap *il;
+
+	*addl_mem_needed = 0L;
+	il = malloc(sizeof(*il));
+	if (!il || !memset(il, 0, sizeof(*il)))
+		return NULL;
+
+	if (gfs2_blockmap_create(il, size)) {
+		*addl_mem_needed = il->mapsize;
+		free(il);
+		il = NULL;
+	}
+	osi_list_init(&sdp->eattr_blocks.list);
+	return il;
+}
+
+int gfs2_blockmap_set(struct gfs2_bmap *bmap, uint64_t bblock,
+		      enum gfs2_mark_block mark)
+{
+	static unsigned char *byte;
+	static uint64_t b;
+
+	if (bblock > bmap->size)
+		return -1;
+
+	byte = bmap->map + BLOCKMAP_SIZE4(bblock);
+	b = BLOCKMAP_BYTE_OFFSET4(bblock);
+	*byte &= ~(BLOCKMAP_MASK4 << b);
+	*byte |= (mark & BLOCKMAP_MASK4) << b;
+	return 0;
+}
+
+void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il)
+{
+	if (il) {
+		gfs2_blockmap_destroy(il);
+		free(il);
+		il = NULL;
+	}
+	gfs2_special_free(&sdp->eattr_blocks);
+	return il;
+}
diff --git a/gfs2/fsck/util.h b/gfs2/fsck/util.h
index 56b83fe..b26c123 100644
--- a/gfs2/fsck/util.h
+++ b/gfs2/fsck/util.h
@@ -33,4 +33,88 @@ static inline uint8_t block_type(uint64_t bblock)
 	return btype;
 }
 
+/* blockmap declarations and functions */
+enum gfs2_mark_block {
+	gfs2_block_free    = (0x0),
+	gfs2_block_used    = (0x1),
+	gfs2_indir_blk     = (0x2),
+	gfs2_inode_dir     = (0x3),
+	gfs2_inode_file    = (0x4),
+
+	gfs2_inode_lnk     = (0x5),
+	gfs2_inode_blk     = (0x6),
+	gfs2_inode_chr     = (0x7),
+	gfs2_inode_fifo    = (0x8),
+	gfs2_inode_sock    = (0x9),
+
+	gfs2_inode_invalid = (0xa),
+	gfs2_meta_inval    = (0xb),
+	gfs2_leaf_blk      = (0xc),
+	gfs2_meta_rgrp     = (0xd),
+	gfs2_meta_eattr    = (0xe),
+
+	gfs2_bad_block     = (0xf), /* Contains at least one bad block */
+};
+
+static const inline char *block_type_string(uint8_t q)
+{
+	const char *blktyp[] = {
+		"free",
+		"data",
+		"indirect data",
+		"directory",
+		"file",
+
+		"symlink",
+		"block device",
+		"char device",
+		"fifo",
+		"socket",
+
+		"invalid inode",
+		"invalid meta",
+		"dir leaf",
+		"rgrp meta",
+		"eattribute",
+
+		"bad"};
+	if (q < 16)
+		return (blktyp[q]);
+	return blktyp[15];
+}
+
+/* Must be kept in sync with gfs2_mark_block enum above. Blocks marked as
+   invalid or bad are considered metadata until actually freed. */
+static inline int blockmap_to_bitmap(enum gfs2_mark_block m)
+{
+	static int bitmap_states[16] = {
+		GFS2_BLKST_FREE,
+		GFS2_BLKST_USED,
+		GFS2_BLKST_USED,
+		GFS2_BLKST_DINODE,
+		GFS2_BLKST_DINODE,
+
+		GFS2_BLKST_DINODE,
+		GFS2_BLKST_DINODE,
+		GFS2_BLKST_DINODE,
+		GFS2_BLKST_DINODE,
+		GFS2_BLKST_DINODE,
+
+		GFS2_BLKST_FREE,
+		GFS2_BLKST_FREE,
+		GFS2_BLKST_USED,
+		GFS2_BLKST_USED,
+		GFS2_BLKST_USED,
+
+		GFS2_BLKST_USED
+	};
+	return bitmap_states[m];
+}
+
+extern struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
+					  uint64_t *addl_mem_needed);
+extern void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il);
+extern int gfs2_blockmap_set(struct gfs2_bmap *il, uint64_t block,
+			     enum gfs2_mark_block mark);
+
 #endif /* __UTIL_H__ */
diff --git a/gfs2/libgfs2/block_list.c b/gfs2/libgfs2/block_list.c
index faedc54..65003b0 100644
--- a/gfs2/libgfs2/block_list.c
+++ b/gfs2/libgfs2/block_list.c
@@ -8,51 +8,6 @@
 
 #include "libgfs2.h"
 
-static int gfs2_blockmap_create(struct gfs2_bmap *bmap, uint64_t size)
-{
-	bmap->size = size;
-
-	/* Have to add 1 to BLOCKMAP_SIZE since it's 0-based and mallocs
-	 * must be 1-based */
-	bmap->mapsize = BLOCKMAP_SIZE4(size);
-
-	if(!(bmap->map = malloc(sizeof(char) * bmap->mapsize)))
-		return -ENOMEM;
-	if(!memset(bmap->map, 0, sizeof(char) * bmap->mapsize)) {
-		free(bmap->map);
-		bmap->map = NULL;
-		return -ENOMEM;
-	}
-	return 0;
-}
-
-static void gfs2_blockmap_destroy(struct gfs2_bmap *bmap)
-{
-	if(bmap->map)
-		free(bmap->map);
-	bmap->size = 0;
-	bmap->mapsize = 0;
-}
-
-struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
-				   uint64_t *addl_mem_needed)
-{
-	struct gfs2_bmap *il;
-
-	*addl_mem_needed = 0L;
-	il = malloc(sizeof(*il));
-	if (!il || !memset(il, 0, sizeof(*il)))
-		return NULL;
-
-	if(gfs2_blockmap_create(il, size)) {
-		*addl_mem_needed = il->mapsize;
-		free(il);
-		il = NULL;
-	}
-	osi_list_init(&sdp->eattr_blocks.list);
-	return il;
-}
-
 void gfs2_special_free(struct special_blocks *blist)
 {
 	struct special_blocks *f;
@@ -108,30 +63,3 @@ void gfs2_special_clear(struct special_blocks *blocklist, uint64_t block)
 		free(b);
 	}
 }
-
-int gfs2_blockmap_set(struct gfs2_bmap *bmap, uint64_t bblock,
-		      enum gfs2_mark_block mark)
-{
-	static unsigned char *byte;
-	static uint64_t b;
-
-	if(bblock > bmap->size)
-		return -1;
-
-	byte = bmap->map + BLOCKMAP_SIZE4(bblock);
-	b = BLOCKMAP_BYTE_OFFSET4(bblock);
-	*byte &= ~(BLOCKMAP_MASK4 << b);
-	*byte |= (mark & BLOCKMAP_MASK4) << b;
-	return 0;
-}
-
-void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il)
-{
-	if(il) {
-		gfs2_blockmap_destroy(il);
-		free(il);
-		il = NULL;
-	}
-	gfs2_special_free(&sdp->eattr_blocks);
-	return il;
-}
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index cc71bd3..a2e1523 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -273,94 +273,12 @@ struct gfs2_bmap {
 
 /* block_list.c */
 
-enum gfs2_mark_block {
-	gfs2_block_free    = (0x0),
-	gfs2_block_used    = (0x1),
-	gfs2_indir_blk     = (0x2),
-	gfs2_inode_dir     = (0x3),
-	gfs2_inode_file    = (0x4),
-
-	gfs2_inode_lnk     = (0x5),
-	gfs2_inode_blk     = (0x6),
-	gfs2_inode_chr     = (0x7),
-	gfs2_inode_fifo    = (0x8),
-	gfs2_inode_sock    = (0x9),
-
-	gfs2_inode_invalid = (0xa),
-	gfs2_meta_inval    = (0xb),
-	gfs2_leaf_blk      = (0xc),
-	gfs2_meta_rgrp     = (0xd),
-	gfs2_meta_eattr    = (0xe),
-
-	gfs2_bad_block     = (0xf), /* Contains at least one bad block */
-};
-
-static const inline char *block_type_string(uint8_t q)
-{
-	const char *blktyp[] = {
-		"free",
-		"data",
-		"indirect data",
-		"directory",
-		"file",
-
-		"symlink",
-		"block device",
-		"char device",
-		"fifo",
-		"socket",
-
-		"invalid inode",
-		"invalid meta",
-		"dir leaf",
-		"rgrp meta",
-		"eattribute",
-
-		"bad"};
-	if (q < 16)
-		return (blktyp[q]);
-	return blktyp[15];
-}
-
-/* Must be kept in sync with gfs2_mark_block enum above. Blocks marked as
-   invalid or bad are considered metadata until actually freed. */
-static inline int blockmap_to_bitmap(enum gfs2_mark_block m)
-{
-	static int bitmap_states[16] = {
-		GFS2_BLKST_FREE,
-		GFS2_BLKST_USED,
-		GFS2_BLKST_USED,
-		GFS2_BLKST_DINODE,
-		GFS2_BLKST_DINODE,
-
-		GFS2_BLKST_DINODE,
-		GFS2_BLKST_DINODE,
-		GFS2_BLKST_DINODE,
-		GFS2_BLKST_DINODE,
-		GFS2_BLKST_DINODE,
-
-		GFS2_BLKST_FREE,
-		GFS2_BLKST_FREE,
-		GFS2_BLKST_USED,
-		GFS2_BLKST_USED,
-		GFS2_BLKST_USED,
-
-		GFS2_BLKST_USED
-	};
-	return bitmap_states[m];
-}
-
-extern struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
-					  uint64_t *addl_mem_needed);
 extern struct special_blocks *blockfind(struct special_blocks *blist, uint64_t num);
 extern void gfs2_special_add(struct special_blocks *blocklist, uint64_t block);
 extern void gfs2_special_set(struct special_blocks *blocklist, uint64_t block);
 extern void gfs2_special_free(struct special_blocks *blist);
-extern int gfs2_blockmap_set(struct gfs2_bmap *il, uint64_t block,
-			     enum gfs2_mark_block mark);
 extern void gfs2_special_clear(struct special_blocks *blocklist,
 			       uint64_t block);
-extern void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il);
 
 /* buf.c */
 extern struct gfs2_buffer_head *__bget_generic(struct gfs2_sbd *sdp,
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 36/66] libgfs2: eliminate gfs1_rindex_read
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (34 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 35/66] libgfs2: move block_map functions to fsck.gfs2 rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 37/66] libgfs2: combine ri_update and gfs1_ri_update rpeterso
                   ` (29 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

Now that function rindex_read is able to handle gfs1 file reading,
this patch eliminates the gfs1-specific function gfs1_rindex_read.

rhbz#675723
---
 gfs2/edit/hexedit.c |   13 +++-------
 gfs2/libgfs2/gfs1.c |   62 +-------------------------------------------------
 2 files changed, 6 insertions(+), 69 deletions(-)

diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index 903f169..abb8ef0 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -1756,7 +1756,7 @@ static int block_has_extended_info(void)
 /* ------------------------------------------------------------------------ */
 static void read_superblock(int fd)
 {
-	int count;
+	int count, sane;
 
 	sbd1 = (struct gfs_sb *)&sbd.sd_sb;
 	ioctl(fd, BLKFLSBUF, 0);
@@ -1809,11 +1809,7 @@ static void read_superblock(int fd)
 		sbd.sd_diptrs = (sbd.bsize - sizeof(struct gfs_dinode)) /
 			sizeof(uint64_t);
 		sbd.md.riinode = inode_read(&sbd, sbd1->sb_rindex_di.no_addr);
-		sbd.fssize = sbd.device.length;
-		gfs1_rindex_read(&sbd, 0, &count);
 	} else {
-		int sane;
-
 		sbd.sd_inptrs = (sbd.bsize - sizeof(struct gfs2_meta_header)) /
 			sizeof(uint64_t);
 		sbd.sd_diptrs = (sbd.bsize - sizeof(struct gfs2_dinode)) /
@@ -1821,11 +1817,10 @@ static void read_superblock(int fd)
 		sbd.master_dir = inode_read(&sbd,
 					    sbd.sd_sb.sb_master_dir.no_addr);
 		gfs2_lookupi(sbd.master_dir, "rindex", 6, &sbd.md.riinode);
-		sbd.fssize = sbd.device.length;
-		if (sbd.md.riinode) /* If we found the rindex */
-			rindex_read(&sbd, 0, &count, &sane);
 	}
-
+	sbd.fssize = sbd.device.length;
+	if (sbd.md.riinode) /* If we found the rindex */
+		rindex_read(&sbd, 0, &count, &sane);
 }
 
 /* ------------------------------------------------------------------------ */
diff --git a/gfs2/libgfs2/gfs1.c b/gfs2/libgfs2/gfs1.c
index 2ace124..076f4d0 100644
--- a/gfs2/libgfs2/gfs1.c
+++ b/gfs2/libgfs2/gfs1.c
@@ -160,65 +160,6 @@ void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
 }
 
 /**
- * gfs1_rindex_read - read in the rg index file
- *                  Stolen from libgfs2/super.c, but modified to handle gfs1.
- * @sdp: the incore superblock pointer
- * fd: optional file handle for rindex file (if meta_fs file system is mounted)
- *     (if fd is <= zero, it will read from raw device)
- * @count1: return count of the rgs.
- *
- * Returns: 0 on success, -1 on failure
- */
-int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1)
-{
-	unsigned int rg;
-	int error;
-	struct gfs2_rindex buf;
-	struct rgrp_list *rgd, *prev_rgd;
-	uint64_t prev_length = 0;
-
-	*count1 = 0;
-	prev_rgd = NULL;
-	for (rg = 0; ; rg++) {
-		if (fd > 0)
-			error = read(fd, &buf, sizeof(struct gfs2_rindex));
-		else
-			error = gfs2_readi(sdp->md.riinode, (char *)&buf,
-					   (rg * sizeof(struct gfs2_rindex)),
-					   sizeof(struct gfs2_rindex));
-		if (!error)
-			break;
-		if (error != sizeof(struct gfs2_rindex))
-			return -1;
-
-		rgd = (struct rgrp_list *)malloc(sizeof(struct rgrp_list));
-		if (!rgd) {
-			log_crit("Cannot allocate memory for rindex.\n");
-			exit(-1);
-		}
-		memset(rgd, 0, sizeof(struct rgrp_list));
-		osi_list_add_prev(&rgd->list, &sdp->rglist);
-
-		gfs2_rindex_in(&rgd->ri, (char *)&buf);
-
-		rgd->start = rgd->ri.ri_addr;
-		if (prev_rgd) {
-			prev_length = rgd->start - prev_rgd->start;
-			prev_rgd->length = prev_length;
-		}
-
-		if(gfs2_compute_bitstructs(sdp, rgd))
-			return -1;
-
-		(*count1)++;
-		prev_rgd = rgd;
-	}
-	if (prev_rgd)
-		prev_rgd->length = prev_length;
-	return 0;
-}
-
-/**
  * gfs1_ri_update - attach rgrps to the super block
  *                  Stolen from libgfs2/super.c, but modified to handle gfs1.
  * @sdp:
@@ -236,8 +177,9 @@ int gfs1_ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int quiet)
 	int count1 = 0, count2 = 0;
 	uint64_t errblock = 0;
 	uint64_t rmax = 0;
+	int sane;
 
-	if (gfs1_rindex_read(sdp, fd, &count1))
+	if (rindex_read(sdp, fd, &count1, &sane))
 	    goto fail;
 	for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
 		rgd = osi_list_entry(tmp, struct rgrp_list, list);
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 37/66] libgfs2: combine ri_update and gfs1_ri_update
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (35 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 36/66] libgfs2: eliminate gfs1_rindex_read rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 38/66] libgfs2: combine gfs_inode_read and gfs_inode_get rpeterso
                   ` (28 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

Since gfs1_ri_update is nearly identical to ri_update, I decided to
combine the main logic into a common function.  That simplifies the
code and if one gets fixed, they both get fixed automatically.

rhbz#675723
---
 gfs2/libgfs2/gfs1.c  |   49 -------------------------------------------------
 gfs2/libgfs2/super.c |   33 ++++++++++++++++++++++++++++++---
 2 files changed, 30 insertions(+), 52 deletions(-)

diff --git a/gfs2/libgfs2/gfs1.c b/gfs2/libgfs2/gfs1.c
index 076f4d0..3e314ce 100644
--- a/gfs2/libgfs2/gfs1.c
+++ b/gfs2/libgfs2/gfs1.c
@@ -159,55 +159,6 @@ void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
 	free(mp);
 }
 
-/**
- * gfs1_ri_update - attach rgrps to the super block
- *                  Stolen from libgfs2/super.c, but modified to handle gfs1.
- * @sdp:
- *
- * Given the rgrp index inode, link in all rgrps into the super block
- * and be sure that they can be read.
- *
- * Returns: 0 on success, -1 on failure.
- */
-int gfs1_ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int quiet)
-{
-	struct rgrp_list *rgd;
-	struct gfs2_rindex *ri;
-	osi_list_t *tmp;
-	int count1 = 0, count2 = 0;
-	uint64_t errblock = 0;
-	uint64_t rmax = 0;
-	int sane;
-
-	if (rindex_read(sdp, fd, &count1, &sane))
-	    goto fail;
-	for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
-		rgd = osi_list_entry(tmp, struct rgrp_list, list);
-		errblock = gfs2_rgrp_read(sdp, rgd);
-		if (errblock)
-			return errblock;
-		count2++;
-		if (!quiet && count2 % 100 == 0) {
-			printf(".");
-			fflush(stdout);
-		}
-		ri = &rgd->ri;
-		if (ri->ri_data0 + ri->ri_data - 1 > rmax)
-			rmax = ri->ri_data0 + ri->ri_data - 1;
-	}
-
-	sdp->fssize = rmax;
-	*rgcount = count1;
-	if (count1 != count2)
-		goto fail;
-
-	return 0;
-
- fail:
-	gfs2_rgrp_free(&sdp->rglist);
-	return -1;
-}
-
 /* ------------------------------------------------------------------------ */
 /* gfs_dinode_in */
 /* ------------------------------------------------------------------------ */
diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c
index 0fac740..27f6c2c 100644
--- a/gfs2/libgfs2/super.c
+++ b/gfs2/libgfs2/super.c
@@ -223,7 +223,8 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *sane)
  *
  * Returns: 0 on success, -1 on failure.
  */
-int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int *sane)
+static int __ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int *sane,
+		       int quiet)
 {
 	struct rgrp_list *rgd;
 	struct gfs2_rindex *ri;
@@ -233,16 +234,20 @@ int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int *sane)
 	uint64_t rmax = 0;
 
 	if (rindex_read(sdp, fd, &count1, sane))
-	    goto fail;
+		goto fail;
 	for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
 		rgd = osi_list_entry(tmp, struct rgrp_list, list);
 		errblock = gfs2_rgrp_read(sdp, rgd);
 		if (errblock)
 			return errblock;
+		count2++;
+		if (!quiet && count2 % 100 == 0) {
+			printf(".");
+			fflush(stdout);
+		}
 		ri = &rgd->ri;
 		if (ri->ri_data0 + ri->ri_data - 1 > rmax)
 			rmax = ri->ri_data0 + ri->ri_data - 1;
-		count2++;
 	}
 
 	sdp->fssize = rmax;
@@ -257,6 +262,28 @@ int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int *sane)
 	return -1;
 }
 
+int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int *sane)
+{
+	return __ri_update(sdp, fd, rgcount, sane, 1);
+}
+
+/**
+ * gfs1_ri_update - attach rgrps to the super block
+ *                  Stolen from libgfs2/super.c, but modified to handle gfs1.
+ * @sdp:
+ *
+ * Given the rgrp index inode, link in all rgrps into the super block
+ * and be sure that they can be read.
+ *
+ * Returns: 0 on success, -1 on failure.
+ */
+int gfs1_ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int quiet)
+{
+	int sane;
+
+	return __ri_update(sdp, fd, rgcount, &sane, quiet);
+}
+
 int write_sb(struct gfs2_sbd *sbp)
 {
 	struct gfs2_buffer_head *bh;
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 38/66] libgfs2: combine gfs_inode_read and gfs_inode_get
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (36 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 37/66] libgfs2: combine ri_update and gfs1_ri_update rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 39/66] libgfs2: move gfs1 functions from edit to libgfs2 rpeterso
                   ` (27 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

Functions gfs_inode_read and gfs_inode_get were nearly identical.
They did the same exact thing, but one operated on a buffer passed in
while the other read the buffer from the media.  This patch combines
the two into a common function and two replacement stubs.

rhbz#675723
---
 gfs2/libgfs2/gfs1.c |   57 +++++++++++++-------------------------------------
 1 files changed, 15 insertions(+), 42 deletions(-)

diff --git a/gfs2/libgfs2/gfs1.c b/gfs2/libgfs2/gfs1.c
index 3e314ce..fb4acab 100644
--- a/gfs2/libgfs2/gfs1.c
+++ b/gfs2/libgfs2/gfs1.c
@@ -191,8 +191,9 @@ static void gfs_dinode_in(struct gfs_dinode *di, struct gfs2_buffer_head *bh)
 	di->di_eattr = be64_to_cpu(str->di_eattr);
 }
 
-struct gfs2_inode *gfs_inode_get(struct gfs2_sbd *sdp,
-				 struct gfs2_buffer_head *bh)
+static struct gfs2_inode *__gfs_inode_get(struct gfs2_sbd *sdp,
+					  struct gfs2_buffer_head *bh,
+					  uint64_t di_addr)
 {
 	struct gfs_dinode gfs1_dinode;
 	struct gfs2_inode *ip;
@@ -203,6 +204,11 @@ struct gfs2_inode *gfs_inode_get(struct gfs2_sbd *sdp,
 		exit(-1);
 	}
 
+	ip->bh_owned = 0;
+	if (!bh) {
+		bh = bread(sdp, di_addr);
+		ip->bh_owned = 1;
+	}
 	gfs_dinode_in(&gfs1_dinode, bh);
 	memcpy(&ip->i_di.di_header, &gfs1_dinode.di_header,
 	       sizeof(struct gfs2_meta_header));
@@ -230,49 +236,16 @@ struct gfs2_inode *gfs_inode_get(struct gfs2_sbd *sdp,
 	ip->i_di.di_eattr = gfs1_dinode.di_eattr;
 	ip->i_bh = bh;
 	ip->i_sbd = sdp;
-	ip->bh_owned = 0;
 	return ip;
 }
 
-struct gfs2_inode *gfs_inode_read(struct gfs2_sbd *sdp, uint64_t di_addr)
+struct gfs2_inode *gfs_inode_get(struct gfs2_sbd *sdp,
+				 struct gfs2_buffer_head *bh)
 {
-	struct gfs_dinode gfs1_dinode;
-	struct gfs2_inode *ip;
-
-	ip = calloc(1, sizeof(struct gfs2_inode));
-	if (ip == NULL) {
-		fprintf(stderr, "Out of memory in %s\n", __FUNCTION__);
-		exit(-1);
-	}
-
-	ip->i_bh = bread(sdp, di_addr);
-	gfs_dinode_in(&gfs1_dinode, ip->i_bh);
-	memcpy(&ip->i_di.di_header, &gfs1_dinode.di_header,
-	       sizeof(struct gfs2_meta_header));
-	memcpy(&ip->i_di.di_num, &gfs1_dinode.di_num,
-	       sizeof(struct gfs2_inum));
-	ip->i_di.di_mode = gfs1_dinode.di_mode;
-	ip->i_di.di_uid = gfs1_dinode.di_uid;
-	ip->i_di.di_gid = gfs1_dinode.di_gid;
-	ip->i_di.di_nlink = gfs1_dinode.di_nlink;
-	ip->i_di.di_size = gfs1_dinode.di_size;
-	ip->i_di.di_blocks = gfs1_dinode.di_blocks;
-	ip->i_di.di_atime = gfs1_dinode.di_atime;
-	ip->i_di.di_mtime = gfs1_dinode.di_mtime;
-	ip->i_di.di_ctime = gfs1_dinode.di_ctime;
-	ip->i_di.di_major = gfs1_dinode.di_major;
-	ip->i_di.di_minor = gfs1_dinode.di_minor;
-	ip->i_di.di_goal_data = gfs1_dinode.di_goal_dblk;
-	ip->i_di.di_goal_meta = gfs1_dinode.di_goal_mblk;
-	ip->i_di.di_flags = gfs1_dinode.di_flags;
-	ip->i_di.di_payload_format = gfs1_dinode.di_payload_format;
-	ip->i_di.__pad1 = gfs1_dinode.di_type;
-	ip->i_di.di_height = gfs1_dinode.di_height;
-	ip->i_di.di_depth = gfs1_dinode.di_depth;
-	ip->i_di.di_entries = gfs1_dinode.di_entries;
-	ip->i_di.di_eattr = gfs1_dinode.di_eattr;
-	ip->i_sbd = sdp;
-	ip->bh_owned = 1;
-	return ip;
+	return __gfs_inode_get(sdp, bh, 0);
 }
 
+struct gfs2_inode *gfs_inode_read(struct gfs2_sbd *sdp, uint64_t di_addr)
+{
+	return __gfs_inode_get(sdp, NULL, di_addr);
+}
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 39/66] libgfs2: move gfs1 functions from edit to libgfs2
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (37 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 38/66] libgfs2: combine gfs_inode_read and gfs_inode_get rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 40/66] gfs2_edit savemeta: save_inode_data backward for gfs1 rpeterso
                   ` (26 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch moves some gfs1-specific functions from gfs2_edit to
libgfs2 so that other utils can eventually operate on gfs1 file
systems.

rhbz#675723
---
 gfs2/edit/hexedit.c    |   47 -------------------------------------------
 gfs2/edit/hexedit.h    |    1 -
 gfs2/libgfs2/gfs1.c    |   52 ++++++++++++++++++++++++++++++++++++++++++++++++
 gfs2/libgfs2/libgfs2.h |    3 ++
 4 files changed, 55 insertions(+), 48 deletions(-)

diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index abb8ef0..a2ccc60 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -1498,40 +1498,6 @@ static uint64_t find_rgrp_block(struct gfs2_inode *dif, int rg)
 }
 
 /* ------------------------------------------------------------------------ */
-/* gfs_rgrp_in - Read in a resource group header                            */
-/* ------------------------------------------------------------------------ */
-void gfs_rgrp_in(struct gfs_rgrp *rgrp, struct gfs2_buffer_head *rbh)
-{
-	struct gfs_rgrp *str = (struct gfs_rgrp *)rbh->b_data;
-
-	gfs2_meta_header_in(&rgrp->rg_header, rbh);
-	rgrp->rg_flags = be32_to_cpu(str->rg_flags);
-	rgrp->rg_free = be32_to_cpu(str->rg_free);
-	rgrp->rg_useddi = be32_to_cpu(str->rg_useddi);
-	rgrp->rg_freedi = be32_to_cpu(str->rg_freedi);
-	gfs2_inum_in(&rgrp->rg_freedi_list, (char *)&str->rg_freedi_list);
-	rgrp->rg_usedmeta = be32_to_cpu(str->rg_usedmeta);
-	rgrp->rg_freemeta = be32_to_cpu(str->rg_freemeta);
-}
-
-/* ------------------------------------------------------------------------ */
-/* gfs_rgrp_out */
-/* ------------------------------------------------------------------------ */
-static void gfs_rgrp_out(struct gfs_rgrp *rgrp, struct gfs2_buffer_head *rbh)
-{
-	struct gfs_rgrp *str = (struct gfs_rgrp *)rbh->b_data;
-
-	gfs2_meta_header_out(&rgrp->rg_header, rbh);
-	str->rg_flags = cpu_to_be32(rgrp->rg_flags);
-	str->rg_free = cpu_to_be32(rgrp->rg_free);
-	str->rg_useddi = cpu_to_be32(rgrp->rg_useddi);
-	str->rg_freedi = cpu_to_be32(rgrp->rg_freedi);
-	gfs2_inum_out(&rgrp->rg_freedi_list, (char *)&str->rg_freedi_list);
-	str->rg_usedmeta = cpu_to_be32(rgrp->rg_usedmeta);
-	str->rg_freemeta = cpu_to_be32(rgrp->rg_freemeta);
-}
-
-/* ------------------------------------------------------------------------ */
 /* gfs_rgrp_print - print a gfs1 resource group                             */
 /* ------------------------------------------------------------------------ */
 void gfs_rgrp_print(struct gfs_rgrp *rg)
@@ -1622,19 +1588,6 @@ static void set_rgrp_flags(int rgnum, uint32_t new_flags, int modify, int full)
 }
 
 /* ------------------------------------------------------------------------ */
-/* gfs_jindex_in - read in a gfs1 jindex structure.                         */
-/* ------------------------------------------------------------------------ */
-void gfs_jindex_in(struct gfs_jindex *jindex, char *jbuf)
-{
-        struct gfs_jindex *str = (struct gfs_jindex *) jbuf;
-
-        jindex->ji_addr = be64_to_cpu(str->ji_addr);
-        jindex->ji_nsegment = be32_to_cpu(str->ji_nsegment);
-        jindex->ji_pad = be32_to_cpu(str->ji_pad);
-        memcpy(jindex->ji_reserved, str->ji_reserved, 64);
-}
-
-/* ------------------------------------------------------------------------ */
 /* has_indirect_blocks                                                      */
 /* ------------------------------------------------------------------------ */
 int has_indirect_blocks(void)
diff --git a/gfs2/edit/hexedit.h b/gfs2/edit/hexedit.h
index f7b539e..07125bd 100644
--- a/gfs2/edit/hexedit.h
+++ b/gfs2/edit/hexedit.h
@@ -221,7 +221,6 @@ extern int display(int identify_only);
 extern uint64_t check_keywords(const char *kword);
 extern uint64_t masterblock(const char *fn);
 extern void gfs_rgrp_print(struct gfs_rgrp *rg);
-extern void gfs_rgrp_in(struct gfs_rgrp *rgrp, struct gfs2_buffer_head *rbh);
 extern int has_indirect_blocks(void);
 
 #endif /* __HEXVIEW_DOT_H__ */
diff --git a/gfs2/libgfs2/gfs1.c b/gfs2/libgfs2/gfs1.c
index fb4acab..5b8d4ed 100644
--- a/gfs2/libgfs2/gfs1.c
+++ b/gfs2/libgfs2/gfs1.c
@@ -249,3 +249,55 @@ struct gfs2_inode *gfs_inode_read(struct gfs2_sbd *sdp, uint64_t di_addr)
 {
 	return __gfs_inode_get(sdp, NULL, di_addr);
 }
+
+/* ------------------------------------------------------------------------ */
+/* gfs_jindex_in - read in a gfs1 jindex structure.                         */
+/* ------------------------------------------------------------------------ */
+void gfs_jindex_in(struct gfs_jindex *jindex, char *jbuf)
+{
+	struct gfs_jindex *str = (struct gfs_jindex *) jbuf;
+
+	jindex->ji_addr = be64_to_cpu(str->ji_addr);
+	jindex->ji_nsegment = be32_to_cpu(str->ji_nsegment);
+	jindex->ji_pad = be32_to_cpu(str->ji_pad);
+	memcpy(jindex->ji_reserved, str->ji_reserved, 64);
+}
+
+/* ------------------------------------------------------------------------ */
+/* gfs_rgrp_in - Read in a resource group header                            */
+/* ------------------------------------------------------------------------ */
+void gfs_rgrp_in(struct gfs_rgrp *rgrp, struct gfs2_buffer_head *rbh)
+{
+	struct gfs_rgrp *str = (struct gfs_rgrp *)rbh->b_data;
+
+	gfs2_meta_header_in(&rgrp->rg_header, rbh);
+	rgrp->rg_flags = be32_to_cpu(str->rg_flags);
+	rgrp->rg_free = be32_to_cpu(str->rg_free);
+	rgrp->rg_useddi = be32_to_cpu(str->rg_useddi);
+	rgrp->rg_freedi = be32_to_cpu(str->rg_freedi);
+	gfs2_inum_in(&rgrp->rg_freedi_list, (char *)&str->rg_freedi_list);
+	rgrp->rg_usedmeta = be32_to_cpu(str->rg_usedmeta);
+	rgrp->rg_freemeta = be32_to_cpu(str->rg_freemeta);
+
+	memcpy(rgrp->rg_reserved, str->rg_reserved, 64);
+}
+
+/* ------------------------------------------------------------------------ */
+/* gfs_rgrp_out */
+/* ------------------------------------------------------------------------ */
+void gfs_rgrp_out(struct gfs_rgrp *rgrp, struct gfs2_buffer_head *rbh)
+{
+	struct gfs_rgrp *str = (struct gfs_rgrp *)rbh->b_data;
+
+	gfs2_meta_header_out(&rgrp->rg_header, rbh);
+	str->rg_flags = cpu_to_be32(rgrp->rg_flags);
+	str->rg_free = cpu_to_be32(rgrp->rg_free);
+	str->rg_useddi = cpu_to_be32(rgrp->rg_useddi);
+	str->rg_freedi = cpu_to_be32(rgrp->rg_freedi);
+	gfs2_inum_out(&rgrp->rg_freedi_list, (char *)&str->rg_freedi_list);
+	str->rg_usedmeta = cpu_to_be32(rgrp->rg_usedmeta);
+	str->rg_freemeta = cpu_to_be32(rgrp->rg_freemeta);
+
+	memcpy(str->rg_reserved, rgrp->rg_reserved, 64);
+	bmodified(rbh);
+}
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index a2e1523..22c6552 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -589,6 +589,9 @@ extern struct gfs2_inode *gfs_inode_get(struct gfs2_sbd *sdp,
 					struct gfs2_buffer_head *bh);
 extern struct gfs2_inode *gfs_inode_read(struct gfs2_sbd *sdp,
 					 uint64_t di_addr);
+extern void gfs_jindex_in(struct gfs_jindex *jindex, char *buf);
+extern void gfs_rgrp_in(struct gfs_rgrp *rg, struct gfs2_buffer_head *bh);
+extern void gfs_rgrp_out(struct gfs_rgrp *rg, struct gfs2_buffer_head *bh);
 
 /* gfs2_log.c */
 struct gfs2_options {
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 40/66] gfs2_edit savemeta: save_inode_data backward for gfs1
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (38 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 39/66] libgfs2: move gfs1 functions from edit to libgfs2 rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 41/66] libgfs2: expand capabilities to operate on gfs1 rpeterso
                   ` (25 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

The logic in "gfs2_edit savemeta" was wrong for saving inode blocks.
This patch fixes the logic.

rhbz#675723
---
 gfs2/edit/savemeta.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index 665af07..8ccbf8a 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -121,9 +121,9 @@ static int get_gfs_struct_info(struct gfs2_buffer_head *lbh, int *block_type,
 		break;
 	case GFS2_METATYPE_DI:   /* 4 (disk inode) */
 		if (sbd.gfs1)
-			inode = inode_get(&sbd, lbh);
-		else
 			inode = gfs_inode_get(&sbd, lbh);
+		else
+			inode = inode_get(&sbd, lbh);
 		if (S_ISDIR(inode->i_di.di_mode) ||
 		     (sbd.gfs1 && inode->i_di.__pad1 == GFS_FILE_DIR))
 			*gstruct_len = sbd.bsize;
@@ -455,9 +455,9 @@ static void save_inode_data(struct metafd *mfd)
 		osi_list_init(&metalist[i]);
 	metabh = bread(&sbd, block);
 	if (sbd.gfs1)
-		inode = inode_get(&sbd, metabh);
-	else
 		inode = gfs_inode_get(&sbd, metabh);
+	else
+		inode = inode_get(&sbd, metabh);
 	height = inode->i_di.di_height;
 	/* If this is a user inode, we don't follow to the file height.
 	   We stop one level less.  That way we save off the indirect
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 41/66] libgfs2: expand capabilities to operate on gfs1
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (39 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 40/66] gfs2_edit savemeta: save_inode_data backward for gfs1 rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 42/66] fsck.gfs2: Combine block and char device inode types rpeterso
                   ` (24 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch expands many of the libgfs2 functions so that they may
operate on gfs1 file systems, depending on the sdp->gfs1 variable.

rhbz#675723
---
 gfs2/libgfs2/fs_ops.c  |  113 +++++++++++++++++++++++++++++++++++--------
 gfs2/libgfs2/gfs1.c    |  126 ++++++++++++++++++++++++++++++++++++++++++++++++
 gfs2/libgfs2/libgfs2.h |   17 ++++++-
 gfs2/libgfs2/ondisk.c  |   10 +++-
 gfs2/libgfs2/rgrp.c    |    9 ++-
 5 files changed, 248 insertions(+), 27 deletions(-)

diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index 6ffee9d..e99cc2a 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -177,7 +177,10 @@ found:
 	rg->rg_free--;
 
 	bmodified(bh);
-	gfs2_rgrp_out(rg, rl->bh[0]);
+	if (sdp->gfs1)
+		gfs_rgrp_out((struct gfs_rgrp *)rg, rl->bh[0]);
+	else
+		gfs2_rgrp_out(rg, rl->bh[0]);
 
 	sdp->blks_alloced++;
 	return ri->ri_data0 + bn;
@@ -231,7 +234,7 @@ void unstuff_dinode(struct gfs2_inode *ip)
 	struct gfs2_sbd *sdp = ip->i_sbd;
 	struct gfs2_buffer_head *bh;
 	uint64_t block = 0;
-	int isdir = !!(S_ISDIR(ip->i_di.di_mode));
+	int isdir = S_ISDIR(ip->i_di.di_mode) || is_gfs_dir(&ip->i_di);
 
 	if (ip->i_di.di_size) {
 		if (isdir) {
@@ -828,6 +831,8 @@ void gfs2_get_leaf_nr(struct gfs2_inode *dip, uint32_t lindex,
 	uint64_t leaf_no;
 	int count;
 
+	if (dip->i_sbd->gfs1)
+		return gfs_get_leaf_nr(dip, lindex, leaf_out);
 	count = gfs2_readi(dip, (char *)&leaf_no, lindex * sizeof(uint64_t),
 			   sizeof(uint64_t));
 	if (count != sizeof(uint64_t))
@@ -841,6 +846,10 @@ void gfs2_put_leaf_nr(struct gfs2_inode *dip, uint32_t inx, uint64_t leaf_out)
 	uint64_t leaf_no;
 	int count;
 
+	if (dip->i_sbd->gfs1) {
+		gfs_put_leaf_nr(dip, inx, leaf_out);
+		return;
+	}
 	leaf_no = cpu_to_be64(leaf_out);
 	count = gfs2_writei(dip, (char *)&leaf_no, inx * sizeof(uint64_t),
 			    sizeof(uint64_t));
@@ -891,8 +900,12 @@ static void dir_split_leaf(struct gfs2_inode *dip, uint32_t lindex,
 	for (x = 0; x < half_len; x++)
 		lp[x] = cpu_to_be64(bn);
 
-	count = gfs2_writei(dip, (char *)lp, start * sizeof(uint64_t),
-			    half_len * sizeof(uint64_t));
+	if (dip->i_sbd->gfs1)
+		count = gfs1_writei(dip, (char *)lp, start * sizeof(uint64_t),
+				    half_len * sizeof(uint64_t));
+	else
+		count = gfs2_writei(dip, (char *)lp, start * sizeof(uint64_t),
+				    half_len * sizeof(uint64_t));
 	if (count != half_len * sizeof(uint64_t))
 		die("dir_split_leaf (2)\n");
 
@@ -985,8 +998,14 @@ static void dir_double_exhash(struct gfs2_inode *dip)
 			*to++ = *from;
 		}
 
-		count = gfs2_writei(dip, (char *)buf + sdp->sd_hash_bsize,
-				    block * sdp->bsize, sdp->bsize);
+		if (sdp->gfs1)
+			count = gfs1_writei(dip, (char *)buf +
+					    sdp->sd_hash_bsize,
+					    block * sdp->bsize, sdp->bsize);
+		else
+			count = gfs2_writei(dip, (char *)buf +
+					    sdp->sd_hash_bsize,
+					    block * sdp->bsize, sdp->bsize);
 		if (count != sdp->bsize)
 			die("dir_double_exhash (2)\n");
 
@@ -1235,13 +1254,21 @@ void dir_add(struct gfs2_inode *dip, const char *filename, int len,
 		dir_l_add(dip, filename, len, inum, type);
 }
 
-struct gfs2_buffer_head *init_dinode(struct gfs2_sbd *sdp,
-				     struct gfs2_inum *inum, unsigned int mode,
-				     uint32_t flags, struct gfs2_inum *parent)
+static struct gfs2_buffer_head *__init_dinode(struct gfs2_sbd *sdp,
+					      struct gfs2_inum *inum,
+					      unsigned int mode,
+					      uint32_t flags,
+					      struct gfs2_inum *parent,
+					      int gfs1)
 {
 	struct gfs2_buffer_head *bh;
 	struct gfs2_dinode di;
+	int is_dir;
 
+	if (gfs1)
+		is_dir = (IF2DT(mode) == GFS_FILE_DIR);
+	else
+		is_dir = S_ISDIR(mode);
 	bh = bget(sdp, inum->no_addr);
 
 	memset(&di, 0, sizeof(struct gfs2_dinode));
@@ -1256,7 +1283,7 @@ struct gfs2_buffer_head *init_dinode(struct gfs2_sbd *sdp,
 	di.di_goal_meta = di.di_goal_data = bh->b_blocknr;
 	di.di_flags = flags;
 
-	if (S_ISDIR(mode)) {
+	if (is_dir) {
 		struct gfs2_dirent de1, de2;
 
 		memset(&de1, 0, sizeof(struct gfs2_dirent));
@@ -1264,14 +1291,14 @@ struct gfs2_buffer_head *init_dinode(struct gfs2_sbd *sdp,
 		de1.de_hash = gfs2_disk_hash(".", 1);
 		de1.de_rec_len = GFS2_DIRENT_SIZE(1);
 		de1.de_name_len = 1;
-		de1.de_type = IF2DT(S_IFDIR);
+		de1.de_type = (gfs1 ? GFS_FILE_DIR : IF2DT(S_IFDIR));
 
 		memset(&de2, 0, sizeof(struct gfs2_dirent));
 		de2.de_inum = *parent;
 		de2.de_hash = gfs2_disk_hash("..", 2);
 		de2.de_rec_len = sdp->bsize - sizeof(struct gfs2_dinode) - de1.de_rec_len;
 		de2.de_name_len = 2;
-		de2.de_type = IF2DT(S_IFDIR);
+		de2.de_type = (gfs1 ? GFS_FILE_DIR : IF2DT(S_IFDIR));
 
 		gfs2_dirent_out(&de1, bh->b_data + sizeof(struct gfs2_dinode));
 		memcpy(bh->b_data +
@@ -1297,30 +1324,56 @@ struct gfs2_buffer_head *init_dinode(struct gfs2_sbd *sdp,
 	return bh;
 }
 
-struct gfs2_inode *createi(struct gfs2_inode *dip, const char *filename,
-			   unsigned int mode, uint32_t flags)
+struct gfs2_buffer_head *init_dinode(struct gfs2_sbd *sdp,
+				     struct gfs2_inum *inum,
+				     unsigned int mode, uint32_t flags,
+				     struct gfs2_inum *parent)
+{
+	return __init_dinode(sdp, inum, mode, flags, parent, 0);
+}
+
+struct gfs2_buffer_head *init_gfs_dinode(struct gfs2_sbd *sdp,
+					 struct gfs2_inum *inum,
+					 unsigned int mode, uint32_t flags,
+					 struct gfs2_inum *parent)
+{
+	return __init_dinode(sdp, inum, mode, flags, parent, 1);
+}
+
+static struct gfs2_inode *__createi(struct gfs2_inode *dip,
+				    const char *filename, unsigned int mode,
+				    uint32_t flags, int if_gfs1)
 {
 	struct gfs2_sbd *sdp = dip->i_sbd;
 	uint64_t bn;
 	struct gfs2_inum inum;
 	struct gfs2_buffer_head *bh;
 	struct gfs2_inode *ip;
+	int is_dir;
 
 	gfs2_lookupi(dip, filename, strlen(filename), &ip);
 	if (!ip) {
 		bn = dinode_alloc(sdp);
 
-		inum.no_formal_ino = sdp->md.next_inum++;
+		if (if_gfs1)
+			inum.no_formal_ino = bn;
+		else
+			inum.no_formal_ino = sdp->md.next_inum++;
 		inum.no_addr = bn;
 
 		dir_add(dip, filename, strlen(filename), &inum, IF2DT(mode));
 
-		if(S_ISDIR(mode)) {
+		if (if_gfs1)
+			is_dir = (IF2DT(mode) == GFS_FILE_DIR);
+		else
+			is_dir = S_ISDIR(mode);
+		if (is_dir) {
 			bmodified(dip->i_bh);
 			dip->i_di.di_nlink++;
 		}
 
-		bh = init_dinode(sdp, &inum, mode, flags, &dip->i_di.di_num);
+		bh = __init_dinode(sdp, &inum, mode, flags, &dip->i_di.di_num,
+				   if_gfs1);
 		ip = inode_get(sdp, bh);
 		bmodified(bh);
 	}
@@ -1328,6 +1381,18 @@ struct gfs2_inode *createi(struct gfs2_inode *dip, const char *filename,
 	return ip;
 }
 
+struct gfs2_inode *createi(struct gfs2_inode *dip, const char *filename,
+			   unsigned int mode, uint32_t flags)
+{
+	return __createi(dip, filename, mode, flags, 0);
+}
+
+struct gfs2_inode *gfs_createi(struct gfs2_inode *dip, const char *filename,
+			   unsigned int mode, uint32_t flags)
+{
+	return __createi(dip, filename, mode, flags, 1);
+}
+
 /**
  * gfs2_filecmp - Compare two filenames
  * @file1: The first filename
@@ -1541,7 +1606,7 @@ int dir_search(struct gfs2_inode *dip, const char *filename, int len,
 {
 	int error;
 
-	if(!S_ISDIR(dip->i_di.di_mode))
+	if(!S_ISDIR(dip->i_di.di_mode) && !is_gfs_dir(&dip->i_di))
 		return -1;
 
 	if (dip->i_di.di_flags & GFS2_DIF_EXHASH)
@@ -1627,7 +1692,7 @@ int gfs2_dirent_del(struct gfs2_inode *dip, const char *filename, int len)
 {
 	int error;
 
-	if(!S_ISDIR(dip->i_di.di_mode))
+	if(!S_ISDIR(dip->i_di.di_mode) && !is_gfs_dir(&dip->i_di))
 		return -1;
 
 	if (dip->i_di.di_flags & GFS2_DIF_EXHASH)
@@ -1684,7 +1749,10 @@ void gfs2_free_block(struct gfs2_sbd *sdp, uint64_t block)
 	if (rgd) {
 		gfs2_set_bitmap(sdp, block, GFS2_BLKST_FREE);
 		rgd->rg.rg_free++; /* adjust the free count */
-		gfs2_rgrp_out(&rgd->rg, rgd->bh[0]); /* back to the buffer */
+		if (sdp->gfs1)
+			gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bh[0]);
+		else
+			gfs2_rgrp_out(&rgd->rg, rgd->bh[0]);
 		sdp->blks_alloced--;
 	}
 }
@@ -1748,7 +1816,10 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock)
 	rgd = gfs2_blk2rgrpd(sdp, diblock);
 	rgd->rg.rg_free++;
 	rgd->rg.rg_dinodes--; /* one less inode in use */
-	gfs2_rgrp_out(&rgd->rg, rgd->bh[0]);
+	if (sdp->gfs1)
+		gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bh[0]);
+	else
+		gfs2_rgrp_out(&rgd->rg, rgd->bh[0]);
 	sdp->dinodes_alloced--;
 	return 0;
 }
diff --git a/gfs2/libgfs2/gfs1.c b/gfs2/libgfs2/gfs1.c
index 5b8d4ed..d1e8ab8 100644
--- a/gfs2/libgfs2/gfs1.c
+++ b/gfs2/libgfs2/gfs1.c
@@ -4,6 +4,7 @@
 #include <string.h>
 #include <stdint.h>
 #include <inttypes.h>
+#include <time.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
@@ -31,6 +32,13 @@ gfs1_metapointer(struct gfs2_buffer_head *bh, unsigned int height,
 	return ((uint64_t *)(bh->b_data + head_size)) + mp->mp_list[height];
 }
 
+int is_gfs_dir(struct gfs2_dinode *dinode)
+{
+	if (dinode->__pad1 == GFS_FILE_DIR)
+		return 1;
+	return 0;
+}
+
 void gfs1_lookup_block(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
 		  unsigned int height, struct metapath *mp,
 		  int create, int *new, uint64_t *block)
@@ -159,6 +167,98 @@ void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
 	free(mp);
 }
 
+int gfs1_writei(struct gfs2_inode *ip, char *buf, uint64_t offset,
+		unsigned int size)
+{
+	struct gfs2_sbd *sdp = ip->i_sbd;
+	struct gfs2_buffer_head *bh;
+	uint64_t lblock, dblock;
+	uint32_t extlen = 0;
+	unsigned int amount;
+	int new;
+	int journaled = fs_is_jdata(ip);
+	const uint64_t start = offset;
+	int copied = 0;
+	int error = 0;
+
+	if (!size)
+		goto fail;  /*  Not really an error  */
+
+
+	if (!ip->i_di.di_height && /* stuffed */
+	    ((start + size) > (sdp->bsize - sizeof(struct gfs_dinode))))
+		unstuff_dinode(ip);
+
+	if (journaled) {
+		lblock = offset / sdp->sd_jbsize;
+		offset %= sdp->sd_jbsize;
+	} else {
+		lblock = offset >> sdp->sd_sb.sb_bsize_shift;
+		offset &= sdp->bsize - 1;
+	}
+
+	if (!ip->i_di.di_height) /* stuffed */
+		offset += sizeof(struct gfs_dinode);
+	else if (journaled)
+		offset += sizeof(struct gfs2_meta_header);
+
+	while (copied < size) {
+		amount = size - copied;
+		if (amount > sdp->bsize - offset)
+			amount = sdp->bsize - offset;
+
+		if (!extlen){
+			new = TRUE;
+			gfs1_block_map(ip, lblock, &new, &dblock, &extlen, 0);
+			if (!dblock)
+				return -1;
+		}
+
+		if (dblock == ip->i_di.di_num.no_addr)
+			bh = ip->i_bh;
+		else
+			bh = bread(sdp, dblock);
+
+		if (journaled && dblock != ip->i_di.di_num.no_addr ) {
+			struct gfs2_meta_header mh;
+
+			mh.mh_magic = GFS2_MAGIC;
+			mh.mh_type = GFS2_METATYPE_JD;
+			mh.mh_format = GFS2_FORMAT_JD;
+			gfs2_meta_header_out(&mh, bh);
+		}
+
+		memcpy(bh->b_data + offset, buf + copied, amount);
+		bmodified(bh);
+		if (bh != ip->i_bh)
+			brelse(bh);
+
+		copied += amount;
+		lblock++;
+		dblock++;
+		extlen--;
+
+		offset = (journaled) ? sizeof(struct gfs2_meta_header) : 0;
+	}
+
+ out:
+	if (ip->i_di.di_size < start + copied) {
+		bmodified(ip->i_bh);
+		ip->i_di.di_size = start + copied;
+	}
+	ip->i_di.di_mtime = ip->i_di.di_ctime = time(NULL);
+
+	gfs2_dinode_out(&ip->i_di, ip->i_bh);
+
+	return copied;
+
+ fail:
+	if (copied)
+		goto out;
+
+	return error;
+}
+
 /* ------------------------------------------------------------------------ */
 /* gfs_dinode_in */
 /* ------------------------------------------------------------------------ */
@@ -301,3 +401,29 @@ void gfs_rgrp_out(struct gfs_rgrp *rgrp, struct gfs2_buffer_head *rbh)
 	memcpy(str->rg_reserved, rgrp->rg_reserved, 64);
 	bmodified(rbh);
 }
+
+void gfs_get_leaf_nr(struct gfs2_inode *dip, uint32_t lindex,
+		     uint64_t *leaf_out)
+{
+	uint64_t leaf_no;
+	int count;
+
+	count = gfs2_readi(dip, (char *)&leaf_no, lindex * sizeof(uint64_t),
+			   sizeof(uint64_t));
+	if (count != sizeof(uint64_t))
+		die("gfs_get_leaf_nr:  Bad internal read.\n");
+
+	*leaf_out = be64_to_cpu(leaf_no);
+}
+
+void gfs_put_leaf_nr(struct gfs2_inode *dip, uint32_t inx, uint64_t leaf_out)
+{
+	uint64_t leaf_no;
+	int count;
+
+	leaf_no = cpu_to_be64(leaf_out);
+	count = gfs1_writei(dip, (char *)&leaf_no, inx * sizeof(uint64_t),
+			   sizeof(uint64_t));
+	if (count != sizeof(uint64_t))
+		die("gfs_put_leaf_nr:  Bad internal write.\n");
+}
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 22c6552..58442e8 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -366,8 +366,16 @@ extern struct gfs2_buffer_head *init_dinode(struct gfs2_sbd *sdp,
 					    struct gfs2_inum *inum,
 					    unsigned int mode, uint32_t flags,
 					    struct gfs2_inum *parent);
+extern struct gfs2_buffer_head *init_gfs_dinode(struct gfs2_sbd *sdp,
+						struct gfs2_inum *inum,
+						unsigned int mode,
+						uint32_t flags,
+						struct gfs2_inum *parent);
 extern struct gfs2_inode *createi(struct gfs2_inode *dip, const char *filename,
 				  unsigned int mode, uint32_t flags);
+extern struct gfs2_inode *gfs_createi(struct gfs2_inode *dip,
+				      const char *filename, unsigned int mode,
+				      uint32_t flags);
 extern void dirent2_del(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
 			struct gfs2_dirent *prev, struct gfs2_dirent *cur);
 extern int dir_search(struct gfs2_inode *dip, const char *filename, int len,
@@ -577,13 +585,15 @@ struct gfs_log_descriptor {
 	char ld_reserved[64];
 };
 
+extern int is_gfs_dir(struct gfs2_dinode *dinode);
 extern void gfs1_lookup_block(struct gfs2_inode *ip,
 			      struct gfs2_buffer_head *bh,
 			      unsigned int height, struct metapath *mp,
 			      int create, int *new, uint64_t *block);
 extern void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
 			   uint64_t *dblock, uint32_t *extlen, int prealloc);
-extern int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1);
+extern int gfs1_writei(struct gfs2_inode *ip, char *buf, uint64_t offset,
+		       unsigned int size);
 extern int gfs1_ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int quiet);
 extern struct gfs2_inode *gfs_inode_get(struct gfs2_sbd *sdp,
 					struct gfs2_buffer_head *bh);
@@ -592,6 +602,10 @@ extern struct gfs2_inode *gfs_inode_read(struct gfs2_sbd *sdp,
 extern void gfs_jindex_in(struct gfs_jindex *jindex, char *buf);
 extern void gfs_rgrp_in(struct gfs_rgrp *rg, struct gfs2_buffer_head *bh);
 extern void gfs_rgrp_out(struct gfs_rgrp *rg, struct gfs2_buffer_head *bh);
+extern void gfs_get_leaf_nr(struct gfs2_inode *dip, uint32_t lindex,
+			    uint64_t *leaf_out);
+extern void gfs_put_leaf_nr(struct gfs2_inode *dip, uint32_t inx,
+			    uint64_t leaf_out);
 
 /* gfs2_log.c */
 struct gfs2_options {
@@ -685,6 +699,7 @@ extern int clean_journal(struct gfs2_inode *ip, struct gfs2_log_header *head);
 /* rgrp.c */
 extern int gfs2_compute_bitstructs(struct gfs2_sbd *sdp, struct rgrp_list *rgd);
 extern struct rgrp_list *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, uint64_t blk);
+extern uint64_t __gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd);
 extern uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd);
 extern void gfs2_rgrp_relse(struct rgrp_list *rgd);
 extern void gfs2_rgrp_free(osi_list_t *rglist);
diff --git a/gfs2/libgfs2/ondisk.c b/gfs2/libgfs2/ondisk.c
index 351198a..507cebb 100644
--- a/gfs2/libgfs2/ondisk.c
+++ b/gfs2/libgfs2/ondisk.c
@@ -98,15 +98,20 @@ void gfs2_sb_in(struct gfs2_sb *sb, struct gfs2_buffer_head *bh)
 
 	CPIN_32(sb, str, sb_fs_format);
 	CPIN_32(sb, str, sb_multihost_format);
+	CPIN_32(sb, str, __pad0);                        /* gfs sb_flags */
 
 	CPIN_32(sb, str, sb_bsize);
 	CPIN_32(sb, str, sb_bsize_shift);
+	CPIN_32(sb, str, __pad1);                        /* gfs sb_seg_size */
 
 	gfs2_inum_in(&sb->sb_master_dir, (char *)&str->sb_master_dir);
 	gfs2_inum_in(&sb->sb_root_dir, (char *)&str->sb_root_dir);
 
 	CPIN_08(sb, str, sb_lockproto, GFS2_LOCKNAME_LEN);
 	CPIN_08(sb, str, sb_locktable, GFS2_LOCKNAME_LEN);
+	gfs2_inum_in(&sb->__pad2, (char *)&str->__pad2); /* gfs rindex */
+	gfs2_inum_in(&sb->__pad3, (char *)&str->__pad3); /* gfs quota */
+	gfs2_inum_in(&sb->__pad4, (char *)&str->__pad4); /* gfs license */
 #ifdef GFS2_HAS_UUID
 	CPIN_08(sb, str, sb_uuid, sizeof(sb->sb_uuid));
 #endif
@@ -233,7 +238,7 @@ void gfs2_rgrp_in(struct gfs2_rgrp *rg, struct gfs2_buffer_head *bh)
 	CPIN_32(rg, str, rg_free);
 	CPIN_32(rg, str, rg_dinodes);
 
-	CPIN_08(rg, str, rg_reserved, 36);
+	CPIN_08(rg, str, rg_reserved, 80);
 }
 
 void gfs2_rgrp_out(struct gfs2_rgrp *rg, struct gfs2_buffer_head *bh)
@@ -245,7 +250,7 @@ void gfs2_rgrp_out(struct gfs2_rgrp *rg, struct gfs2_buffer_head *bh)
 	CPOUT_32(rg, str, rg_free);
 	CPOUT_32(rg, str, rg_dinodes);
 
-	CPOUT_08(rg, str, rg_reserved, 36);
+	CPOUT_08(rg, str, rg_reserved, 80);
 	bmodified(bh);
 }
 
@@ -343,6 +348,7 @@ void gfs2_dinode_out(struct gfs2_dinode *di, struct gfs2_buffer_head *bh)
 
 	CPOUT_32(di, str, di_flags);
 	CPOUT_32(di, str, di_payload_format);
+	CPOUT_16(di, str, __pad1);
 	CPOUT_16(di, str, di_height);
 
 	CPOUT_16(di, str, di_depth);
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index 0f34e33..cd3667f 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -156,9 +156,12 @@ uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd)
 			return error;
 		}
 	}
-
-	if (rgd->bh && rgd->bh[0])
-		gfs2_rgrp_in(&rgd->rg, rgd->bh[0]);
+	if (rgd->bh && rgd->bh[0]) {
+		if (sdp->gfs1)
+			gfs_rgrp_in((struct gfs_rgrp *)&rgd->rg, rgd->bh[0]);
+		else
+			gfs2_rgrp_in(&rgd->rg, rgd->bh[0]);
+	}
 	return 0;
 }
 
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 42/66] fsck.gfs2: Combine block and char device inode types
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (40 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 41/66] libgfs2: expand capabilities to operate on gfs1 rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 43/66] fsck.gfs2: four-step duplicate elimination process rpeterso
                   ` (23 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch combines the block and character device block designations.
Devices are now treated equally as one block type, which is fine.
This buys back a block type in the block map which may be used later
for gfs1 support.  It also eliminates the rgrp block designation,
which is not needed: We only need to know whether rgrp blocks are
"in use" or not.  In fact, the rgrp blocks have special processing
anyway and special code (function valid_block) to check for overlaps.

rhbz#675723
---
 gfs2/fsck/pass1.c |    6 +++---
 gfs2/fsck/pass2.c |    8 ++------
 gfs2/fsck/pass3.c |    5 ++---
 gfs2/fsck/pass4.c |    3 +--
 gfs2/fsck/pass5.c |    4 +---
 gfs2/fsck/util.h  |   50 +++++++++++++++++++++++++-------------------------
 6 files changed, 34 insertions(+), 42 deletions(-)

diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 64220f0..c0b7420 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -1153,12 +1153,12 @@ static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip)
 		break;
 	case S_IFBLK:
 		if (fsck_blockmap_set(ip, block, _("block device"),
-				      gfs2_inode_blk))
+				      gfs2_inode_device))
 			goto bad_dinode;
 		break;
 	case S_IFCHR:
 		if (fsck_blockmap_set(ip, block, _("character device"),
-				      gfs2_inode_chr))
+				      gfs2_inode_device))
 			goto bad_dinode;
 		break;
 	case S_IFIFO:
@@ -1551,7 +1551,7 @@ int pass1(struct gfs2_sbd *sdp)
 				     "is now marked as 'rgrp data'\n"),
 				   rgd->ri.ri_addr + i, rgd->ri.ri_addr + i);
 			if (gfs2_blockmap_set(bl, rgd->ri.ri_addr + i,
-					      gfs2_meta_rgrp)) {
+					      gfs2_indir_blk)) {
 				stack;
 				return FSCK_ERROR;
 			}
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 7f32903..a4e8dca 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -134,12 +134,8 @@ static int check_file_type(uint8_t de_type, uint8_t blk_type)
 		if (de_type != DT_LNK)
 			return 1;
 		break;
-	case gfs2_inode_blk:
-		if (de_type != DT_BLK)
-			return 1;
-		break;
-	case gfs2_inode_chr:
-		if (de_type != DT_CHR)
+	case gfs2_inode_device:
+		if (de_type != DT_BLK && de_type != DT_CHR)
 			return 1;
 		break;
 	case gfs2_inode_fifo:
diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c
index b904814..51104b5 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -240,9 +240,8 @@ int pass3(struct gfs2_sbd *sdp)
 					log_err( _("Unlinked directory with bad block remains\n"));
 			}
 			if (q != gfs2_inode_dir && q != gfs2_inode_file &&
-			   q != gfs2_inode_lnk && q != gfs2_inode_blk &&
-			   q != gfs2_inode_chr && q != gfs2_inode_fifo &&
-			   q != gfs2_inode_sock) {
+			   q != gfs2_inode_lnk && q != gfs2_inode_device &&
+			   q != gfs2_inode_fifo && q != gfs2_inode_sock) {
 				log_err( _("Unlinked block marked as an inode "
 					   "is not an inode\n"));
 				if (!query(_("Clear the unlinked block?"
diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c
index 04fb075..32dbb72 100644
--- a/gfs2/fsck/pass4.c
+++ b/gfs2/fsck/pass4.c
@@ -83,8 +83,7 @@ static int scan_inode_list(struct gfs2_sbd *sdp) {
 			if (q != gfs2_inode_dir &&
 			   q != gfs2_inode_file &&
 			   q != gfs2_inode_lnk &&
-			   q != gfs2_inode_blk &&
-			   q != gfs2_inode_chr &&
+			   q != gfs2_inode_device &&
 			   q != gfs2_inode_fifo &&
 			   q != gfs2_inode_sock) {
 				log_err( _("Unlinked block %lld (0x%llx) "
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index 814f202..29b5965 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -27,8 +27,7 @@ static int convert_mark(uint8_t q, uint32_t *count)
 	case gfs2_inode_dir:
 	case gfs2_inode_file:
 	case gfs2_inode_lnk:
-	case gfs2_inode_blk:
-	case gfs2_inode_chr:
+	case gfs2_inode_device:
 	case gfs2_inode_fifo:
 	case gfs2_inode_sock:
 		count[1]++;
@@ -36,7 +35,6 @@ static int convert_mark(uint8_t q, uint32_t *count)
 
 	case gfs2_indir_blk:
 	case gfs2_leaf_blk:
-	case gfs2_meta_rgrp:
 	case gfs2_meta_eattr:
 		count[2]++;
 		return GFS2_BLKST_USED;
diff --git a/gfs2/fsck/util.h b/gfs2/fsck/util.h
index b26c123..106cca8 100644
--- a/gfs2/fsck/util.h
+++ b/gfs2/fsck/util.h
@@ -42,15 +42,15 @@ enum gfs2_mark_block {
 	gfs2_inode_file    = (0x4),
 
 	gfs2_inode_lnk     = (0x5),
-	gfs2_inode_blk     = (0x6),
-	gfs2_inode_chr     = (0x7),
+	gfs2_inode_device  = (0x6),
+
 	gfs2_inode_fifo    = (0x8),
 	gfs2_inode_sock    = (0x9),
 
 	gfs2_inode_invalid = (0xa),
 	gfs2_meta_inval    = (0xb),
 	gfs2_leaf_blk      = (0xc),
-	gfs2_meta_rgrp     = (0xd),
+
 	gfs2_meta_eattr    = (0xe),
 
 	gfs2_bad_block     = (0xf), /* Contains at least one bad block */
@@ -66,15 +66,15 @@ static const inline char *block_type_string(uint8_t q)
 		"file",
 
 		"symlink",
-		"block device",
-		"char device",
+		"device",
+		"",
 		"fifo",
 		"socket",
 
 		"invalid inode",
 		"invalid meta",
 		"dir leaf",
-		"rgrp meta",
+		"",
 		"eattribute",
 
 		"bad"};
@@ -88,25 +88,25 @@ static const inline char *block_type_string(uint8_t q)
 static inline int blockmap_to_bitmap(enum gfs2_mark_block m)
 {
 	static int bitmap_states[16] = {
-		GFS2_BLKST_FREE,
-		GFS2_BLKST_USED,
-		GFS2_BLKST_USED,
-		GFS2_BLKST_DINODE,
-		GFS2_BLKST_DINODE,
-
-		GFS2_BLKST_DINODE,
-		GFS2_BLKST_DINODE,
-		GFS2_BLKST_DINODE,
-		GFS2_BLKST_DINODE,
-		GFS2_BLKST_DINODE,
-
-		GFS2_BLKST_FREE,
-		GFS2_BLKST_FREE,
-		GFS2_BLKST_USED,
-		GFS2_BLKST_USED,
-		GFS2_BLKST_USED,
-
-		GFS2_BLKST_USED
+		GFS2_BLKST_FREE,  /* free */
+		GFS2_BLKST_USED,  /* data */
+		GFS2_BLKST_USED,  /* indirect data or rgrp meta*/
+		GFS2_BLKST_DINODE,  /* directory */
+		GFS2_BLKST_DINODE,  /* file */
+
+		GFS2_BLKST_DINODE,  /* symlink */
+		GFS2_BLKST_DINODE,  /* block or char device */
+		GFS2_BLKST_USED,    /* reserved */
+		GFS2_BLKST_DINODE,  /* fifo */
+		GFS2_BLKST_DINODE,  /* socket */
+
+		GFS2_BLKST_FREE,  /* invalid inode */
+		GFS2_BLKST_FREE,  /* invalid meta */
+		GFS2_BLKST_USED,  /* dir leaf */
+		GFS2_BLKST_UNLINKED,  /* unused */
+		GFS2_BLKST_USED,  /* eattribute */
+
+		GFS2_BLKST_USED,  /* bad */
 	};
 	return bitmap_states[m];
 }
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 43/66] fsck.gfs2: four-step duplicate elimination process
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (41 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 42/66] fsck.gfs2: Combine block and char device inode types rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 44/66] fsck.gfs2: Add ability to check gfs1 file systems rpeterso
                   ` (22 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch reforms the duplicate block reference processing by
introducing a new four-step duplicate elimination process.
Step 1. Delete inodes that reference the block and were previously
        marked invalid.
Step 2. Delete inodes that reference the block as the wrong block
        type.  (Data block referenced as metadata, or vise versa)
Step 3. Delete inodes until we're down to a single reference.
Step 4. Fix the block type to be according to the remaining reference.

rhbz#675723
---
 gfs2/fsck/pass1b.c |  280 ++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 196 insertions(+), 84 deletions(-)

diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index 67b8d14..a66bd8b 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -13,6 +13,10 @@
 #include "metawalk.h"
 #include "inode_hash.h"
 
+const char *reftype_str[ref_types + 1] = {"data", "metadata",
+					  "extended attribute",
+					  "unimportant"};
+
 struct fxn_info {
 	uint64_t block;
 	int found;
@@ -365,25 +369,38 @@ static int find_block_ref(struct gfs2_sbd *sdp, uint64_t inode)
 	return error;
 }
 
+/* get_ref_type - figure out if all duplicate references from this inode
+   are the same type, and if so, return the type. */
+static enum dup_ref_type get_ref_type(struct inode_with_dups *id)
+{
+	if (id->reftypecount[ref_as_ea] &&
+	    !id->reftypecount[ref_as_data] &&
+	    !id->reftypecount[ref_as_meta])
+		return ref_as_ea;
+	if (!id->reftypecount[ref_as_ea] &&
+	    id->reftypecount[ref_as_data] &&
+	    !id->reftypecount[ref_as_meta])
+		return ref_as_data;
+	if (!id->reftypecount[ref_as_ea] &&
+	    !id->reftypecount[ref_as_data] &&
+	    id->reftypecount[ref_as_meta])
+		return ref_as_meta;
+	return ref_types; /* multiple references */
+}
+
 static void log_inode_reference(struct duptree *b, osi_list_t *tmp, int inval)
 {
 	char reftypestring[32];
 	struct inode_with_dups *id;
 
 	id = osi_list_entry(tmp, struct inode_with_dups, list);
-	if (id->dup_count == 1) {
-		if (id->reftypecount[ref_as_data])
-			strcpy(reftypestring, "as data");
-		else if (id->reftypecount[ref_as_meta])
-			strcpy(reftypestring, "as metadata");
-		else
-			strcpy(reftypestring, "as extended attribute");
-	} else {
+	if (id->dup_count == 1)
+		sprintf(reftypestring, "as %s", reftype_str[get_ref_type(id)]);
+	else
 		sprintf(reftypestring, "%d/%d/%d",
 			id->reftypecount[ref_as_data],
 			id->reftypecount[ref_as_meta],
 			id->reftypecount[ref_as_ea]);
-	}
 	if (inval)
 		log_warn( _("Invalid "));
 	log_warn( _("Inode %s (%lld/0x%llx) has %d reference(s) to "
@@ -393,10 +410,22 @@ static void log_inode_reference(struct duptree *b, osi_list_t *tmp, int inval)
 		  (unsigned long long)b->block,
 		  (unsigned long long)b->block, reftypestring);
 }
-
-static int clear_a_reference(struct gfs2_sbd *sdp, struct duptree *b,
-			     osi_list_t *ref_list, struct dup_handler *dh,
-			     int inval)
+/*
+ * resolve_dup_references - resolve all but the last dinode that has a
+ *                          duplicate reference to a given block.
+ *
+ * @sdp - pointer to the superblock structure
+ * @b - pointer to the duplicate reference rbtree to use
+ * @ref_list - list of duplicate references to be resolved (invalid or valid)
+ * @dh - duplicate handler
+ * inval - The references on this ref_list are invalid.  We prefer to delete
+ *         these first before resorting to deleting valid dinodes.
+ * acceptable_ref - Delete dinodes that reference the given block as anything
+ *                  _but_ this type.  Try to save references as this type.
+ */
+static int resolve_dup_references(struct gfs2_sbd *sdp, struct duptree *b,
+				  osi_list_t *ref_list, struct dup_handler *dh,
+				  int inval, int acceptable_ref)
 {
 	struct gfs2_inode *ip;
 	struct inode_with_dups *id;
@@ -412,26 +441,74 @@ static int clear_a_reference(struct gfs2_sbd *sdp, struct duptree *b,
 		.check_eattr_entry = clear_eattr_entry,
 		.check_eattr_extentry = clear_eattr_extentry,
 	};
+	enum dup_ref_type this_ref;
+	struct inode_info *ii;
+	int found_good_ref = 0;
 
 	osi_list_foreach_safe(tmp, ref_list, x) {
 		id = osi_list_entry(tmp, struct inode_with_dups, list);
 		dh->b = b;
 		dh->id = id;
+
 		if (dh->ref_inode_count == 1) /* down to the last reference */
 			return 1;
-		if (!(query( _("Okay to clear %s inode %lld (0x%llx)? (y/n) "),
+
+		this_ref = get_ref_type(id);
+		if (inval)
+			log_warn( _("Invalid "));
+		/* FIXME: If we already found an acceptable reference to this
+		 * block, we should really duplicate the block and fix all
+		 * references to it in this inode.  Unfortunately, we would
+		 * have to traverse the entire metadata tree to do that. */
+		if (acceptable_ref != ref_types && /* If we're nuking all but
+						      an acceptable reference
+						      type and */
+		    this_ref == acceptable_ref && /* this ref is acceptable */
+		    !found_good_ref) { /* We haven't found a good reference */
+			uint8_t q;
+
+			/* If this is an invalid inode, but not on the invalid
+			   list, it's better to delete it. */
+			q = block_type(id->block_no);
+			if (q != gfs2_inode_invalid) {
+				found_good_ref = 1;
+				continue; /* don't delete the dinode */
+			}
+		}
+
+		log_warn( _("Inode %s (%lld/0x%llx) references block "
+			    "%llu (0x%llx) as '%s', but the block is "
+			    "really %s.\n"),
+			  id->name, (unsigned long long)id->block_no,
+			  (unsigned long long)id->block_no,
+			  (unsigned long long)b->block,
+			  (unsigned long long)b->block,
+			  reftype_str[this_ref],
+			  reftype_str[acceptable_ref]);
+		if (!(query( _("Okay to delete %s inode %lld (0x%llx)? "
+			       "(y/n) "),
 			     (inval ? _("invalidated") : ""),
 			     (unsigned long long)id->block_no,
 			     (unsigned long long)id->block_no))) {
-			log_warn( _("The bad inode was not cleared...\n"));
+			log_warn( _("The bad inode was not cleared."));
+			/* delete the list entry so we don't leak memory but
+			   leave the reference count.  If the decrement the
+			   ref count, we could get down to 1 and the dinode
+			   would be changed without a 'Yes' answer. */
+			/* (dh->ref_inode_count)--;*/
+			dup_listent_delete(id);
 			continue;
 		}
 		log_warn( _("Clearing inode %lld (0x%llx)...\n"),
 			  (unsigned long long)id->block_no,
 			  (unsigned long long)id->block_no);
+
+		ip = fsck_load_inode(sdp, id->block_no);
+		ii = inodetree_find(ip->i_di.di_num.no_addr);
+		if (ii)
+			inodetree_delete(ii);
 		clear_dup_fxns.private = (void *) dh;
 		/* Clear the EAs for the inode first */
-		ip = fsck_load_inode(sdp, id->block_no);
 		check_inode_eattr(ip, &clear_dup_fxns);
 		/* If the dup wasn't only in the EA, clear the inode */
 		if (id->reftypecount[ref_as_data] ||
@@ -439,13 +516,14 @@ static int clear_a_reference(struct gfs2_sbd *sdp, struct duptree *b,
 			check_metatree(ip, &clear_dup_fxns);
 
 		fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
-				  _("bad"), gfs2_inode_invalid);
+				  _("duplicate referencing bad"),
+				  gfs2_inode_invalid);
 		fsck_inode_put(&ip); /* out, brelse, free */
 		(dh->ref_inode_count)--;
-		/* Inode is marked invalid and is removed in pass2 */
 		/* FIXME: other option should be to duplicate the
 		 * block for each duplicate and point the metadata at
 		 * the cloned blocks */
+		dup_listent_delete(id);
 	}
 	if (dh->ref_inode_count == 1) /* down to the last reference */
 		return 1;
@@ -458,19 +536,56 @@ static int handle_dup_blk(struct gfs2_sbd *sdp, struct duptree *b)
 	osi_list_t *tmp;
 	struct inode_with_dups *id;
 	struct dup_handler dh = {0};
-	int last_reference, ref_in_invalid_inode = 0;
+	int last_reference = 0;
+	struct gfs2_buffer_head *bh;
+	uint32_t cmagic, ctype;
+	enum dup_ref_type acceptable_ref;
 
+	/* Count the duplicate references, both valid and invalid */
 	osi_list_foreach(tmp, &b->ref_invinode_list) {
 		id = osi_list_entry(tmp, struct inode_with_dups, list);
 		dh.ref_inode_count++;
 		dh.ref_count += id->dup_count;
-		ref_in_invalid_inode = 1;
 	}
 	osi_list_foreach(tmp, &b->ref_inode_list) {
 		id = osi_list_entry(tmp, struct inode_with_dups, list);
 		dh.ref_inode_count++;
 		dh.ref_count += id->dup_count;
 	}
+
+	/* Log the duplicate references */
+	log_notice( _("Block %llu (0x%llx) has %d inodes referencing it"
+		   " for a total of %d duplicate references:\n"),
+		   (unsigned long long)b->block, (unsigned long long)b->block,
+		   dh.ref_inode_count, dh.ref_count);
+
+	osi_list_foreach(tmp, &b->ref_invinode_list)
+		log_inode_reference(b, tmp, 1);
+	osi_list_foreach(tmp, &b->ref_inode_list)
+		log_inode_reference(b, tmp, 0);
+
+	/* Figure out the block type to see if we can eliminate references
+	   to a different type. In other words, if the duplicate block looks
+	   like metadata, we can delete dinodes that reference it as data.
+	   If the block doesn't look like metadata, we can eliminate any
+	   references to it as metadata.  Dinodes with such references are
+	   clearly corrupt and need to be deleted.
+	   And if we're left with a single reference, problem solved. */
+	bh = bread(sdp, b->block);
+	cmagic = ((struct gfs2_meta_header *)(bh->b_data))->mh_magic;
+	ctype = ((struct gfs2_meta_header *)(bh->b_data))->mh_type;
+	brelse(bh);
+
+	if (be32_to_cpu(cmagic) == GFS2_MAGIC &&
+	    (be32_to_cpu(ctype) == GFS2_METATYPE_EA ||
+	     be32_to_cpu(ctype) == GFS2_METATYPE_ED))
+		acceptable_ref = ref_as_ea;
+	else if (be32_to_cpu(cmagic) == GFS2_MAGIC &&
+		 be32_to_cpu(ctype) <= GFS2_METATYPE_QC)
+		acceptable_ref = ref_as_meta;
+	else
+		acceptable_ref = ref_as_data;
+
 	/* A single reference to the block implies a possible situation where
 	   a data pointer points to a metadata block.  In other words, the
 	   duplicate reference in the file system is (1) Metadata block X and
@@ -484,75 +599,71 @@ static int handle_dup_blk(struct gfs2_sbd *sdp, struct duptree *b)
 	   invalidated for other reasons, such as bad pointers.  So we need to
 	   make sure@this point that any inode deletes reverse out any
 	   duplicate reference before we get to this point. */
-	if (dh.ref_count == 1) {
-		struct gfs2_buffer_head *bh;
-		uint32_t cmagic;
-
-		bh = bread(sdp, b->block);
-		cmagic = ((struct gfs2_meta_header *)(bh->b_data))->mh_magic;
-		brelse(bh);
-		if (be32_to_cpu(cmagic) == GFS2_MAGIC) {
-			if (ref_in_invalid_inode)
-				tmp = b->ref_invinode_list.next;
-			else
-				tmp = b->ref_inode_list.next;
-			id = osi_list_entry(tmp, struct inode_with_dups, list);
-			log_warn( _("Inode %s (%lld/0x%llx) has a reference to"
-				    " data block %llu (0x%llx), "
-				    "but the block is really metadata.\n"),
-				  id->name, (unsigned long long)id->block_no,
-				  (unsigned long long)id->block_no,
-				  (unsigned long long)b->block,
-				  (unsigned long long)b->block);
-			if (query( _("Clear the inode? (y/n) "))) {
-				struct inode_info *ii;
-
-				log_warn( _("Clearing inode %lld (0x%llx)...\n"),
-					 (unsigned long long)id->block_no,
-					 (unsigned long long)id->block_no);
-				ip = fsck_load_inode(sdp, id->block_no);
-				ii = inodetree_find(ip->i_di.di_num.no_addr);
-				if (ii)
-					inodetree_delete(ii);
-				/* Setting the block to invalid means the inode
-				   is cleared in pass2 */
-				fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
-						 _("inode with bad duplicate"),
-						 gfs2_inode_invalid);
-				fsck_inode_put(&ip);
-			} else {
-				log_warn( _("The bad inode was not cleared."));
-			}
-			return 0;
-		}
-		/* The other references may have been discredited due to
-		   invalid metadata or something.  Use the last remaining. */
-		log_notice( _("Block %llu (0x%llx) has only one remaining "
-			      "reference.\n"),
+	if (dh.ref_count == 1)
+		last_reference = 1;
+
+	/* Step 1 - eliminate references from inodes that are not valid.
+	 *          This may be because they were deleted due to corruption.
+	 *          All block types are unacceptable, so we use ref_types.
+	 */
+	if (!last_reference) {
+		log_debug( _("----------------------------------------------\n"
+			     "Step 1: Eliminate references to block %llu "
+			     "(0x%llx) that were previously marked "
+			     "invalid.\n"),
+			   (unsigned long long)b->block,
+			   (unsigned long long)b->block);
+		last_reference = resolve_dup_references(sdp, b,
+							&b->ref_invinode_list,
+							&dh, 1, ref_types);
+	}
+	/* Step 2 - eliminate reference from inodes that reference it as the
+	 *          wrong type.  For example, a data file referencing it as
+	 *          a data block, but it's really a metadata block.  Or a
+	 *          directory inode referencing a data block as a leaf block.
+	 */
+	if (!last_reference) {
+		last_reference = resolve_dup_references(sdp, b,
+							&b->ref_inode_list,
+							&dh, 0,
+							acceptable_ref);
+		log_debug( _("----------------------------------------------\n"
+			     "Step 2: Eliminate references to block %llu "
+			     "(0x%llx) that need the wrong block type.\n"),
+			   (unsigned long long)b->block,
+			   (unsigned long long)b->block);
+	}
+	/* Step 3 - We have multiple dinodes referencing it as the correct
+	 *          type.  Just blast one of them.
+	 *          All block types are fair game, so we use ref_types.
+	 */
+	if (!last_reference) {
+		log_debug( _("----------------------------------------------\n"
+			     "Step 3: Choose one reference to block %llu "
+			     "(0x%llx) to keep.\n"),
+			   (unsigned long long)b->block,
+			   (unsigned long long)b->block);
+		last_reference = resolve_dup_references(sdp, b,
+							&b->ref_inode_list,
+							&dh, 0, ref_types);
+	}
+	/* Now fix the block type of the block in question. */
+	if (osi_list_empty(&b->ref_inode_list)) {
+		log_notice( _("Block %llu (0x%llx) has no more references; "
+			      "Marking as 'free'.\n"),
 			    (unsigned long long)b->block,
 			    (unsigned long long)b->block);
+		gfs2_blockmap_set(bl, b->block, gfs2_block_free);
+		check_n_fix_bitmap(sdp, b->block, gfs2_block_free);
 		return 0;
 	}
-
-	log_notice( _("Block %llu (0x%llx) has %d inodes referencing it"
-		   " for a total of %d duplicate references\n"),
-		   (unsigned long long)b->block, (unsigned long long)b->block,
-		   dh.ref_inode_count, dh.ref_count);
-
-	osi_list_foreach(tmp, &b->ref_invinode_list)
-		log_inode_reference(b, tmp, 1);
-	osi_list_foreach(tmp, &b->ref_inode_list)
-		log_inode_reference(b, tmp, 0);
-
-	last_reference = clear_a_reference(sdp, b, &b->ref_invinode_list,
-					   &dh, 1);
-	if (!last_reference)
-		last_reference = clear_a_reference(sdp, b, &b->ref_inode_list,
-						   &dh, 0);
-
-	if (last_reference && !osi_list_empty(&b->ref_inode_list)) {
+	if (last_reference) {
 		uint8_t q;
 
+		log_notice( _("Block %llu (0x%llx) has only one remaining "
+			      "reference.\n"),
+			    (unsigned long long)b->block,
+			    (unsigned long long)b->block);
 		/* If we're down to a single reference (and not all references
 		   deleted, which may be the case of an inode that has only
 		   itself and a reference), we need to reset the block type
@@ -560,7 +671,8 @@ static int handle_dup_blk(struct gfs2_sbd *sdp, struct duptree *b)
 		   in the list, not the structure's place holder. */
 		tmp = (&b->ref_inode_list)->next;
 		id = osi_list_entry(tmp, struct inode_with_dups, list);
-		log_debug( _("Resetting the type based on the remaining "
+		log_debug( _("----------------------------------------------\n"
+			     "Step 4. Set block type based on the remaining "
 			     "reference in inode %lld (0x%llx).\n"),
 			   (unsigned long long)id->block_no,
 			   (unsigned long long)id->block_no);
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 44/66] fsck.gfs2: Add ability to check gfs1 file systems
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (42 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 43/66] fsck.gfs2: four-step duplicate elimination process rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 45/66] fsck.gfs2: Remove bad inodes from duplicate tree rpeterso
                   ` (21 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch gives fsck.gfs2 the ability to check GFS1 file systems.

rhbz#675723
---
 gfs2/fsck/fs_recovery.c   |   37 ++++--
 gfs2/fsck/fsck.h          |    3 +
 gfs2/fsck/initialize.c    |  302 +++++++++++++++++++++++++++++++++++----------
 gfs2/fsck/lost_n_found.c  |   96 ++++++++++++---
 gfs2/fsck/main.c          |   14 ++-
 gfs2/fsck/metawalk.c      |   90 ++++++++++----
 gfs2/fsck/pass1.c         |  167 +++++++++++++++++++++-----
 gfs2/fsck/pass1b.c        |    5 +-
 gfs2/fsck/pass2.c         |   40 ++++---
 gfs2/fsck/pass3.c         |   39 +++++-
 gfs2/fsck/pass4.c         |    7 +
 gfs2/fsck/pass5.c         |   87 ++++++++++++-
 gfs2/fsck/rgrepair.c      |   20 +++-
 gfs2/fsck/util.h          |  111 ++++++++++++-----
 gfs2/libgfs2/libgfs2.h    |    3 +
 gfs2/libgfs2/structures.c |   29 +++--
 16 files changed, 836 insertions(+), 214 deletions(-)

diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c
index 8e29167..907e37f 100644
--- a/gfs2/fsck/fs_recovery.c
+++ b/gfs2/fsck/fs_recovery.c
@@ -629,7 +629,9 @@ int ji_update(struct gfs2_sbd *sdp)
 {
 	struct gfs2_inode *jip, *ip = sdp->md.jiinode;
 	char journal_name[JOURNAL_NAME_SIZE];
-	int i;
+	int i, error;
+	char buf[sizeof(struct gfs_jindex)];
+	struct gfs_jindex ji;
 
 	if (!ip) {
 		log_crit("Journal index inode not found.\n");
@@ -640,24 +642,41 @@ int ji_update(struct gfs2_sbd *sdp)
 	   plus two for "." and "..".  So we subtract the 2 and divide by 3.
 	   If per_node is missing or damaged, we have to trust jindex has
 	   the correct number of entries. */
-	if (sdp->md.pinode) /* if per_node was read in properly */
+	if (sdp->gfs1)
+		sdp->md.journals = ip->i_di.di_size / sizeof(struct gfs_jindex);
+	else if (sdp->md.pinode) /* if per_node was read in properly */
 		sdp->md.journals = (sdp->md.pinode->i_di.di_entries - 2) / 3;
 	else
 		sdp->md.journals = ip->i_di.di_entries - 2;
 
 	if (!(sdp->md.journal = calloc(sdp->md.journals,
-				      sizeof(struct gfs2_inode *)))) {
+				       sizeof(struct gfs2_inode *)))) {
 		log_err("Unable to allocate journal index\n");
 		return -1;
 	}
 	memset(journal_name, 0, sizeof(*journal_name));
 	for (i = 0; i < sdp->md.journals; i++) {
-		/* FIXME check snprintf return code */
-		snprintf(journal_name, JOURNAL_NAME_SIZE, "journal%u", i);
-		gfs2_lookupi(sdp->md.jiinode, journal_name, strlen(journal_name),
-			     &jip);
-		sdp->md.journal[i] = jip;
+		if (sdp->gfs1) {
+			error = gfs2_readi(ip,
+					   buf, i * sizeof(struct gfs_jindex),
+					   sizeof(struct gfs_jindex));
+			if (!error)
+				break;
+			if (error != sizeof(struct gfs_jindex)){
+				log_err("An error occurred while reading the"
+					" journal index file.\n");
+				return -1;
+			}
+			gfs_jindex_in(&ji, buf);
+			sdp->md.journal[i] = inode_read(sdp, ji.ji_addr);
+		} else {
+			/* FIXME check snprintf return code */
+			snprintf(journal_name, JOURNAL_NAME_SIZE,
+				 "journal%u", i);
+			gfs2_lookupi(sdp->md.jiinode, journal_name,
+				     strlen(journal_name), &jip);
+			sdp->md.journal[i] = jip;
+		}
 	}
 	return 0;
-
 }
diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h
index 0fed06b..e2640d8 100644
--- a/gfs2/fsck/fsck.h
+++ b/gfs2/fsck/fsck.h
@@ -113,6 +113,7 @@ extern void gfs2_dup_free(void);
 extern int fsck_query(const char *format, ...)
 	__attribute__((format(printf,1,2)));
 extern struct dir_info *dirtree_find(uint64_t block);
+extern void dup_listent_delete(struct inode_with_dups *id);
 extern void dup_delete(struct duptree *b);
 extern void dirtree_delete(struct dir_info *b);
 
@@ -135,4 +136,6 @@ extern struct osi_root inodetree;
 extern int dups_found; /* How many duplicate references have we found? */
 extern int dups_found_first; /* How many duplicates have we found the original
 				reference for? */
+extern struct gfs_sb *sbd1;
+
 #endif /* _FSCK_H */
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index d7586de..cee1f49 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -9,6 +9,7 @@
 #include <unistd.h>
 #include <libintl.h>
 #include <errno.h>
+#include <time.h>
 
 #define _(String) gettext(String)
 
@@ -191,12 +192,14 @@ static void check_rgrp_integrity(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
 				 int *fixit, int *this_rg_fixed,
 				 int *this_rg_bad)
 {
-	uint32_t rg_free, rg_reclaimed;
+	uint32_t rg_free, rg_reclaimed, rg_unlinked;
 	int rgb, x, y, off, bytes_to_check, total_bytes_to_check, asked = 0;
 	unsigned int state;
+	struct gfs_rgrp *gfs1rg = (struct gfs_rgrp *)&rgd->rg;
 
-	rg_free = rg_reclaimed = 0;
+	rg_free = rg_reclaimed = rg_unlinked = 0;
 	total_bytes_to_check = rgd->ri.ri_bitbytes;
+
 	*this_rg_fixed = *this_rg_bad = 0;
 
 	for (rgb = 0; rgb < rgd->ri.ri_length; rgb++){
@@ -244,8 +247,10 @@ static void check_rgrp_integrity(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
 					if (query("%s", msg))
 						*fixit = 1;
 				}
-				if (!(*fixit))
+				if (!(*fixit)) {
+					rg_unlinked++;
 					continue;
+				}
 				*byte &= ~(GFS2_BIT_MASK <<
 					   (GFS2_BIT_SIZE * y));
 				bmodified(rgd->bh[rgb]);
@@ -267,7 +272,29 @@ static void check_rgrp_integrity(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
 				 rg_reclaimed);
 		if (query( _("Fix the rgrp free blocks count? (y/n)"))) {
 			rgd->rg.rg_free = rg_free;
-			gfs2_rgrp_out(&rgd->rg, rgd->bh[0]);
+			if (sdp->gfs1)
+				gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg,
+					     rgd->bh[0]);
+			else
+				gfs2_rgrp_out(&rgd->rg, rgd->bh[0]);
+			*this_rg_fixed = 1;
+			log_err( _("The rgrp was fixed.\n"));
+		} else
+			log_err( _("The rgrp was not fixed.\n"));
+	}
+	if (sdp->gfs1 && gfs1rg->rg_freemeta != rg_unlinked) {
+		*this_rg_bad = 1;
+		log_err( _("Error: resource group %lld (0x%llx): "
+			   "free meta  (%d) does not match bitmap (%d)\n"),
+			 (unsigned long long)rgd->ri.ri_addr,
+			 (unsigned long long)rgd->ri.ri_addr,
+			 gfs1rg->rg_freemeta, rg_unlinked);
+		if (rg_reclaimed)
+			log_err( _("(%d blocks were reclaimed)\n"),
+				 rg_reclaimed);
+		if (query( _("Fix the rgrp free meta blocks count? (y/n)"))) {
+			gfs1rg->rg_freemeta = rg_unlinked;
+			gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bh[0]);
 			*this_rg_fixed = 1;
 			log_err( _("The rgrp was fixed.\n"));
 		} else
@@ -455,7 +482,7 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
 	uint64_t inumbuf;
 	char *buf;
 	struct gfs2_statfs_change sc;
-	int rgcount, sane = 1;
+	int rgcount, sane = 1, err = 0;
 	enum rgindex_trust_level trust_lvl;
 	uint64_t addl_mem_needed;
 	const char *level_desc[] = {
@@ -482,7 +509,10 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
 	/* Get root dinode */
 	sdp->md.rooti = inode_read(sdp, sdp->sd_sb.sb_root_dir.no_addr);
 
-	gfs2_lookupi(sdp->master_dir, "rindex", 6, &sdp->md.riinode);
+	if (sdp->gfs1)
+		sdp->md.riinode = inode_read(sdp, sbd1->sb_rindex_di.no_addr);
+	else
+		gfs2_lookupi(sdp->master_dir, "rindex", 6, &sdp->md.riinode);
 	if (!sdp->md.riinode) {
 		if (query( _("The gfs2 system rindex inode is missing. "
 			     "Okay to rebuild it? (y/n) ")))
@@ -495,7 +525,10 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
 
 	/* rgrepair requires the journals be read in in order to distinguish
 	   "real" rgrps from rgrps that are just copies left in journals. */
-	gfs2_lookupi(sdp->master_dir, "jindex", 6, &sdp->md.jiinode);
+	if (sdp->gfs1)
+		sdp->md.jiinode = inode_read(sdp, sbd1->sb_jindex_di.no_addr);
+	else
+		gfs2_lookupi(sdp->master_dir, "jindex", 6, &sdp->md.jiinode);
 	if (!sdp->md.jiinode) {
 		if (query( _("The gfs2 system jindex inode is missing. "
 			     "Okay to rebuild it? (y/n) ")))
@@ -513,7 +546,7 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
 	 *******************************************************************/
 	log_warn( _("Validating Resource Group index.\n"));
 	for (trust_lvl = blind_faith; trust_lvl <= indignation; trust_lvl++) {
-		int ret;
+		int ret = 0;
 
 		log_warn( _("Level %d rgrp check: %s.\n"), trust_lvl + 1,
 			  level_desc[trust_lvl]);
@@ -547,27 +580,60 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
 	/*******************************************************************
 	 *****************  Initialize more system inodes  *****************
 	 *******************************************************************/
-	/* Look for "inum" entry in master dinode */
-	gfs2_lookupi(sdp->master_dir, "inum", 4, &sdp->md.inum);
-	if (!sdp->md.inum) {
-		if (query( _("The gfs2 system inum inode is missing. "
-			     "Okay to rebuild it? (y/n) ")))
-			build_inum(sdp);
+	if (!sdp->gfs1) {
+		/* Look for "inum" entry in master dinode */
+		gfs2_lookupi(sdp->master_dir, "inum", 4, &sdp->md.inum);
+		if (!sdp->md.inum) {
+			if (!query( _("The gfs2 system inum inode is missing. "
+				      "Okay to rebuild it? (y/n) "))) {
+				log_err( _("fsck.gfs2 cannot continue without "
+					   "a valid inum file; aborting.\n"));
+				goto fail;
+			}
+			err = build_inum(sdp);
+			if (err) {
+				log_crit(_("Error rebuilding inum inode: %s\n"),
+					 strerror(err));
+				exit(-1);
+			}
+			gfs2_lookupi(sdp->master_dir, "inum", 4,
+				     &sdp->md.inum);
+			if (!sdp->md.inum) {
+				log_crit("System inum inode was not rebuilt.  "
+					 "Aborting.\n");
+				goto fail;
+			}
+		}
+		/* Read inum entry into buffer */
+		gfs2_readi(sdp->md.inum, &inumbuf, 0,
+			   sdp->md.inum->i_di.di_size);
+		/* call gfs2_inum_range_in() to retrieve range */
+		sdp->md.next_inum = be64_to_cpu(inumbuf);
 	}
-	/* Read inum entry into buffer */
-	gfs2_readi(sdp->md.inum, &inumbuf, 0, sdp->md.inum->i_di.di_size);
-	/* call gfs2_inum_range_in() to retrieve range */
-	sdp->md.next_inum = be64_to_cpu(inumbuf);
 
-	gfs2_lookupi(sdp->master_dir, "statfs", 6, &sdp->md.statfs);
-	if (!sdp->md.statfs) {
-		if (query( _("The gfs2 system statfs inode is missing. "
-			     "Okay to rebuild it? (y/n) ")))
-			build_statfs(sdp);
-		else {
-			log_err( _("fsck.gfs2 cannot continue without a "
-				   "valid statfs file; aborting.\n"));
-			return FSCK_ERROR;
+	if (sdp->gfs1)
+		sdp->md.statfs = inode_read(sdp, sbd1->sb_license_di.no_addr);
+	else
+		gfs2_lookupi(sdp->master_dir, "statfs", 6, &sdp->md.statfs);
+	if (!sdp->gfs1 && !sdp->md.statfs) {
+		if (!query( _("The gfs2 system statfs inode is missing. "
+			      "Okay to rebuild it? (y/n) "))) {
+			log_err( _("fsck.gfs2 cannot continue without a valid "
+				   "statfs file; aborting.\n"));
+			goto fail;
+		}
+		err = build_statfs(sdp);
+		if (err) {
+			log_crit(_("Error rebuilding statfs inode: %s\n"),
+				 strerror(err));
+			exit(-1);
+		}
+		gfs2_lookupi(sdp->master_dir, "statfs", 6, &sdp->md.statfs);
+		if (!sdp->md.statfs) {
+			log_err( _("Rebuild of statfs system file failed."));
+			log_err( _("fsck.gfs2 cannot continue without "
+				   "a valid statfs file; aborting.\n"));
+			goto fail;
 		}
 	}
 	buf = malloc(sdp->md.statfs->i_di.di_size);
@@ -577,16 +643,36 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
 	gfs2_statfs_change_in(&sc, buf);
 	free(buf);
 
-	gfs2_lookupi(sdp->master_dir, "quota", 5, &sdp->md.qinode);
-	if (!sdp->md.qinode) {
-		if (query( _("The gfs2 system quota inode is missing. "
-			     "Okay to rebuild it? (y/n) ")))
-			build_quota(sdp);
+	if (sdp->gfs1)
+		sdp->md.qinode = inode_read(sdp, sbd1->sb_quota_di.no_addr);
+	else
+		gfs2_lookupi(sdp->master_dir, "quota", 5, &sdp->md.qinode);
+	if (!sdp->gfs1 && !sdp->md.qinode) {
+		if (!query( _("The gfs2 system quota inode is missing. "
+			      "Okay to rebuild it? (y/n) "))) {
+			log_crit("System quota inode was not "
+				 "rebuilt.  Aborting.\n");
+			goto fail;
+		}
+		err = build_quota(sdp);
+		if (err) {
+			log_crit(_("Error rebuilding quota inode: %s\n"),
+				 strerror(err));
+			exit(-1);
+		}
+		gfs2_lookupi(sdp->master_dir, "quota", 5, &sdp->md.qinode);
+		if (!sdp->md.qinode) {
+			log_crit("Unable to rebuild system quota file "
+				 "inode.  Aborting.\n");
+			goto fail;
+		}
 	}
 
 	/* Try to lookup the per_node inode.  If it was missing, it is now
 	   safe to rebuild it. */
-	lookup_per_node(sdp, 1);
+	if (!sdp->gfs1)
+		lookup_per_node(sdp, 1);
+
 	/*******************************************************************
 	 *******  Now, set boundary fields in the super block  *************
 	 *******************************************************************/
@@ -699,13 +785,15 @@ static void peruse_system_dinode(struct gfs2_sbd *sdp, struct gfs2_dinode *di,
 		return;
 	}
 	ip = inode_read(sdp, di->di_num.no_addr);
-	if (di->di_num.no_formal_ino == 3) {
+	if ((!sdp->gfs1 && di->di_num.no_formal_ino == 3) ||
+	    (sdp->gfs1 && (di->di_flags & GFS2_DIF_JDATA) &&
+	     (di->di_size % sizeof(struct gfs_jindex) == 0))) {
 		if (fix_md.jiinode || is_journal_copy(ip, bh))
 			return;
 		log_warn(_("Found system jindex file at: 0x%llx\n"),
 			 di->di_num.no_addr);
 		fix_md.jiinode = ip;
-	} else if (S_ISDIR(di->di_mode)) {
+	} else if (!sdp->gfs1 && is_dir(di, sdp->gfs1)) {
 		/* Check for a jindex dir entry. Only one system dir has a
 		   jindex: master */
 		gfs2_lookupi(ip, "jindex", 6, &child_ip);
@@ -741,7 +829,7 @@ static void peruse_system_dinode(struct gfs2_sbd *sdp, struct gfs2_dinode *di,
 		log_debug(_("Unknown system directory at block 0x%llx\n"),
 			  di->di_num.no_addr);
 		inode_put(&ip);
-	} else if (di->di_size == 8) {
+	} else if (!sdp->gfs1 && di->di_size == 8) {
 		if (fix_md.inum || is_journal_copy(ip, bh))
 			return;
 		fix_md.inum = ip;
@@ -783,7 +871,7 @@ static void peruse_user_dinode(struct gfs2_sbd *sdp, struct gfs2_dinode *di,
 
 	if (sdp->sd_sb.sb_root_dir.no_addr) /* if we know the root dinode */
 		return;             /* we don't need to find the root */
-	if (!S_ISDIR(di->di_mode))  /* if this isn't a directory */
+	if (!is_dir(di, sdp->gfs1))  /* if this isn't a directory */
 		return;             /* it can't lead us to the root anyway */
 
 	if (di->di_num.no_formal_ino == 1) {
@@ -918,7 +1006,6 @@ static int peruse_metadata(struct gfs2_sbd *sdp, uint64_t startblock)
 	uint64_t blk, max_rg_size;
 	struct gfs2_buffer_head *bh;
 	struct gfs2_dinode di;
-	int found_gfs2_dinodes = 0, possible_gfs1_dinodes = 0;
 
 	max_rg_size = 2147483648ull / sdp->bsize;
 	/* Max RG size is 2GB. 2G / bsize. */
@@ -929,18 +1016,6 @@ static int peruse_metadata(struct gfs2_sbd *sdp, uint64_t startblock)
 			continue;
 		}
 		gfs2_dinode_in(&di, bh);
-		if (!found_gfs2_dinodes &&
-		    di.di_num.no_addr == di.di_num.no_formal_ino) {
-			possible_gfs1_dinodes++;
-			if (possible_gfs1_dinodes > 5) {
-				log_err(_("Found several gfs (version 1) "
-					  "dinodes; aborting.\n"));
-				brelse(bh);
-				return -1;
-			}
-		} else {
-			found_gfs2_dinodes++;
-		}
 		if (di.di_flags & GFS2_DIF_SYSTEM)
 			peruse_system_dinode(sdp, &di, bh);
 		else
@@ -1067,6 +1142,8 @@ static int sb_repair(struct gfs2_sbd *sdp)
  */
 static int fill_super_block(struct gfs2_sbd *sdp)
 {
+	int ret;
+
 	sync();
 
 	/********************************************************************
@@ -1091,19 +1168,109 @@ static int fill_super_block(struct gfs2_sbd *sdp)
 		log_crit(_("Bad constants (1)\n"));
 		exit(-1);
 	}
-	if (read_sb(sdp, 0) < 0) {
-		/* First, check for a gfs1 (not gfs2) file system */
-		if (sdp->sd_sb.sb_header.mh_magic == GFS2_MAGIC &&
-		    sdp->sd_sb.sb_header.mh_type == GFS2_METATYPE_SB)
-			return -1; /* This is gfs1, don't try to repair */
-		/* It's not a "sane" gfs1 fs so try to repair it */
+	ret = read_sb(sdp, 1);
+	if (ret < 0) {
 		if (sb_repair(sdp) != 0)
 			return -1; /* unrepairable, so exit */
 		/* Now that we've tried to repair it, re-read it. */
-		if (read_sb(sdp, 0) < 0)
+		ret = read_sb(sdp, 1);
+		if (ret < 0)
 			return -1;
 	}
+	if (sdp->gfs1)
+		sbd1 = (struct gfs_sb *)&sdp->sd_sb;
+	return 0;
+}
+
+static void gfs_log_header_out(struct gfs_log_header *head, char *buf)
+{
+        struct gfs_log_header *str = (struct gfs_log_header *) buf;
+
+	str->lh_header.mh_magic = cpu_to_be32(head->lh_header.mh_magic);
+	str->lh_header.mh_type = cpu_to_be32(head->lh_header.mh_type);
+	str->lh_header.mh_format = cpu_to_be32(head->lh_header.mh_format);
+	str->lh_header.__pad0 = cpu_to_be32(head->lh_header.__pad0);
+
+	str->lh_flags = cpu_to_be32(head->lh_flags);
+	str->lh_pad = cpu_to_be32(head->lh_pad);
+	str->lh_first = cpu_to_be64(head->lh_first);
+	str->lh_sequence = cpu_to_be64(head->lh_sequence);
+	str->lh_tail = cpu_to_be64(head->lh_tail);
+	str->lh_last_dump = cpu_to_be64(head->lh_last_dump);
+}
+
+/*
+ * reconstruct_single_journal - write a fresh GFS1 journal
+ * @sdp: superblock
+ * @jnum: journal number
+ *
+ * This function will write a fresh journal over the top of
+ * the previous journal.  All journal information is lost.  This
+ * process is basically stolen from write_journals() in the mkfs code.
+ *
+ * Returns: -1 on error, 0 otherwise
+ */
+static int reconstruct_single_journal(struct gfs2_sbd *sdp, int jnum,
+				      uint32_t ji_nsegment)
+{
+	struct gfs_log_header lh;
+	uint32_t seg, sequence;
+	struct gfs2_buffer_head *bh;
+
+	srandom(time(NULL));
+	sequence = ji_nsegment / (RAND_MAX + 1.0) * random();
+
+	log_info("Clearing journal %d\n", jnum);
+
+	for (seg = 0; seg < ji_nsegment; seg++){
+		bh = bget(sdp, lh.lh_first * sdp->bsize);
+		memset(bh->b_data, 0, sdp->bsize);
+		memset(&lh, 0, sizeof(struct gfs_log_header));
+
+		lh.lh_header.mh_magic = GFS2_MAGIC;
+		lh.lh_header.mh_type = GFS2_METATYPE_LH;
+		lh.lh_header.mh_format = GFS2_FORMAT_LH;
+		lh.lh_header.__pad0 = 0x101674; /* mh_generation */
+		lh.lh_flags = GFS2_LOG_HEAD_UNMOUNT;
+		lh.lh_first = sdp->md.journal[jnum]->i_di.di_num.no_addr +
+			(seg * sbd1->sb_seg_size);
+		lh.lh_sequence = sequence;
+
+		gfs_log_header_out(&lh, bh->b_data);
+		gfs_log_header_out(&lh, bh->b_data + GFS2_BASIC_BLOCK -
+				   sizeof(struct gfs_log_header));
+		brelse(bh);
+
+		if (++sequence == ji_nsegment)
+			sequence = 0;
+	}
+	return 0;
+}
 
+
+/*
+ * reconstruct_journals - write fresh journals for GFS1 only
+ * sdp: the super block
+ *
+ * Returns: 0 on success, -1 on failure
+ */
+static int reconstruct_journals(struct gfs2_sbd *sdp)
+{
+	int i;
+	struct gfs_jindex ji;
+	char buf[sizeof(struct gfs_jindex)];
+
+	log_err("Clearing GFS journals (this may take a while)");
+	for (i = 0; i < sdp->md.journals; i++) {
+		gfs2_readi(sdp->md.jiinode, buf, i * sizeof(struct gfs_jindex),
+			   sizeof(struct gfs_jindex));
+		gfs_jindex_in(&ji, buf);
+		if ((i % 2) == 0)
+			log_err(".");
+		if (reconstruct_single_journal(sdp, i, ji.ji_nsegment))
+			return -1;
+	}
+	log_err("\nJournals cleared.\n");
 	return 0;
 }
 
@@ -1175,10 +1342,15 @@ int initialize(struct gfs2_sbd *sdp, int force_check, int preen,
 	}
 
 	/* Get master dinode */
-	sdp->master_dir = inode_read(sdp, sdp->sd_sb.sb_master_dir.no_addr);
-	if (sdp->master_dir->i_di.di_header.mh_magic != GFS2_MAGIC ||
-	    sdp->master_dir->i_di.di_header.mh_type != GFS2_METATYPE_DI ||
-	    !sdp->master_dir->i_di.di_size) {
+	if (sdp->gfs1)
+		sdp->master_dir = NULL;
+	else
+		sdp->master_dir = inode_read(sdp,
+					     sdp->sd_sb.sb_master_dir.no_addr);
+	if (!sdp->gfs1 &&
+	    (sdp->master_dir->i_di.di_header.mh_magic != GFS2_MAGIC ||
+	     sdp->master_dir->i_di.di_header.mh_type != GFS2_METATYPE_DI ||
+	     !sdp->master_dir->i_di.di_size)) {
 		inode_put(&sdp->master_dir);
 		rebuild_master(sdp);
 		sdp->master_dir = inode_read(sdp,
@@ -1188,11 +1360,15 @@ int initialize(struct gfs2_sbd *sdp, int force_check, int preen,
 	/* Look up the "per_node" inode.  If there are journals missing, we
 	   need to figure out what's missing from per_node. And we need all
 	   our journals to be there before we can replay them. */
-	lookup_per_node(sdp, 0);
+	if (!sdp->gfs1)
+		lookup_per_node(sdp, 0);
 
 	/* verify various things */
 
-	if (replay_journals(sdp, preen, force_check, &clean_journals)) {
+	if (sdp->gfs1) {
+		if (reconstruct_journals(sdp))
+			return FSCK_ERROR;
+	} else if (replay_journals(sdp, preen, force_check, &clean_journals)) {
 		if (!opts.no && preen_is_safe(sdp, preen, force_check))
 			block_mounters(sdp, 0);
 		stack;
diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index 0de4f8e..af4189f 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -28,7 +28,7 @@ static void add_dotdot(struct gfs2_inode *ip)
 	/* If there's a pre-existing .. directory entry, we have to
 	   back out the links. */
 	di = dirtree_find(ip->i_di.di_num.no_addr);
-	if (di && !valid_block(sdp, di->dotdot_parent) == 0) {
+	if (di && valid_block(sdp, di->dotdot_parent)) {
 		struct gfs2_inode *dip;
 
 		log_debug(_("Directory %lld (0x%llx) already had a "
@@ -75,7 +75,47 @@ static void add_dotdot(struct gfs2_inode *ip)
 		log_warn( _("add_inode_to_lf:  Unable to remove "
 			    "\"..\" directory entry.\n"));
 
-	dir_add(ip, "..", 2, &(lf_dip->i_di.di_num), DT_DIR);
+	dir_add(ip, "..", 2, &(lf_dip->i_di.di_num),
+		(sdp->gfs1 ? GFS_FILE_DIR : DT_DIR));
+}
+
+static uint64_t find_free_blk(struct gfs2_sbd *sdp)
+{
+	osi_list_t *tmp, *head;
+	struct rgrp_list *rl = NULL;
+	struct gfs2_rindex *ri;
+	struct gfs2_rgrp *rg;
+	unsigned int block, bn = 0, x = 0, y = 0;
+	unsigned int state;
+	struct gfs2_buffer_head *bh;
+
+	memset(&rg, 0, sizeof(rg));
+	for (head = &sdp->rglist, tmp = head->next; tmp != head;
+	     tmp = tmp->next) {
+		rl = osi_list_entry(tmp, struct rgrp_list, list);
+		if (rl->rg.rg_free)
+			break;
+	}
+
+	if (tmp == head)
+		return 0;
+
+	ri = &rl->ri;
+	rg = &rl->rg;
+
+	for (block = 0; block < ri->ri_length; block++) {
+		bh = rl->bh[block];
+		x = (block) ? sizeof(struct gfs2_meta_header) : sizeof(struct gfs2_rgrp);
+
+		for (; x < sdp->bsize; x++)
+			for (y = 0; y < GFS2_NBBY; y++) {
+				state = (bh->b_data[x] >> (GFS2_BIT_SIZE * y)) & 0x03;
+				if (state == GFS2_BLKST_FREE)
+					return ri->ri_data0 + bn;
+				bn++;
+			}
+	}
+	return 0;
 }
 
 /* add_inode_to_lf - Add dir entry to lost+found for the inode
@@ -93,16 +133,33 @@ int add_inode_to_lf(struct gfs2_inode *ip){
 	uint64_t lf_blocks;
 	struct gfs2_sbd *sdp = ip->i_sbd;
 	struct dir_info *di;
+	uint32_t mode;
 
 	if (!lf_dip) {
 		uint8_t q;
 
 		log_info( _("Locating/Creating lost+found directory\n"));
 
-		lf_dip = createi(sdp->md.rooti, "lost+found",
-				 S_IFDIR | 0700, 0);
+		/* if this is gfs1, we have to trick createi into using
+		   no_formal_ino = no_addr, so we set next_inum to the
+		   free block we're about to allocate. */
+		if (sdp->gfs1)
+			sdp->md.next_inum = find_free_blk(sdp);
+		mode = (sdp->gfs1 ? DT2IF(GFS_FILE_DIR) : S_IFDIR) | 0700;
+		if (sdp->gfs1)
+			lf_dip = gfs_createi(sdp->md.rooti, "lost+found",
+					     mode, 0);
+		else
+			lf_dip = createi(sdp->md.rooti, "lost+found",
+					 S_IFDIR | 0700, 0);
+		if (lf_dip == NULL) {
+			log_crit(_("Error creating lost+found: %s\n"),
+			         strerror(errno));
+			exit(FSCK_ERROR);
+		}
+
 		/* createi will have incremented the di_nlink link count for
-		   the root directory.  We must increment the nlink value
+		   the root directory.  We must set the nlink value
 		   in the hash table to keep them in sync so that pass4 can
 		   detect and fix any descrepancies. */
 		set_di_nlink(sdp->md.rooti);
@@ -129,7 +186,9 @@ int add_inode_to_lf(struct gfs2_inode *ip){
 			/* lost+found link for '..' back to root */
 			incr_link_count(lf_dip->i_di.di_num.no_addr,
 					sdp->md.rooti->i_di.di_num.no_addr,
-					"\"..\"");
+				       "\"..\"");
+			if (sdp->gfs1)
+				lf_dip->i_di.__pad1 = GFS_FILE_DIR;
 		}
 		log_info( _("lost+found directory is dinode %lld (0x%llx)\n"),
 			  (unsigned long long)lf_dip->i_di.di_num.no_addr,
@@ -147,47 +206,52 @@ int add_inode_to_lf(struct gfs2_inode *ip){
 	}
 	lf_blocks = lf_dip->i_di.di_blocks;
 
-	switch(ip->i_di.di_mode & S_IFMT){
+	if (sdp->gfs1)
+		mode = gfs_to_gfs2_mode(ip->i_di.__pad1);
+	else
+		mode = ip->i_di.di_mode & S_IFMT;
+
+	switch (mode) {
 	case S_IFDIR:
 		add_dotdot(ip);
 		sprintf(tmp_name, "lost_dir_%llu",
 			(unsigned long long)ip->i_di.di_num.no_addr);
-		inode_type = DT_DIR;
+		inode_type = (sdp->gfs1 ? GFS_FILE_DIR : DT_DIR);
 		break;
 	case S_IFREG:
 		sprintf(tmp_name, "lost_file_%llu",
 			(unsigned long long)ip->i_di.di_num.no_addr);
-		inode_type = DT_REG;
+		inode_type = (sdp->gfs1 ? GFS_FILE_REG : DT_REG);
 		break;
 	case S_IFLNK:
 		sprintf(tmp_name, "lost_link_%llu",
 			(unsigned long long)ip->i_di.di_num.no_addr);
-		inode_type = DT_LNK;
+		inode_type = (sdp->gfs1 ? GFS_FILE_LNK : DT_LNK);
 		break;
 	case S_IFBLK:
 		sprintf(tmp_name, "lost_blkdev_%llu",
 			(unsigned long long)ip->i_di.di_num.no_addr);
-		inode_type = DT_BLK;
+		inode_type = (sdp->gfs1 ? GFS_FILE_BLK : DT_BLK);
 		break;
 	case S_IFCHR:
 		sprintf(tmp_name, "lost_chrdev_%llu",
 			(unsigned long long)ip->i_di.di_num.no_addr);
-		inode_type = DT_CHR;
+		inode_type = (sdp->gfs1 ? GFS_FILE_CHR : DT_CHR);
 		break;
 	case S_IFIFO:
 		sprintf(tmp_name, "lost_fifo_%llu",
 			(unsigned long long)ip->i_di.di_num.no_addr);
-		inode_type = DT_FIFO;
+		inode_type = (sdp->gfs1 ? GFS_FILE_FIFO : DT_FIFO);
 		break;
 	case S_IFSOCK:
 		sprintf(tmp_name, "lost_socket_%llu",
 			(unsigned long long)ip->i_di.di_num.no_addr);
-		inode_type = DT_SOCK;
+		inode_type = (sdp->gfs1 ? GFS_FILE_SOCK : DT_SOCK);
 		break;
 	default:
 		sprintf(tmp_name, "lost_%llu",
 			(unsigned long long)ip->i_di.di_num.no_addr);
-		inode_type = DT_REG;
+		inode_type = (sdp->gfs1 ? GFS_FILE_REG : DT_REG);
 		break;
 	}
 
@@ -202,7 +266,7 @@ int add_inode_to_lf(struct gfs2_inode *ip){
 	incr_link_count(ip->i_di.di_num.no_addr, lf_dip->i_di.di_num.no_addr,
 			_("from lost+found"));
 	/* If it's a directory, lost+found is back-linked to it via .. */
-	if (S_ISDIR(ip->i_di.di_mode))
+	if (is_dir(&ip->i_di, sdp->gfs1))
 		incr_link_count(lf_dip->i_di.di_num.no_addr,
 				ip->i_di.di_mode, _("to lost+found"));
 
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index 5dae096..75ccc11 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -33,6 +33,7 @@ struct osi_root dup_blocks = (struct osi_root) { NULL, };
 struct osi_root dirtree = (struct osi_root) { NULL, };
 struct osi_root inodetree = (struct osi_root) { NULL, };
 int dups_found = 0, dups_found_first = 0;
+struct gfs_sb *sbd1 = NULL;
 
 /* This function is for libgfs2's sake.                                      */
 void print_it(const char *label, const char *fmt, const char *fmt2, ...)
@@ -153,6 +154,10 @@ static void check_statfs(struct gfs2_sbd *sdp)
 	char buf[sizeof(struct gfs2_statfs_change)];
 	int count;
 
+	if (sdp->gfs1 && !sdp->md.statfs->i_di.di_size) {
+		log_info("This GFS1 file system is not using fast_statfs.\n");
+		return;
+	}
 	/* Read the current statfs values */
 	count = gfs2_readi(sdp->md.statfs, buf, 0,
 			   sdp->md.statfs->i_di.di_size);
@@ -338,16 +343,19 @@ int main(int argc, char **argv)
 		check_statfs(sdp);
 
 	/* Free up our system inodes */
-	inode_put(&sdp->md.inum);
+	if (!sdp->gfs1)
+		inode_put(&sdp->md.inum);
 	inode_put(&sdp->md.statfs);
 	for (j = 0; j < sdp->md.journals; j++)
 		inode_put(&sdp->md.journal[j]);
 	inode_put(&sdp->md.jiinode);
 	inode_put(&sdp->md.riinode);
 	inode_put(&sdp->md.qinode);
-	inode_put(&sdp->md.pinode);
+	if (!sdp->gfs1)
+		inode_put(&sdp->md.pinode);
 	inode_put(&sdp->md.rooti);
-	inode_put(&sdp->master_dir);
+	if (!sdp->gfs1)
+		inode_put(&sdp->master_dir);
 	if (lf_dip)
 		inode_put(&lf_dip);
 
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index b25b40d..2ddf7dd 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -40,17 +40,19 @@ int check_n_fix_bitmap(struct gfs2_sbd *sdp, uint64_t blk,
 			 (unsigned long long)blk, (unsigned long long)blk);
 		return -1;
 	}
-	new_bitmap_state = blockmap_to_bitmap(new_blockmap_state);
+	new_bitmap_state = blockmap_to_bitmap(new_blockmap_state, sdp->gfs1);
 	if (old_bitmap_state != new_bitmap_state) {
-		const char *allocdesc[] = {"free space", "data", "unlinked",
-					   "inode", "reserved"};
+		const char *allocdesc[2][5] = { /* gfs2 descriptions */
+			{"free", "data", "unlinked", "inode", "reserved"},
+			/* gfs1 descriptions: */
+			{"free", "data", "free meta", "metadata", "reserved"}};
 
 		/* Keep these messages as short as possible, or the output
 		   gets to be huge and unmanageable. */
 		log_err( _("Block %llu (0x%llx) was '%s', should be %s.\n"),
 			 (unsigned long long)blk, (unsigned long long)blk,
-			 allocdesc[new_bitmap_state],
-			 allocdesc[old_bitmap_state]);
+			 allocdesc[sdp->gfs1][old_bitmap_state],
+			 allocdesc[sdp->gfs1][new_bitmap_state]);
 		if (query( _("Fix the bitmap? (y/n)"))) {
 			/* If the new bitmap state is free (and therefore the
 			   old state was not) we have to add to the free
@@ -75,10 +77,18 @@ int check_n_fix_bitmap(struct gfs2_sbd *sdp, uint64_t blk,
 						inodetree_delete(ii);
 				}
 				rgd->rg.rg_free++;
-				gfs2_rgrp_out(&rgd->rg, rgd->bh[0]);
+				if (sdp->gfs1)
+					gfs_rgrp_out((struct gfs_rgrp *)
+						     &rgd->rg, rgd->bh[0]);
+				else
+					gfs2_rgrp_out(&rgd->rg, rgd->bh[0]);
 			} else if (old_bitmap_state == GFS2_BLKST_FREE) {
 				rgd->rg.rg_free--;
-				gfs2_rgrp_out(&rgd->rg, rgd->bh[0]);
+				if (sdp->gfs1)
+					gfs_rgrp_out((struct gfs_rgrp *)
+						     &rgd->rg, rgd->bh[0]);
+				else
+					gfs2_rgrp_out(&rgd->rg, rgd->bh[0]);
 			}
 			log_err( _("The bitmap was fixed.\n"));
 		} else {
@@ -168,9 +178,28 @@ struct duptree *dupfind(uint64_t block)
 
 struct gfs2_inode *fsck_system_inode(struct gfs2_sbd *sdp, uint64_t block)
 {
+	int j;
+
 	if (lf_dip && lf_dip->i_di.di_num.no_addr == block)
 		return lf_dip;
-	return is_system_inode(sdp, block);
+	if (!sdp->gfs1)
+		return is_system_inode(sdp, block);
+
+	if (sdp->md.statfs && block == sdp->md.statfs->i_di.di_num.no_addr)
+		return sdp->md.statfs;
+	if (sdp->md.jiinode && block == sdp->md.jiinode->i_di.di_num.no_addr)
+		return sdp->md.jiinode;
+	if (sdp->md.riinode && block == sdp->md.riinode->i_di.di_num.no_addr)
+		return sdp->md.riinode;
+	if (sdp->md.qinode && block == sdp->md.qinode->i_di.di_num.no_addr)
+		return sdp->md.qinode;
+	if (sdp->md.rooti && block == sdp->md.rooti->i_di.di_num.no_addr)
+		return sdp->md.rooti;
+	for (j = 0; j < sdp->md.journals; j++)
+		if (sdp->md.journal && sdp->md.journal[j] &&
+		    block == sdp->md.journal[j]->i_di.di_num.no_addr)
+			return sdp->md.journal[j];
+	return NULL;
 }
 
 /* fsck_load_inode - same as gfs2_load_inode() in libgfs2 but system inodes
@@ -182,6 +211,8 @@ struct gfs2_inode *fsck_load_inode(struct gfs2_sbd *sdp, uint64_t block)
 	ip = fsck_system_inode(sdp, block);
 	if (ip)
 		return ip;
+	if (sdp->gfs1)
+		return gfs_inode_read(sdp, block);
 	return inode_read(sdp, block);
 }
 
@@ -196,6 +227,8 @@ struct gfs2_inode *fsck_inode_get(struct gfs2_sbd *sdp,
 	if (sysip)
 		return sysip;
 
+	if (sdp->gfs1)
+		return gfs_inode_get(sdp, bh);
 	return inode_get(sdp, bh);
 }
 
@@ -432,12 +465,13 @@ static int check_entries(struct gfs2_inode *ip, struct gfs2_buffer_head *bh,
 	return 0;
 }
 
-/* Process a bad leaf pointer and ask to repair the first time.      */
-/* The repair process involves extending the previous leaf's entries */
-/* so that they replace the bad ones.  We have to hack up the old    */
-/* leaf a bit, but it's better than deleting the whole directory,    */
-/* which is what used to happen before.                              */
-static int warn_and_patch(struct gfs2_inode *ip, uint64_t *leaf_no,
+/* warn_and_patch - Warn the user of an error and ask permission to fix it
+ * Process a bad leaf pointer and ask to repair the first time.
+ * The repair process involves extending the previous leaf's entries
+ * so that they replace the bad ones.  We have to hack up the old
+ * leaf a bit, but it's better than deleting the whole directory,
+ * which is what used to happen before. */
+static int warn_and_patch(struct gfs2_inode *ip, uint64_t *leaf_no, 
 			  uint64_t *bad_leaf, uint64_t old_leaf,
 			  uint64_t first_ok_leaf, int pindex, const char *msg)
 {
@@ -539,7 +573,7 @@ static int check_leaf(struct gfs2_inode *ip, int lindex,
 		goto out_copy_old_leaf;
 	}
 
-	if (pass->check_dentry && S_ISDIR(ip->i_di.di_mode)) {
+	if (pass->check_dentry && is_dir(&ip->i_di, sdp->gfs1)) {
 		error = check_entries(ip, lbh, DIR_EXHASH, &count, pass);
 
 		if (skip_this_pass || fsck_abort)
@@ -1072,7 +1106,7 @@ static int build_and_check_metalist(struct gfs2_inode *ip, osi_list_t *mlp,
 	   because it checks everything through the hash table using
 	   "depth" field calculations. However, we still have to check the
 	   indirect blocks, even if the height == 1.  */
-	if (S_ISDIR(ip->i_di.di_mode))
+	if (is_dir(&ip->i_di, ip->i_sbd->gfs1))
 		height++;
 
 	/* if (<there are no indirect blocks to check>) */
@@ -1080,12 +1114,15 @@ static int build_and_check_metalist(struct gfs2_inode *ip, osi_list_t *mlp,
 		return 0;
 	for (h = 1; h < height; h++) {
 		if (h > 1) {
-			if (S_ISDIR(ip->i_di.di_mode) &&
+			if (is_dir(&ip->i_di, ip->i_sbd->gfs1) &&
 			    h == ip->i_di.di_height + 1)
 				iblk_type = GFS2_METATYPE_JD;
 			else
 				iblk_type = GFS2_METATYPE_IN;
-			head_size = sizeof(struct gfs2_meta_header);
+			if (ip->i_sbd->gfs1)
+				head_size = sizeof(struct gfs_indirect);
+			else
+				head_size = sizeof(struct gfs2_meta_header);
 		} else {
 			iblk_type = GFS2_METATYPE_DI;
 			head_size = sizeof(struct gfs2_dinode);
@@ -1176,7 +1213,7 @@ static int check_data(struct gfs2_inode *ip, struct metawalk_fxns *pass,
 		if (skip_this_pass || fsck_abort)
 			return error;
 		block =  be64_to_cpu(*ptr);
-		/* It's important that we don't call !valid_block and
+		/* It's important that we don't call valid_block() and
 		   bypass calling check_data on invalid blocks because that
 		   would defeat the rangecheck_block related functions in
 		   pass1. Therefore the individual check_data functions
@@ -1207,7 +1244,7 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 	uint64_t blks_checked = 0;
 	int error, rc;
 
-	if (!height && !S_ISDIR(ip->i_di.di_mode))
+	if (!height && !is_dir(&ip->i_di, ip->i_sbd->gfs1))
 		return 0;
 
 	for (i = 0; i < GFS2_MAX_META_HEIGHT; i++)
@@ -1223,7 +1260,7 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 	/* For directories, we've already checked the "data" blocks which
 	 * comprise the directory hash table, so we perform the directory
 	 * checks and exit. */
-        if (S_ISDIR(ip->i_di.di_mode)) {
+        if (is_dir(&ip->i_di, ip->i_sbd->gfs1)) {
 		free_metalist(ip, &metalist[0]);
 		if (!(ip->i_di.di_flags & GFS2_DIF_EXHASH))
 			return 0;
@@ -1266,7 +1303,10 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 					brelse(bh);
 				continue;
 			}
-			head_size = sizeof(struct gfs2_meta_header);
+			if (ip->i_sbd->gfs1)
+				head_size = sizeof(struct gfs_indirect);
+			else
+				head_size = sizeof(struct gfs2_meta_header);
 		} else {
 			/* if this isn't really a dinode, skip it */
 			if (gfs2_check_meta(bh, GFS2_METATYPE_DI)) {
@@ -1437,7 +1477,7 @@ static int alloc_metalist(struct gfs2_inode *ip, uint64_t block,
 	   after the bitmap has been set but before the blockmap has. */
 	*bh = bread(ip->i_sbd, block);
 	q = block_type(block);
-	if (blockmap_to_bitmap(q) == GFS2_BLKST_FREE) { /* If not marked yet */
+	if (blockmap_to_bitmap(q, ip->i_sbd->gfs1) == GFS2_BLKST_FREE) {
 		log_debug(_("%s reference to new metadata block "
 			    "%lld (0x%llx) is now marked as indirect.\n"),
 			  desc, (unsigned long long)block,
@@ -1456,7 +1496,7 @@ static int alloc_data(struct gfs2_inode *ip, uint64_t block, void *private)
 	/* We can't check the bitmap here because this function is called
 	   after the bitmap has been set but before the blockmap has. */
 	q = block_type(block);
-	if (blockmap_to_bitmap(q) == GFS2_BLKST_FREE) { /* If not marked yet */
+	if (blockmap_to_bitmap(q, ip->i_sbd->gfs1) == GFS2_BLKST_FREE) {
 		log_debug(_("%s reference to new data block "
 			    "%lld (0x%llx) is now marked as data.\n"),
 			  desc, (unsigned long long)block,
@@ -1474,7 +1514,7 @@ static int alloc_leaf(struct gfs2_inode *ip, uint64_t block, void *private)
 	/* We can't check the bitmap here because this function is called
 	   after the bitmap has been set but before the blockmap has. */
 	q = block_type(block);
-	if (blockmap_to_bitmap(q) == GFS2_BLKST_FREE) /* If not marked yet */
+	if (blockmap_to_bitmap(q, ip->i_sbd->gfs1) == GFS2_BLKST_FREE)
 		fsck_blockmap_set(ip, block, _("newly allocated leaf"),
 				  gfs2_leaf_blk);
 	return 0;
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index c0b7420..876078e 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -26,6 +26,8 @@
 #include "link.h"
 #include "metawalk.h"
 
+struct special_blocks gfs1_rindex_blks;
+
 struct block_count {
 	uint64_t indir_count;
 	uint64_t data_count;
@@ -174,9 +176,10 @@ static int resuscitate_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 			 (unsigned long long)ip->i_di.di_num.no_addr);
 		return 0;
 	}
-	if (block == sdp->md.jiinode->i_di.di_num.no_addr ||
-	    block == sdp->md.pinode->i_di.di_num.no_addr ||
-	    block == sdp->master_dir->i_di.di_num.no_addr)
+	if (block == sdp->md.jiinode->i_di.di_num.no_addr)
+		dinode_type = gfs2_inode_dir;
+	else if (!sdp->gfs1 && (block == sdp->md.pinode->i_di.di_num.no_addr ||
+				block == sdp->master_dir->i_di.di_num.no_addr))
 		dinode_type = gfs2_inode_dir;
 	else
 		dinode_type = gfs2_inode_file;
@@ -239,8 +242,12 @@ static int fix_leaf_pointers(struct gfs2_inode *dip, int *lindex,
 	   the last 8 of them.  If we have 7, write the last 4, etc.
 	   We need to write these starting at the current lindex and adjust
 	   lindex accordingly. */
-	count = gfs2_writei(dip, ptrbuf + (off_by * sizeof(uint64_t)),
-			    start_lindex * sizeof(uint64_t), bufsize);
+	if (dip->i_sbd->gfs1)
+		count = gfs1_writei(dip, ptrbuf + (off_by * sizeof(uint64_t)),
+				    start_lindex * sizeof(uint64_t), bufsize);
+	else
+		count = gfs2_writei(dip, ptrbuf + (off_by * sizeof(uint64_t)),
+				    start_lindex * sizeof(uint64_t), bufsize);
 	if (count != bufsize) {
 		log_err( _("Error: bad read while fixing leaf pointers.\n"));
 		free(ptrbuf);
@@ -248,8 +255,12 @@ static int fix_leaf_pointers(struct gfs2_inode *dip, int *lindex,
 	}
 	/* Now zero out the hole left at the end */
 	memset(ptrbuf, 0, off_by * sizeof(uint64_t));
-	gfs2_writei(dip, ptrbuf, (start_lindex * sizeof(uint64_t)) +
-		    bufsize, off_by * sizeof(uint64_t));
+	if (dip->i_sbd->gfs1)
+		gfs1_writei(dip, ptrbuf, (start_lindex * sizeof(uint64_t)) +
+			    bufsize, off_by * sizeof(uint64_t));
+	else
+		gfs2_writei(dip, ptrbuf, (start_lindex * sizeof(uint64_t)) +
+			    bufsize, off_by * sizeof(uint64_t));
 	free(ptrbuf);
 	*lindex -= off_by; /* adjust leaf index to account for the change */
 	return 0;
@@ -381,7 +392,7 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block,
 
 		return 1;
 	}
-	if (S_ISDIR(ip->i_di.di_mode) && h == ip->i_di.di_height) {
+	if (is_dir(&ip->i_di, ip->i_sbd->gfs1) && h == ip->i_di.di_height) {
 		iblk_type = GFS2_METATYPE_JD;
 		blktypedesc = _("a directory hash table block");
 	} else {
@@ -449,7 +460,7 @@ static int undo_check_metalist(struct gfs2_inode *ip, uint64_t block,
 				  _("itself"), gfs2_block_free);
 		return 1;
 	}
-	if (S_ISDIR(ip->i_di.di_mode) && h == ip->i_di.di_height)
+	if (is_dir(&ip->i_di, ip->i_sbd->gfs1) && h == ip->i_di.di_height)
 		iblk_type = GFS2_METATYPE_JD;
 	else
 		iblk_type = GFS2_METATYPE_IN;
@@ -526,7 +537,22 @@ static int check_data(struct gfs2_inode *ip, uint64_t block, void *private)
 		bc->data_count++;
 		return 1;
 	}
-	fsck_blockmap_set(ip, block, _("data"), gfs2_block_used);
+	/* In gfs1, rgrp indirect blocks are marked in the bitmap as "meta".
+	   In gfs2, "meta" is only for dinodes. So here we dummy up the
+	   blocks so that the bitmap isn't changed improperly. */
+	if (ip->i_sbd->gfs1 && ip == ip->i_sbd->md.riinode) {
+		log_info(_("Block %lld (0x%llx) is a GFS1 rindex block\n"),
+			 (unsigned long long)block, (unsigned long long)block);
+		gfs2_special_set(&gfs1_rindex_blks, block);
+		fsck_blockmap_set(ip, block, _("rgrp"), gfs2_indir_blk);
+		/*gfs2_meta_rgrp);*/
+	} else if (ip->i_sbd->gfs1 && ip->i_di.di_flags & GFS2_DIF_JDATA) {
+		log_info(_("Block %lld (0x%llx) is a GFS1 journaled data "
+			   "block\n"),
+			 (unsigned long long)block, (unsigned long long)block);
+		fsck_blockmap_set(ip, block, _("jdata"), gfs2_jdata);
+	} else
+		fsck_blockmap_set(ip, block, _("data"), gfs2_block_used);
 	bc->data_count++;
 	return 0;
 }
@@ -1020,6 +1046,7 @@ static int invalidate_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
  * messing with them because we don't want to mark a block as a
  * duplicate (for example) until we know if the pointers in general can
  * be trusted. Thus it needs to be in a separate loop.
+ * Returns: 0 if good range, otherwise != 0
  */
 static int rangecheck_block(struct gfs2_inode *ip, uint64_t block,
 			    struct gfs2_buffer_head **bh,
@@ -1112,6 +1139,7 @@ static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip)
 	struct block_count bc = {0};
 	long bad_pointers;
 	uint64_t block = ip->i_bh->b_blocknr;
+	uint32_t mode;
 
 	bad_pointers = 0L;
 
@@ -1132,8 +1160,12 @@ static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip)
 		return 0;
 	}
 
-	switch(ip->i_di.di_mode & S_IFMT) {
+	if (sdp->gfs1)
+		mode = gfs_to_gfs2_mode(ip->i_di.__pad1);
+	else
+		mode = ip->i_di.di_mode & S_IFMT;
 
+	switch (mode) {
 	case S_IFDIR:
 		if (fsck_blockmap_set(ip, block, _("directory"),
 				      gfs2_inode_dir))
@@ -1142,8 +1174,7 @@ static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip)
 			goto bad_dinode;
 		break;
 	case S_IFREG:
-		if (fsck_blockmap_set(ip, block, _("file"),
-				      gfs2_inode_file))
+		if (fsck_blockmap_set(ip, block, _("file"), gfs2_inode_file))
 			goto bad_dinode;
 		break;
 	case S_IFLNK:
@@ -1196,8 +1227,7 @@ static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip)
 	if (set_di_nlink(ip))
 		goto bad_dinode;
 
-	if (S_ISDIR(ip->i_di.di_mode) &&
-	    (ip->i_di.di_flags & GFS2_DIF_EXHASH)) {
+	if (is_dir(&ip->i_di, sdp->gfs1) && (ip->i_di.di_flags & GFS2_DIF_EXHASH)) {
 		if (((1 << ip->i_di.di_depth) * sizeof(uint64_t)) != ip->i_di.di_size){
 			log_warn( _("Directory dinode block #%llu (0x%llx"
 				 ") has bad depth.  Found %u, Expected %u\n"),
@@ -1396,7 +1426,7 @@ static int check_system_inode(struct gfs2_sbd *sdp,
 			return -1;
 		}
 	}
-	if (S_ISDIR((*sysinode)->i_di.di_mode)) {
+	if (is_dir(&(*sysinode)->i_di, sdp->gfs1)) {
 		struct block_count bc = {0};
 
 		sysdir_fxns.private = &bc;
@@ -1413,12 +1443,17 @@ static int check_system_inode(struct gfs2_sbd *sdp,
 static int build_a_journal(struct gfs2_sbd *sdp)
 {
 	char name[256];
+	int err = 0;
 
 	/* First, try to delete the journal if it's in jindex */
 	sprintf(name, "journal%u", sdp->md.journals);
 	gfs2_dirent_del(sdp->md.jiinode, name, strlen(name));
 	/* Now rebuild it */
-	build_journal(sdp, sdp->md.journals, sdp->md.jiinode);
+	err = build_journal(sdp, sdp->md.journals, sdp->md.jiinode);
+	if (err) {
+		log_crit(_("Error %d building journal\n"), err);
+		exit(FSCK_ERROR);
+	}
 	return 0;
 }
 
@@ -1432,13 +1467,15 @@ static int check_system_inodes(struct gfs2_sbd *sdp)
 	/* Mark the master system dinode as a "dinode" in the block map.
 	   All other system dinodes in master will be taken care of by function
 	   resuscitate_metalist.  But master won't since it has no parent.*/
-	fsck_blockmap_set(sdp->master_dir,
-			  sdp->master_dir->i_di.di_num.no_addr,
-			  "master", gfs2_inode_dir);
-	if (check_system_inode(sdp, &sdp->master_dir, "master", build_master,
-			       gfs2_inode_dir)) {
-		stack;
-		return -1;
+	if (!sdp->gfs1) {
+		fsck_blockmap_set(sdp->master_dir,
+				  sdp->master_dir->i_di.di_num.no_addr,
+				  "master", gfs2_inode_dir);
+		if (check_system_inode(sdp, &sdp->master_dir, "master",
+				       build_master, gfs2_inode_dir)) {
+			stack;
+			return -1;
+		}
 	}
 	/* Mark the root dinode as a "dinode" in the block map as we did
 	   for master, since it has no parent. */
@@ -1449,7 +1486,8 @@ static int check_system_inodes(struct gfs2_sbd *sdp)
 		stack;
 		return -1;
 	}
-	if (check_system_inode(sdp, &sdp->md.inum, "inum", build_inum,
+	if (!sdp->gfs1 &&
+	    check_system_inode(sdp, &sdp->md.inum, "inum", build_inum,
 			       gfs2_inode_file)) {
 		stack;
 		return -1;
@@ -1460,7 +1498,7 @@ static int check_system_inodes(struct gfs2_sbd *sdp)
 		return -1;
 	}
 	if (check_system_inode(sdp, &sdp->md.jiinode, "jindex", build_jindex,
-			       gfs2_inode_dir)) {
+			       (sdp->gfs1 ? gfs2_inode_file : gfs2_inode_dir))) {
 		stack;
 		return -1;
 	}
@@ -1474,7 +1512,8 @@ static int check_system_inodes(struct gfs2_sbd *sdp)
 		stack;
 		return -1;
 	}
-	if (check_system_inode(sdp, &sdp->md.pinode, "per_node",
+	if (!sdp->gfs1 &&
+	    check_system_inode(sdp, &sdp->md.pinode, "per_node",
 			       build_per_node, gfs2_inode_dir)) {
 		stack;
 		return -1;
@@ -1482,6 +1521,21 @@ static int check_system_inodes(struct gfs2_sbd *sdp)
 	/* We have to play a trick on build_journal:  We swap md.journals
 	   in order to keep a count of which journal we need to build. */
 	journal_count = sdp->md.journals;
+	/* gfs1's journals aren't dinode, they're just a bunch of blocks. */
+	if (sdp->gfs1) {
+		/* gfs1 has four dinodes that are set in the superblock and
+		   therefore not linked to anything else. We need to adjust
+		   the link counts so pass4 doesn't get confused. */
+		incr_link_count(sdp->md.statfs->i_di.di_num.no_addr, 0,
+				_("gfs1 statfs inode"));
+		incr_link_count(sdp->md.jiinode->i_di.di_num.no_addr, 0,
+				_("gfs1 jindex inode"));
+		incr_link_count(sdp->md.riinode->i_di.di_num.no_addr, 0,
+				_("gfs1 rindex inode"));
+		incr_link_count(sdp->md.qinode->i_di.di_num.no_addr, 0,
+				_("gfs1 quota inode"));
+		return 0;
+	}
 	for (sdp->md.journals = 0; sdp->md.journals < journal_count;
 	     sdp->md.journals++) {
 		char jname[16];
@@ -1523,6 +1577,8 @@ int pass1(struct gfs2_sbd *sdp)
 	uint64_t offset;
 	uint64_t rg_count = 0;
 
+	osi_list_init(&gfs1_rindex_blks.list);
+
 	/* FIXME: In the gfs fsck, we had to mark things like the
 	 * journals and indices and such as 'other_meta' - in gfs2,
 	 * the journals are files and are found in the normal file
@@ -1553,6 +1609,7 @@ int pass1(struct gfs2_sbd *sdp)
 			if (gfs2_blockmap_set(bl, rgd->ri.ri_addr + i,
 					      gfs2_indir_blk)) {
 				stack;
+				gfs2_special_free(&gfs1_rindex_blks);
 				return FSCK_ERROR;
 			}
 			/* rgrps and bitmaps don't have bits to represent
@@ -1568,13 +1625,25 @@ int pass1(struct gfs2_sbd *sdp)
 		while (1) {
 			/* "block" is relative to the entire file system */
 			/* Get the next dinode in the file system, according
-			   to the bitmap.  This should ONLY be dinodes. */
+			   to the bitmap.  This should ONLY be dinodes unless
+			   it's GFS1, in which case it can be any metadata. */
 			if (gfs2_next_rg_meta(rgd, &block, first))
 				break;
+			/* skip gfs1 rindex indirect blocks */
+			if (sdp->gfs1 && blockfind(&gfs1_rindex_blks, block)) {
+				log_debug(_("Skipping rindex indir block "
+					    "%lld (0x%llx)\n"),
+					  (unsigned long long)block,
+					  (unsigned long long)block);
+				first = 0;
+				continue;
+			}
 			warm_fuzzy_stuff(block);
 
-			if (fsck_abort) /* if asked to abort */
+			if (fsck_abort) { /* if asked to abort */
+				gfs2_special_free(&gfs1_rindex_blks);
 				return FSCK_OK;
+			}
 			if (skip_this_pass) {
 				printf( _("Skipping pass 1 is not a good idea.\n"));
 				skip_this_pass = FALSE;
@@ -1594,6 +1663,31 @@ int pass1(struct gfs2_sbd *sdp)
 			  " (0x%" PRIx64 ")\n"), block, block);*/
 
 			if (gfs2_check_meta(bh, GFS2_METATYPE_DI)) {
+				/* In gfs2, a bitmap mark of 2 means an inode,
+				   but in gfs1 it means any metadata.  So if
+				   this is gfs1 and not an inode, it may be
+				   okay.  If it's non-dinode metadata, it will
+				   be referenced by an inode, so we need to
+				   skip it here and it will be sorted out
+				   when the referencing inode is checked. */
+				if (sdp->gfs1) {
+					uint32_t check_magic;
+
+					check_magic = ((struct
+							gfs2_meta_header *)
+						       (bh->b_data))->mh_magic;
+					if (be32_to_cpu(check_magic) ==
+					    GFS2_MAGIC) {
+						log_debug( _("Deferring GFS1 "
+							     "metadata block #"
+							     "%" PRIu64" (0x%"
+							     PRIx64 ")\n"),
+							   block, block);
+						brelse(bh);
+						first = 0;
+						continue;
+					}
+				}
 				log_err( _("Found invalid inode at block #"
 					   "%llu (0x%llx)\n"),
 					 (unsigned long long)block,
@@ -1602,6 +1696,7 @@ int pass1(struct gfs2_sbd *sdp)
 						      gfs2_block_free)) {
 					stack;
 					brelse(bh);
+					gfs2_special_free(&gfs1_rindex_blks);
 					return FSCK_ERROR;
 				}
 				check_n_fix_bitmap(sdp, block,
@@ -1609,6 +1704,7 @@ int pass1(struct gfs2_sbd *sdp)
 			} else if (handle_di(sdp, bh) < 0) {
 				stack;
 				brelse(bh);
+				gfs2_special_free(&gfs1_rindex_blks);
 				return FSCK_ERROR;
 			}
 			/* Ignore everything else - they should be hit by the
@@ -1621,6 +1717,19 @@ int pass1(struct gfs2_sbd *sdp)
 			brelse(bh);
 			first = 0;
 		}
+		/*
+		  For GFS1, we have to count the "free meta" blocks in the
+		  resource group and mark them specially so we can count them
+		  properly in pass5.
+		 */
+		if (!sdp->gfs1)
+			continue;
+		first = 1;
+		while (gfs2_next_rg_freemeta(rgd, &block, first) == 0) {
+			gfs2_blockmap_set(bl, block, gfs2_freemeta);
+			first = 0;
+		}
 	}
+	gfs2_special_free(&gfs1_rindex_blks);
 	return FSCK_OK;
 }
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index a66bd8b..003d696 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -357,7 +357,8 @@ static int find_block_ref(struct gfs2_sbd *sdp, uint64_t inode)
 	/* Exhash dir leafs will be checked by check_metatree (right after
 	   the "end:" label.)  But if this is a linear directory we need to
 	   check the dir with check_linear_dir. */
-	if (S_ISDIR(ip->i_di.di_mode) && !(ip->i_di.di_flags & GFS2_DIF_EXHASH))
+	if (is_dir(&ip->i_di, sdp->gfs1) &&
+	   !(ip->i_di.di_flags & GFS2_DIF_EXHASH))
 		error = check_linear_dir(ip, ip->i_bh, &find_dirents);
 
 	/* Check for ea references in the inode */
@@ -693,7 +694,7 @@ static int handle_dup_blk(struct gfs2_sbd *sdp, struct duptree *b)
 					  _("reference-repaired data"),
 					  gfs2_block_used);
 		} else if (id->reftypecount[ref_as_meta]) {
-			if (S_ISDIR(ip->i_di.di_mode))
+			if (is_dir(&ip->i_di, sdp->gfs1))
 				fsck_blockmap_set(ip, b->block,
 						  _("reference-repaired leaf"),
 						  gfs2_leaf_blk);
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index a4e8dca..7e20315 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -119,31 +119,32 @@ static const char *de_type_string(uint8_t de_type)
 	return de_types[3]; /* invalid */
 }
 
-static int check_file_type(uint8_t de_type, uint8_t blk_type)
+static int check_file_type(uint8_t de_type, uint8_t blk_type, int gfs1)
 {
 	switch(blk_type) {
 	case gfs2_inode_dir:
-		if (de_type != DT_DIR)
+		if (de_type != (gfs1 ? GFS_FILE_DIR : DT_DIR))
 			return 1;
 		break;
 	case gfs2_inode_file:
-		if (de_type != DT_REG)
+		if (de_type != (gfs1 ? GFS_FILE_REG : DT_REG))
 			return 1;
 		break;
 	case gfs2_inode_lnk:
-		if (de_type != DT_LNK)
+		if (de_type != (gfs1 ? GFS_FILE_LNK : DT_LNK))
 			return 1;
 		break;
 	case gfs2_inode_device:
-		if (de_type != DT_BLK && de_type != DT_CHR)
+		if ((de_type != (gfs1 ? GFS_FILE_BLK : DT_BLK)) &&
+		    (de_type != (gfs1 ? GFS_FILE_CHR : DT_CHR)))
 			return 1;
 		break;
 	case gfs2_inode_fifo:
-		if (de_type != DT_FIFO)
+		if (de_type != (gfs1 ? GFS_FILE_FIFO : DT_FIFO))
 			return 1;
 		break;
 	case gfs2_inode_sock:
-		if (de_type != DT_SOCK)
+		if (de_type != (gfs1 ? GFS_FILE_SOCK : DT_SOCK))
 			return 1;
 		break;
 	default:
@@ -391,7 +392,7 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 		goto nuke_dentry;
 	}
 
-	error = check_file_type(de->de_type, q);
+	error = check_file_type(de->de_type, q, sdp->gfs1);
 	if (error < 0) {
 		log_err( _("Error: directory entry type is "
 			   "incompatible with block type@block %lld "
@@ -664,7 +665,9 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
 			memcpy(filename, tmp_name, filename_len);
 			log_warn( _("Adding '.' entry\n"));
 			dir_add(sysinode, filename, filename_len,
-				&(sysinode->i_di.di_num), DT_DIR);
+				&(sysinode->i_di.di_num),
+				(sysinode->i_sbd->gfs1 ?
+				 GFS_FILE_DIR : DT_DIR));
 			if (cur_blks != sysinode->i_di.di_blocks)
 				reprocess_inode(sysinode, dirname);
 			/* This system inode is linked to itself via '.' */
@@ -706,8 +709,11 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
  */
 static inline int is_system_dir(struct gfs2_sbd *sdp, uint64_t block)
 {
-	if (block == sdp->md.rooti->i_di.di_num.no_addr ||
-	    block == sdp->md.jiinode->i_di.di_num.no_addr ||
+	if (block == sdp->md.rooti->i_di.di_num.no_addr)
+		return TRUE;
+	if (sdp->gfs1)
+		return FALSE;
+	if (block == sdp->md.jiinode->i_di.di_num.no_addr ||
 	    block == sdp->md.pinode->i_di.di_num.no_addr ||
 	    block == sdp->master_dir->i_di.di_num.no_addr)
 		return TRUE;
@@ -737,19 +743,22 @@ int pass2(struct gfs2_sbd *sdp)
 	int error = 0;
 
 	/* Check all the system directory inodes. */
-	if (check_system_dir(sdp->md.jiinode, "jindex", build_jindex)) {
+	if (!sdp->gfs1 &&
+	    check_system_dir(sdp->md.jiinode, "jindex", build_jindex)) {
 		stack;
 		return FSCK_ERROR;
 	}
 	if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
 		return FSCK_OK;
-	if (check_system_dir(sdp->md.pinode, "per_node", build_per_node)) {
+	if (!sdp->gfs1 &&
+	    check_system_dir(sdp->md.pinode, "per_node", build_per_node)) {
 		stack;
 		return FSCK_ERROR;
 	}
 	if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
 		return FSCK_OK;
-	if (check_system_dir(sdp->master_dir, "master", build_master)) {
+	if (!sdp->gfs1 &&
+	    check_system_dir(sdp->master_dir, "master", build_master)) {
 		stack;
 		return FSCK_ERROR;
 	}
@@ -870,7 +879,8 @@ int pass2(struct gfs2_sbd *sdp)
 
 				cur_blks = ip->i_di.di_blocks;
 				dir_add(ip, filename, filename_len,
-					&(ip->i_di.di_num), DT_DIR);
+					&(ip->i_di.di_num),
+					(sdp->gfs1 ? GFS_FILE_DIR : DT_DIR));
 				if (cur_blks != ip->i_di.di_blocks) {
 					char dirname[80];
 
diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c
index 51104b5..e1accc9 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -52,7 +52,8 @@ static int attach_dotdot_to(struct gfs2_sbd *sdp, uint64_t newdotdot,
 	else
 		decr_link_count(olddotdot, block, _("old \"..\""));
 	cur_blks = ip->i_di.di_blocks;
-	dir_add(ip, filename, filename_len, &pip->i_di.di_num, DT_DIR);
+	dir_add(ip, filename, filename_len, &pip->i_di.di_num,
+		(sdp->gfs1 ? GFS_FILE_DIR : DT_DIR));
 	if (cur_blks != ip->i_di.di_blocks) {
 		char dirname[80];
 
@@ -188,10 +189,38 @@ int pass3(struct gfs2_sbd *sdp)
 		log_info( _("Marking root inode connected\n"));
 		di->checked = 1;
 	}
-	di = dirtree_find(sdp->master_dir->i_di.di_num.no_addr);
-	if (di) {
-		log_info( _("Marking master directory inode connected\n"));
-		di->checked = 1;
+	if (sdp->gfs1) {
+		di = dirtree_find(sdp->md.statfs->i_di.di_num.no_addr);
+		if (di) {
+			log_info( _("Marking GFS1 statfs file inode "
+				    "connected\n"));
+			di->checked = 1;
+		}
+		di = dirtree_find(sdp->md.jiinode->i_di.di_num.no_addr);
+		if (di) {
+			log_info( _("Marking GFS1 jindex file inode "
+				    "connected\n"));
+			di->checked = 1;
+		}
+		di = dirtree_find(sdp->md.riinode->i_di.di_num.no_addr);
+		if (di) {
+			log_info( _("Marking GFS1 rindex file inode "
+				    "connected\n"));
+			di->checked = 1;
+		}
+		di = dirtree_find(sdp->md.qinode->i_di.di_num.no_addr);
+		if (di) {
+			log_info( _("Marking GFS1 quota file inode "
+				    "connected\n"));
+			di->checked = 1;
+		}
+	} else {
+		di = dirtree_find(sdp->master_dir->i_di.di_num.no_addr);
+		if (di) {
+			log_info( _("Marking master directory inode "
+				    "connected\n"));
+			di->checked = 1;
+		}
 	}
 
 	/* Go through the directory list, working up through the parents
diff --git a/gfs2/fsck/pass4.c b/gfs2/fsck/pass4.c
index 32dbb72..6d933e9 100644
--- a/gfs2/fsck/pass4.c
+++ b/gfs2/fsck/pass4.c
@@ -56,6 +56,13 @@ static int scan_inode_list(struct gfs2_sbd *sdp) {
 			log_crit( _("osi_tree broken in scan_info_list!!\n"));
 			exit(FSCK_ERROR);
 		}
+		/* Don't check reference counts on the special gfs files */
+		if (sdp->gfs1 &&
+		    ((ii->inode == sdp->md.riinode->i_di.di_num.no_addr) ||
+		     (ii->inode == sdp->md.jiinode->i_di.di_num.no_addr) ||
+		     (ii->inode == sdp->md.qinode->i_di.di_num.no_addr) ||
+		     (ii->inode == sdp->md.statfs->i_di.di_num.no_addr)))
+			continue;
 		if (ii->counted_links == 0) {
 			log_err( _("Found unlinked inode at %llu (0x%llx)\n"),
 				(unsigned long long)ii->inode,
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index 29b5965..3cf420b 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -9,7 +9,7 @@
 #include "fsck.h"
 #include "util.h"
 
-static int convert_mark(uint8_t q, uint32_t *count)
+static int gfs1_convert_mark(uint8_t q, uint32_t *count)
 {
 	switch(q) {
 
@@ -35,10 +35,62 @@ static int convert_mark(uint8_t q, uint32_t *count)
 
 	case gfs2_indir_blk:
 	case gfs2_leaf_blk:
+	/*case gfs2_meta_rgrp:*/
+	case gfs2_jdata: /* gfs1 jdata blocks count as "metadata" and gfs1
+			    metadata is marked the same as gfs2 inode in the
+			    bitmap. */
+	case gfs2_meta_eattr:
+		count[3]++;
+		return GFS2_BLKST_DINODE;
+
+	case gfs2_freemeta:
+		count[4]++;
+		return GFS2_BLKST_UNLINKED;
+
+	default:
+		log_err( _("Invalid block type %d found\n"), q);
+	}
+	return -1;
+}
+
+static int gfs2_convert_mark(uint8_t q, uint32_t *count)
+{
+	switch(q) {
+
+	case gfs2_meta_inval:
+	case gfs2_inode_invalid:
+		/* Convert invalid metadata to free blocks */
+	case gfs2_block_free:
+		count[0]++;
+		return GFS2_BLKST_FREE;
+
+	case gfs2_block_used:
+		count[2]++;
+		return GFS2_BLKST_USED;
+
+	case gfs2_inode_dir:
+	case gfs2_inode_file:
+	case gfs2_inode_lnk:
+	case gfs2_inode_device:
+	case gfs2_jdata: /* gfs1 jdata blocks count as "metadata" and gfs1
+			    metadata is marked the same as gfs2 inode in the
+			    bitmap. */
+	case gfs2_inode_fifo:
+	case gfs2_inode_sock:
+		count[1]++;
+		return GFS2_BLKST_DINODE;
+
+	case gfs2_indir_blk:
+	case gfs2_leaf_blk:
 	case gfs2_meta_eattr:
 		count[2]++;
 		return GFS2_BLKST_USED;
 
+	case gfs2_freemeta:
+		log_err( _("Invalid freemeta type %d found\n"), q);
+		count[4]++;
+		return -1;
+
 	default:
 		log_err( _("Invalid block type %d found\n"), q);
 	}
@@ -69,7 +121,10 @@ static int check_block_status(struct gfs2_sbd *sdp, char *buffer,
 			return 0;
 		q = block_type(block);
 
-		block_status = convert_mark(q, count);
+		if (sdp->gfs1)
+			block_status = gfs1_convert_mark(q, count);
+		else
+			block_status = gfs2_convert_mark(q, count);
 
 		/* If one node opens a file and another node deletes it, we
 		   may be left with a block that appears to be "unlinked" in
@@ -143,6 +198,7 @@ static void update_rgrp(struct gfs2_sbd *sdp, struct rgrp_list *rgp,
 	struct gfs2_bitmap *bits;
 	uint64_t rg_block = 0;
 	int update = 0;
+	struct gfs_rgrp *gfs1rg = (struct gfs_rgrp *)&rgp->rg;
 
 	for(i = 0; i < rgp->ri.ri_length; i++) {
 		bits = &rgp->bits[i];
@@ -174,7 +230,25 @@ static void update_rgrp(struct gfs2_sbd *sdp, struct rgrp_list *rgp,
 		rgp->rg.rg_dinodes = count[1];
 		update = 1;
 	}
-	if ((rgp->ri.ri_data - count[0] - count[1]) != count[2]) {
+	if (sdp->gfs1 && gfs1rg->rg_usedmeta != count[3]) {
+		log_err( _("RG #%llu (0x%llx) Used metadata count "
+			   "inconsistent: is %u should be %u\n"),
+			 (unsigned long long)rgp->ri.ri_addr,
+			 (unsigned long long)rgp->ri.ri_addr,
+			 gfs1rg->rg_usedmeta, count[3]);
+		gfs1rg->rg_usedmeta = count[3];
+		update = 1;
+	}
+	if (sdp->gfs1 && gfs1rg->rg_freemeta != count[4]) {
+		log_err( _("RG #%llu (0x%llx) Free metadata count "
+			   "inconsistent: is %u should be %u\n"),
+			 (unsigned long long)rgp->ri.ri_addr,
+			 (unsigned long long)rgp->ri.ri_addr,
+			 gfs1rg->rg_freemeta, count[4]);
+		gfs1rg->rg_freemeta = count[4];
+		update = 1;
+	}
+	if (!sdp->gfs1 && (rgp->ri.ri_data - count[0] - count[1]) != count[2]) {
 		/* FIXME not sure how to handle this case ATM - it
 		 * means that the total number of blocks we've counted
 		 * exceeds the blocks in the rg */
@@ -185,7 +259,10 @@ static void update_rgrp(struct gfs2_sbd *sdp, struct rgrp_list *rgp,
 		if (query( _("Update resource group counts? (y/n) "))) {
 			log_warn( _("Resource group counts updated\n"));
 			/* write out the rgrp */
-			gfs2_rgrp_out(&rgp->rg, rgp->bh[0]);
+			if (sdp->gfs1)
+				gfs_rgrp_out(gfs1rg, rgp->bh[0]);
+			else
+				gfs2_rgrp_out(&rgp->rg, rgp->bh[0]);
 		} else
 			log_err( _("Resource group counts left inconsistent\n"));
 	}
@@ -201,7 +278,7 @@ int pass5(struct gfs2_sbd *sdp)
 {
 	osi_list_t *tmp;
 	struct rgrp_list *rgp = NULL;
-	uint32_t count[3];
+	uint32_t count[5];
 	uint64_t rg_count = 0;
 
 	/* Reconcile RG bitmaps with fsck bitmap */
diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c
index c01aaa6..28ed451 100644
--- a/gfs2/fsck/rgrepair.c
+++ b/gfs2/fsck/rgrepair.c
@@ -184,8 +184,13 @@ static uint64_t count_usedspace(struct gfs2_sbd *sdp, int first,
 	unsigned int state;
 
 	/* Count up the free blocks in the bitmap */
-	off = (first) ? sizeof(struct gfs2_rgrp) :
-		sizeof(struct gfs2_meta_header);
+	if (first) {
+		if (sdp->gfs1)
+			off = sizeof(struct gfs_rgrp);
+		else
+			off = sizeof(struct gfs2_rgrp);
+	} else
+		off = sizeof(struct gfs2_meta_header);
 	bytes_to_check = sdp->bsize - off;
 	for (x = 0; x < bytes_to_check; x++) {
 		unsigned char *byte;
@@ -681,12 +686,19 @@ static int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_list *rg,
 			mh.mh_format = GFS2_FORMAT_RB;
 			gfs2_meta_header_out(&mh, rg->bh[x]);
 		} else {
-			memset(&rg->rg, 0, sizeof(struct gfs2_rgrp));
+			if (sdp->gfs1)
+				memset(&rg->rg, 0, sizeof(struct gfs_rgrp));
+			else
+				memset(&rg->rg, 0, sizeof(struct gfs2_rgrp));
 			rg->rg.rg_header.mh_magic = GFS2_MAGIC;
 			rg->rg.rg_header.mh_type = GFS2_METATYPE_RG;
 			rg->rg.rg_header.mh_format = GFS2_FORMAT_RG;
 			rg->rg.rg_free = rg->ri.ri_data;
-			gfs2_rgrp_out(&rg->rg, rg->bh[x]);
+			if (sdp->gfs1)
+				gfs_rgrp_out((struct gfs_rgrp *)&rg->rg,
+					     rg->bh[x]);
+			else
+				gfs2_rgrp_out(&rg->rg, rg->bh[x]);
 		}
 		brelse(rg->bh[x]);
 		rg->bh[x] = NULL;
diff --git a/gfs2/fsck/util.h b/gfs2/fsck/util.h
index 106cca8..9b2de61 100644
--- a/gfs2/fsck/util.h
+++ b/gfs2/fsck/util.h
@@ -1,6 +1,8 @@
 #ifndef __UTIL_H__
 #define __UTIL_H__
 
+#include <sys/stat.h>
+
 #include "fsck.h"
 #include "libgfs2.h"
 
@@ -42,15 +44,15 @@ enum gfs2_mark_block {
 	gfs2_inode_file    = (0x4),
 
 	gfs2_inode_lnk     = (0x5),
-	gfs2_inode_device  = (0x6),
-
+	gfs2_inode_device  = (0x6), /* char or block device */
+	gfs2_jdata         = (0x7), /* gfs journaled data blocks */
 	gfs2_inode_fifo    = (0x8),
 	gfs2_inode_sock    = (0x9),
 
 	gfs2_inode_invalid = (0xa),
 	gfs2_meta_inval    = (0xb),
 	gfs2_leaf_blk      = (0xc),
-
+	gfs2_freemeta      = (0xd), /* was: gfs2_meta_rgrp */
 	gfs2_meta_eattr    = (0xe),
 
 	gfs2_bad_block     = (0xf), /* Contains at least one bad block */
@@ -67,14 +69,14 @@ static const inline char *block_type_string(uint8_t q)
 
 		"symlink",
 		"device",
-		"",
+		"journaled data",
 		"fifo",
 		"socket",
 
 		"invalid inode",
 		"invalid meta",
 		"dir leaf",
-		"",
+		"free metadata",
 		"eattribute",
 
 		"bad"};
@@ -85,30 +87,82 @@ static const inline char *block_type_string(uint8_t q)
 
 /* Must be kept in sync with gfs2_mark_block enum above. Blocks marked as
    invalid or bad are considered metadata until actually freed. */
-static inline int blockmap_to_bitmap(enum gfs2_mark_block m)
+static inline int blockmap_to_bitmap(enum gfs2_mark_block m, int gfs1)
 {
-	static int bitmap_states[16] = {
-		GFS2_BLKST_FREE,  /* free */
-		GFS2_BLKST_USED,  /* data */
-		GFS2_BLKST_USED,  /* indirect data or rgrp meta*/
-		GFS2_BLKST_DINODE,  /* directory */
-		GFS2_BLKST_DINODE,  /* file */
-
-		GFS2_BLKST_DINODE,  /* symlink */
-		GFS2_BLKST_DINODE,  /* block or char device */
-		GFS2_BLKST_USED,    /* reserved */
-		GFS2_BLKST_DINODE,  /* fifo */
-		GFS2_BLKST_DINODE,  /* socket */
-
-		GFS2_BLKST_FREE,  /* invalid inode */
-		GFS2_BLKST_FREE,  /* invalid meta */
-		GFS2_BLKST_USED,  /* dir leaf */
-		GFS2_BLKST_UNLINKED,  /* unused */
-		GFS2_BLKST_USED,  /* eattribute */
-
-		GFS2_BLKST_USED,  /* bad */
-	};
-	return bitmap_states[m];
+	static int bitmap_states[2][16] = {
+		/* ---------------------- gfs2 ------------------------------*/
+		{GFS2_BLKST_FREE,  /* free */
+		 GFS2_BLKST_USED,  /* data */
+		 GFS2_BLKST_USED,  /* indirect data or rgrp meta */
+		 GFS2_BLKST_DINODE,  /* directory */
+		 GFS2_BLKST_DINODE,  /* file */
+
+		 GFS2_BLKST_DINODE,  /* symlink */
+		 GFS2_BLKST_DINODE,  /* block or char device */
+		 GFS2_BLKST_USED,    /* journaled data */
+		 GFS2_BLKST_DINODE,  /* fifo */
+		 GFS2_BLKST_DINODE,  /* socket */
+
+		 GFS2_BLKST_FREE,  /* invalid inode */
+		 GFS2_BLKST_FREE,  /* invalid meta */
+		 GFS2_BLKST_USED,  /* dir leaf */
+		 GFS2_BLKST_UNLINKED,  /* GFS unlinked metadata */
+		 GFS2_BLKST_USED,  /* eattribute */
+
+		 GFS2_BLKST_USED},  /* bad */
+		/* ---------------------- gfs1 ----------------------------- */
+		{GFS2_BLKST_FREE,  /* free */
+		 GFS2_BLKST_USED,  /* data */
+		 GFS2_BLKST_DINODE,  /* indirect data or rgrp meta*/
+		 GFS2_BLKST_DINODE,  /* directory */
+		 GFS2_BLKST_DINODE,  /* file */
+
+		 GFS2_BLKST_DINODE,  /* symlink */
+		 GFS2_BLKST_DINODE,  /* block or char device */
+		 GFS2_BLKST_DINODE,  /* journaled data */
+		 GFS2_BLKST_DINODE,  /* fifo */
+		 GFS2_BLKST_DINODE,  /* socket */
+
+		 GFS2_BLKST_FREE,  /* invalid inode */
+		 GFS2_BLKST_FREE,  /* invalid meta */
+		 GFS2_BLKST_DINODE,  /* dir leaf */
+		 GFS2_BLKST_UNLINKED, /* GFS unlinked metadata */
+		 GFS2_BLKST_DINODE,  /* eattribute */
+
+		 GFS2_BLKST_USED}};  /* bad */
+	return bitmap_states[gfs1][m];
+}
+
+static inline int is_dir(struct gfs2_dinode *dinode, int gfs1)
+{
+	if (gfs1 && is_gfs_dir(dinode))
+		return 1;
+	if (S_ISDIR(dinode->di_mode))
+		return 1;
+
+	return 0;
+}
+
+static inline uint32_t gfs_to_gfs2_mode(uint32_t gfs1mode)
+{
+	switch (gfs1mode) {
+	case GFS_FILE_DIR:
+		return S_IFDIR;
+	case GFS_FILE_REG:
+		return S_IFREG;
+	case GFS_FILE_LNK:
+		return S_IFLNK;
+	case GFS_FILE_BLK:
+		return S_IFBLK;
+	case GFS_FILE_CHR:
+		return S_IFCHR;
+	case GFS_FILE_FIFO:
+		return S_IFIFO;
+	case GFS_FILE_SOCK:
+		return S_IFSOCK;
+	default:
+		return S_IFREG;
+	}
 }
 
 extern struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
@@ -116,5 +170,4 @@ extern struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
 extern void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il);
 extern int gfs2_blockmap_set(struct gfs2_bmap *il, uint64_t block,
 			     enum gfs2_mark_block mark);
-
 #endif /* __UTIL_H__ */
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 58442e8..b1574fb 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -723,6 +723,9 @@ extern int gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block,
 			     int first);
 extern int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
 				 uint64_t *block, uint32_t type, int first);
+extern int gfs2_next_rg_freemeta(struct rgrp_list *rgd, uint64_t *block,
+				 int first);
+
 /* super.c */
 extern int check_sb(struct gfs2_sb *sb, int allow_gfs);
 extern int read_sb(struct gfs2_sbd *sdp, int allow_gfs);
diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c
index 7dabd80..f53b4af 100644
--- a/gfs2/libgfs2/structures.c
+++ b/gfs2/libgfs2/structures.c
@@ -459,39 +459,50 @@ int gfs2_check_meta(struct gfs2_buffer_head *bh, int type)
  *
  * Returns: 0 on success, -1 when finished
  */
-int gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block, int first)
+static int __gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block,
+			       int first, unsigned char state)
 {
 	struct gfs2_bitmap *bits = NULL;
 	uint32_t length = rgd->ri.ri_length;
-	uint32_t blk = (first)? 0: (uint32_t)((*block+1)-rgd->ri.ri_data0);
+	uint32_t blk = (first)? 0: (uint32_t)((*block + 1) - rgd->ri.ri_data0);
 	int i;
 
 	if(!first && (*block < rgd->ri.ri_data0)) {
 		log_err("next_rg_meta:  Start block is outside rgrp bounds.\n");
 		exit(1);
 	}
-	for(i=0; i < length; i++){
+	for(i = 0; i < length; i++){
 		bits = &rgd->bits[i];
-		if(blk < bits->bi_len*GFS2_NBBY)
+		if (blk < bits->bi_len * GFS2_NBBY)
 			break;
-		blk -= bits->bi_len*GFS2_NBBY;
+		blk -= bits->bi_len * GFS2_NBBY;
 	}
 	for(; i < length; i++){
 		bits = &rgd->bits[i];
 		blk = gfs2_bitfit((unsigned char *)rgd->bh[i]->b_data +
-				  bits->bi_offset, bits->bi_len, blk,
-				  GFS2_BLKST_DINODE);
+				  bits->bi_offset, bits->bi_len, blk, state);
 		if(blk != BFITNOENT){
-			*block = blk + (bits->bi_start * GFS2_NBBY) + rgd->ri.ri_data0;
+			*block = blk + (bits->bi_start * GFS2_NBBY) +
+				rgd->ri.ri_data0;
 			break;
 		}
-		blk=0;
+		blk = 0;
 	}
 	if(i == length)
 		return -1;
 	return 0;
 }
 
+int gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block, int first)
+{
+	return __gfs2_next_rg_meta(rgd, block, first, GFS2_BLKST_DINODE);
+}
+
+int gfs2_next_rg_freemeta(struct rgrp_list *rgd, uint64_t *block, int first)
+{
+	return __gfs2_next_rg_meta(rgd, block, first, GFS2_BLKST_UNLINKED);
+}
+
 /**
  * next_rg_metatype
  * @rgd:
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 45/66] fsck.gfs2: Remove bad inodes from duplicate tree
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (43 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 44/66] fsck.gfs2: Add ability to check gfs1 file systems rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 46/66] fsck.gfs2: Handle duplicate reference to dinode blocks rpeterso
                   ` (20 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

The problem was that if an inode was determined to be "bad" (lots of
corruption) and its metadata blocks were invalidated in pass1, the
"bad" block for the inode was set as "data" in the bitmap.  Later,
that caused duplicate reference processing (pass1b) to not remove the
block from the inode tree inside function check_n_fix_bitmap when the
bad block was freed. Later still, in pass4, that caused the now
deleted inode to be processed again, at which time it would reprocess
the inode's metadata and free all blocks, including blocks that were
duplicate-referenced by other inodes.  In other words, pass4 freed
blocks out from under valid references when it should not have. This
patch changes the bitmap type for "bad" blocks from "data" to
"inode". That causes function check_n_fix_bitmap to try to remove the
bad block from the inode tree, so pass4 never processes it by mistake.

This patch also changes a few debug messages to make them shorter so
that the output files aren't as big to search through.

rhbz#675723
---
 gfs2/fsck/metawalk.c |   20 ++++++--------------
 gfs2/fsck/pass1.c    |    8 ++++++--
 gfs2/fsck/util.h     |    4 ++--
 3 files changed, 14 insertions(+), 18 deletions(-)

diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 2ddf7dd..94b0148 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -113,36 +113,28 @@ int _fsck_blockmap_set(struct gfs2_inode *ip, uint64_t bblock,
 		   output easier to debug. */
 		if (ip->i_di.di_num.no_addr == bblock) {
 			print_fsck_log(MSG_DEBUG, caller, fline,
-				       _("%s inode found at block %lld "
-					 "(0x%llx): marking as '%s'\n"),
+				       _("%s inode found at block "
+					 "0x%llx: marking as '%s'\n"),
 				       btype, (unsigned long long)
 				       ip->i_di.di_num.no_addr,
-				       (unsigned long long)
-				       ip->i_di.di_num.no_addr,
 				       block_type_string(mark));
 		} else if (mark == gfs2_bad_block || mark == gfs2_meta_inval) {
 			print_fsck_log(MSG_DEBUG, caller, fline,
-				       _("inode %lld (0x%llx) references "
-					 "%s block %lld (0x%llx): "
+				       _("inode 0x%llx references "
+					 "%s block 0x%llx: "
 					 "marking as '%s'\n"),
 				       (unsigned long long)
 				       ip->i_di.di_num.no_addr,
-				       (unsigned long long)
-				       ip->i_di.di_num.no_addr,
 				       btype, (unsigned long long)bblock,
-				       (unsigned long long)bblock,
 				       block_type_string(mark));
 		} else {
 			print_fsck_log(MSG_DEBUG, caller, fline,
-				       _("inode %lld (0x%llx) references "
-					 "%s block %lld (0x%llx): "
+				       _("inode 0x%llx references "
+					 "%s block 0x%llx: "
 					 "marking as '%s'\n"),
 				       (unsigned long long)
-				       ip->i_di.di_num.no_addr,
-				       (unsigned long long)
 				       ip->i_di.di_num.no_addr, btype,
 				       (unsigned long long)bblock,
-				       (unsigned long long)bblock,
 				       block_type_string(mark));
 		}
 	}
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 876078e..515f50a 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -383,8 +383,12 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block,
 	*bh = NULL;
 
 	if (!valid_block(ip->i_sbd, block)) { /* blk outside of FS */
+		/* The bad dinode should be invalidated later due to
+		   "unrecoverable" errors.  The inode itself should be
+		   set "free" and removed from the inodetree by
+		   undo_check_metalist. */
 		fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
-				  _("itself"), gfs2_bad_block);
+				  _("bad block referencing"), gfs2_bad_block);
 		log_debug( _("Bad indirect block (invalid/out of range) "
 			     "found in inode %lld (0x%llx).\n"),
 			   (unsigned long long)ip->i_di.di_num.no_addr,
@@ -457,7 +461,7 @@ static int undo_check_metalist(struct gfs2_inode *ip, uint64_t block,
 
 	if (!valid_block(ip->i_sbd, block)) { /* blk outside of FS */
 		fsck_blockmap_set(ip, ip->i_di.di_num.no_addr,
-				  _("itself"), gfs2_block_free);
+				  _("bad block referencing"), gfs2_block_free);
 		return 1;
 	}
 	if (is_dir(&ip->i_di, ip->i_sbd->gfs1) && h == ip->i_di.di_height)
diff --git a/gfs2/fsck/util.h b/gfs2/fsck/util.h
index 9b2de61..fd75212 100644
--- a/gfs2/fsck/util.h
+++ b/gfs2/fsck/util.h
@@ -109,7 +109,7 @@ static inline int blockmap_to_bitmap(enum gfs2_mark_block m, int gfs1)
 		 GFS2_BLKST_UNLINKED,  /* GFS unlinked metadata */
 		 GFS2_BLKST_USED,  /* eattribute */
 
-		 GFS2_BLKST_USED},  /* bad */
+		 GFS2_BLKST_DINODE}, /* bad */
 		/* ---------------------- gfs1 ----------------------------- */
 		{GFS2_BLKST_FREE,  /* free */
 		 GFS2_BLKST_USED,  /* data */
@@ -129,7 +129,7 @@ static inline int blockmap_to_bitmap(enum gfs2_mark_block m, int gfs1)
 		 GFS2_BLKST_UNLINKED, /* GFS unlinked metadata */
 		 GFS2_BLKST_DINODE,  /* eattribute */
 
-		 GFS2_BLKST_USED}};  /* bad */
+		 GFS2_BLKST_DINODE}}; /* bad */
 	return bitmap_states[gfs1][m];
 }
 
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 46/66] fsck.gfs2: Handle duplicate reference to dinode blocks
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (44 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 45/66] fsck.gfs2: Remove bad inodes from duplicate tree rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 47/66] fsck.gfs2: Bad extended attributes not deleted properly rpeterso
                   ` (19 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

The fsck.gfs2 tool was not properly handling cases where dinode
blocks were referenced by other dinodes as another type.  For example,
if some dinode wrongly thought that another dinode was one of its
metadata blocks or data blocks.  This patch fixes that situation by
introducing a new "ref_is_inode" duplicate reference type.  The only
thing that should ever reference a dinode is a directory, and that's
a special case.  Any other reference is wrong and should be removed.
This patch takes care of those situations.

The patch also moves the code that marks dinodes as their
proper type to a new function in util.c called set_ip_blockmap.
That allows duplicate processing to set the proper type in the
blockmap in cases where the invalid reference was found first
(before the dinode itself was encountered).  It also removes the
redundant "reftype_str" array of descriptions in favor of a central
one already in util.c called "reftypes".

rhbz#675723
---
 gfs2/fsck/fsck.h   |   11 +++++---
 gfs2/fsck/pass1.c  |   50 +++---------------------------------
 gfs2/fsck/pass1b.c |   57 +++++++++++++++++++++++++----------------
 gfs2/fsck/util.c   |   71 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 gfs2/fsck/util.h   |    3 +-
 5 files changed, 119 insertions(+), 73 deletions(-)

diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h
index e2640d8..edd73d7 100644
--- a/gfs2/fsck/fsck.h
+++ b/gfs2/fsck/fsck.h
@@ -61,10 +61,13 @@ struct duptree {
 };
 
 enum dup_ref_type {
-	ref_as_data = 0,
-	ref_as_meta = 1,
-	ref_as_ea   = 2,
-	ref_types   = 3
+	ref_as_data = 0, /* dinode references this block as a data block */
+	ref_as_meta = 1, /* dinode references this block as a metadata block */
+	ref_as_ea   = 2, /* dinode references this block as an extended attr */
+	ref_is_inode= 3, /* The reference is itself a dinode.  In other words,
+			    it's a dinode, not pointed to as data or
+			    metadata */
+	ref_types   = 4,
 };
 
 struct inode_with_dups {
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 515f50a..32ebfba 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -1143,7 +1143,6 @@ static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip)
 	struct block_count bc = {0};
 	long bad_pointers;
 	uint64_t block = ip->i_bh->b_blocknr;
-	uint32_t mode;
 
 	bad_pointers = 0L;
 
@@ -1164,49 +1163,8 @@ static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip)
 		return 0;
 	}
 
-	if (sdp->gfs1)
-		mode = gfs_to_gfs2_mode(ip->i_di.__pad1);
-	else
-		mode = ip->i_di.di_mode & S_IFMT;
-
-	switch (mode) {
-	case S_IFDIR:
-		if (fsck_blockmap_set(ip, block, _("directory"),
-				      gfs2_inode_dir))
-			goto bad_dinode;
-		if (!dirtree_insert(block))
-			goto bad_dinode;
-		break;
-	case S_IFREG:
-		if (fsck_blockmap_set(ip, block, _("file"), gfs2_inode_file))
-			goto bad_dinode;
-		break;
-	case S_IFLNK:
-		if (fsck_blockmap_set(ip, block, _("symlink"),
-				      gfs2_inode_lnk))
-			goto bad_dinode;
-		break;
-	case S_IFBLK:
-		if (fsck_blockmap_set(ip, block, _("block device"),
-				      gfs2_inode_device))
-			goto bad_dinode;
-		break;
-	case S_IFCHR:
-		if (fsck_blockmap_set(ip, block, _("character device"),
-				      gfs2_inode_device))
-			goto bad_dinode;
-		break;
-	case S_IFIFO:
-		if (fsck_blockmap_set(ip, block, _("fifo"),
-				      gfs2_inode_fifo))
-			goto bad_dinode;
-		break;
-	case S_IFSOCK:
-		if (fsck_blockmap_set(ip, block, _("socket"),
-				      gfs2_inode_sock))
-			goto bad_dinode;
-		break;
-	default:
+	error = set_ip_blockmap(ip, 1);
+	if (error == -EINVAL) {
 		/* We found a dinode that has an invalid mode, so we can't
 		   tell if it's a data file, directory or a socket.
 		   Regardless, we have to invalidate its metadata in case there
@@ -1227,7 +1185,9 @@ static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip)
 				      gfs2_inode_invalid))
 			goto bad_dinode;
 		return 0;
-	}
+	} else if (error)
+		goto bad_dinode;
+
 	if (set_di_nlink(ip))
 		goto bad_dinode;
 
diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index 003d696..b7be683 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -13,10 +13,6 @@
 #include "metawalk.h"
 #include "inode_hash.h"
 
-const char *reftype_str[ref_types + 1] = {"data", "metadata",
-					  "extended attribute",
-					  "unimportant"};
-
 struct fxn_info {
 	uint64_t block;
 	int found;
@@ -347,6 +343,10 @@ static int find_block_ref(struct gfs2_sbd *sdp, uint64_t inode)
 			     (unsigned long long)inode);
 		return 1;
 	}
+	/* Check to see if this inode was referenced by another by mistake */
+	add_duplicate_ref(ip, inode, ref_is_inode, 1, INODE_VALID);
+
+	/* Check this dinode's metadata for references to known duplicates */
 	error = check_metatree(ip, &find_refs);
 	if (error < 0) {
 		stack;
@@ -374,19 +374,25 @@ static int find_block_ref(struct gfs2_sbd *sdp, uint64_t inode)
    are the same type, and if so, return the type. */
 static enum dup_ref_type get_ref_type(struct inode_with_dups *id)
 {
-	if (id->reftypecount[ref_as_ea] &&
-	    !id->reftypecount[ref_as_data] &&
-	    !id->reftypecount[ref_as_meta])
-		return ref_as_ea;
-	if (!id->reftypecount[ref_as_ea] &&
-	    id->reftypecount[ref_as_data] &&
-	    !id->reftypecount[ref_as_meta])
-		return ref_as_data;
-	if (!id->reftypecount[ref_as_ea] &&
-	    !id->reftypecount[ref_as_data] &&
-	    id->reftypecount[ref_as_meta])
-		return ref_as_meta;
-	return ref_types; /* multiple references */
+	enum dup_ref_type t, i;
+	int found_type_with_ref;
+	int found_other_types;
+
+	for (t = ref_as_data; t < ref_types; t++) {
+		found_type_with_ref = 0;
+		found_other_types = 0;
+		for (i = ref_as_data; i < ref_types; i++) {
+			if (id->reftypecount[i]) {
+				if (t == i)
+					found_type_with_ref = 1;
+				else
+					found_other_types = 1;
+			}
+		}
+		if (found_type_with_ref)
+			return found_other_types ? ref_types : t;
+	}
+	return ref_types;
 }
 
 static void log_inode_reference(struct duptree *b, osi_list_t *tmp, int inval)
@@ -396,9 +402,10 @@ static void log_inode_reference(struct duptree *b, osi_list_t *tmp, int inval)
 
 	id = osi_list_entry(tmp, struct inode_with_dups, list);
 	if (id->dup_count == 1)
-		sprintf(reftypestring, "as %s", reftype_str[get_ref_type(id)]);
+		sprintf(reftypestring, "as %s", reftypes[get_ref_type(id)]);
 	else
-		sprintf(reftypestring, "%d/%d/%d",
+		sprintf(reftypestring, "%d/%d/%d/%d",
+			id->reftypecount[ref_is_inode],
 			id->reftypecount[ref_as_data],
 			id->reftypecount[ref_as_meta],
 			id->reftypecount[ref_as_ea]);
@@ -484,8 +491,7 @@ static int resolve_dup_references(struct gfs2_sbd *sdp, struct duptree *b,
 			  (unsigned long long)id->block_no,
 			  (unsigned long long)b->block,
 			  (unsigned long long)b->block,
-			  reftype_str[this_ref],
-			  reftype_str[acceptable_ref]);
+			  reftypes[this_ref], reftypes[acceptable_ref]);
 		if (!(query( _("Okay to delete %s inode %lld (0x%llx)? "
 			       "(y/n) "),
 			     (inval ? _("invalidated") : ""),
@@ -511,7 +517,7 @@ static int resolve_dup_references(struct gfs2_sbd *sdp, struct duptree *b,
 		clear_dup_fxns.private = (void *) dh;
 		/* Clear the EAs for the inode first */
 		check_inode_eattr(ip, &clear_dup_fxns);
-		/* If the dup wasn't only in the EA, clear the inode */
+		/* If the dup was in data or metadata, clear the dinode */
 		if (id->reftypecount[ref_as_data] ||
 		    id->reftypecount[ref_as_meta])
 			check_metatree(ip, &clear_dup_fxns);
@@ -577,7 +583,12 @@ static int handle_dup_blk(struct gfs2_sbd *sdp, struct duptree *b)
 	ctype = ((struct gfs2_meta_header *)(bh->b_data))->mh_type;
 	brelse(bh);
 
+	/* If this is a dinode, any references to it (except in directory
+	   entries) are invalid and should be deleted. */
 	if (be32_to_cpu(cmagic) == GFS2_MAGIC &&
+	    be32_to_cpu(ctype) == GFS2_METATYPE_DI)
+		acceptable_ref = ref_is_inode;
+	else if (be32_to_cpu(cmagic) == GFS2_MAGIC &&
 	    (be32_to_cpu(ctype) == GFS2_METATYPE_EA ||
 	     be32_to_cpu(ctype) == GFS2_METATYPE_ED))
 		acceptable_ref = ref_as_ea;
@@ -689,6 +700,8 @@ static int handle_dup_blk(struct gfs2_sbd *sdp, struct duptree *b)
 			fsck_blockmap_set(ip, b->block,
 					  _("reference-repaired leaf"),
 					  gfs2_block_free);
+		} else if (id->reftypecount[ref_is_inode]) {
+			set_ip_blockmap(ip, 0); /* 0=do not add to dirtree */
 		} else if (id->reftypecount[ref_as_data]) {
 			fsck_blockmap_set(ip, b->block,
 					  _("reference-repaired data"),
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index 4075aec..69bf328 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -10,9 +10,12 @@
 
 #include "libgfs2.h"
 #include "fs_bits.h"
+#include "metawalk.h"
 #include "util.h"
 
-const char *reftypes[3] = {"data", "metadata", "extended attribute"};
+const char *reftypes[ref_types + 1] = {"data", "metadata",
+				       "extended attribute", "itself",
+				       "unimportant"};
 
 void big_file_comfort(struct gfs2_inode *ip, uint64_t blks_checked)
 {
@@ -452,3 +455,69 @@ void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il)
 	gfs2_special_free(&sdp->eattr_blocks);
 	return il;
 }
+
+/* set_ip_blockmap - set the blockmap for a dinode
+ *
+ * instree: Set to 1 if directories should be inserted into the directory tree
+ *          otherwise 0.
+ * returns: 0 if no error, -EINVAL if dinode has a bad mode, -EPERM on error
+ */
+int set_ip_blockmap(struct gfs2_inode *ip, int instree)
+{
+	uint64_t block = ip->i_bh->b_blocknr;
+	struct gfs2_sbd *sdp = ip->i_sbd;
+	uint32_t mode;
+
+	if (sdp->gfs1)
+		mode = gfs_to_gfs2_mode(ip->i_di.__pad1);
+	else
+		mode = ip->i_di.di_mode & S_IFMT;
+
+	switch (mode) {
+	case S_IFDIR:
+		if (fsck_blockmap_set(ip, block, _("directory"),
+				      gfs2_inode_dir))
+			goto bad_dinode;
+		if (instree && !dirtree_insert(block))
+			goto bad_dinode;
+		break;
+	case S_IFREG:
+		if (fsck_blockmap_set(ip, block, _("file"), gfs2_inode_file))
+			goto bad_dinode;
+		break;
+	case S_IFLNK:
+		if (fsck_blockmap_set(ip, block, _("symlink"),
+				      gfs2_inode_lnk))
+			goto bad_dinode;
+		break;
+	case S_IFBLK:
+		if (fsck_blockmap_set(ip, block, _("block device"),
+				      gfs2_inode_device))
+			goto bad_dinode;
+		break;
+	case S_IFCHR:
+		if (fsck_blockmap_set(ip, block, _("character device"),
+				      gfs2_inode_device))
+			goto bad_dinode;
+		break;
+	case S_IFIFO:
+		if (fsck_blockmap_set(ip, block, _("fifo"),
+				      gfs2_inode_fifo))
+			goto bad_dinode;
+		break;
+	case S_IFSOCK:
+		if (fsck_blockmap_set(ip, block, _("socket"),
+				      gfs2_inode_sock))
+			goto bad_dinode;
+		break;
+	default:
+		fsck_blockmap_set(ip, block, _("invalid mode"),
+				  gfs2_inode_invalid);
+		return -EINVAL;
+	}
+	return 0;
+
+bad_dinode:
+	stack;
+	return -EPERM;
+}
diff --git a/gfs2/fsck/util.h b/gfs2/fsck/util.h
index fd75212..6581cb1 100644
--- a/gfs2/fsck/util.h
+++ b/gfs2/fsck/util.h
@@ -21,7 +21,7 @@ extern struct inode_with_dups *find_dup_ref_inode(struct duptree *dt,
 						  struct gfs2_inode *ip);
 extern void dup_listent_delete(struct inode_with_dups *id);
 
-extern const char *reftypes[3];
+extern const char *reftypes[ref_types + 1];
 
 static inline uint8_t block_type(uint64_t bblock)
 {
@@ -170,4 +170,5 @@ extern struct gfs2_bmap *gfs2_bmap_create(struct gfs2_sbd *sdp, uint64_t size,
 extern void *gfs2_bmap_destroy(struct gfs2_sbd *sdp, struct gfs2_bmap *il);
 extern int gfs2_blockmap_set(struct gfs2_bmap *il, uint64_t block,
 			     enum gfs2_mark_block mark);
+extern int set_ip_blockmap(struct gfs2_inode *ip, int instree);
 #endif /* __UTIL_H__ */
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 47/66] fsck.gfs2: Bad extended attributes not deleted properly
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (45 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 46/66] fsck.gfs2: Handle duplicate reference to dinode blocks rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 48/66] libgfs2: Make rebuild functions not re-read ip rpeterso
                   ` (18 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch fixes a couple of problems fsck.gfs2 when it discovered
corrupt extended attributes and tried to delete them.  First, in
check_eattr_entries it wasn't reporting the corruption.  Second,
when the EA block was freed, it wasn't returning a proper return
code which caused fsck to not update the inode accordingly.
Third, it wasn't zeroing out the EA block address properly.
Fourth, I did a small amount of reformatting.

rhbz#675723
---
 gfs2/fsck/metawalk.c |   56 ++++++++++++++++++++++++++++++++++++++++---------
 gfs2/fsck/pass1.c    |    4 +--
 gfs2/fsck/pass1c.c   |    7 +++--
 gfs2/fsck/pass2.c    |    9 +++++--
 4 files changed, 56 insertions(+), 20 deletions(-)

diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 94b0148..db7168b 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -755,6 +755,13 @@ static int check_eattr_entries(struct gfs2_inode *ip,
 							      bh, ea_hdr,
 							      ea_hdr_prev,
 							      pass->private)) {
+					log_err(_("Bad extended attribute "
+						  "found at block %lld "
+						  "(0x%llx)"),
+						(unsigned long long)
+						be64_to_cpu(*ea_data_ptr),
+						(unsigned long long)
+						be64_to_cpu(*ea_data_ptr));
 					if (query( _("Repair the bad Extended "
 						     "Attribute? (y/n) "))) {
 						ea_hdr->ea_num_ptrs = i;
@@ -807,12 +814,14 @@ static int check_leaf_eattr(struct gfs2_inode *ip, uint64_t block,
 			    uint64_t parent, struct metawalk_fxns *pass)
 {
 	struct gfs2_buffer_head *bh = NULL;
-	int error = 0;
-
-	log_debug( _("Checking EA leaf block #%"PRIu64" (0x%" PRIx64 ").\n"),
-			  block, block);
 
 	if (pass->check_eattr_leaf) {
+		int error = 0;
+
+		log_debug( _("Checking EA leaf block #%llu (0x%llx).\n"),
+			   (unsigned long long)block,
+			   (unsigned long long)block);
+
 		error = pass->check_eattr_leaf(ip, block, parent, &bh,
 					       pass->private);
 		if (error < 0) {
@@ -886,13 +895,18 @@ int find_remove_dup(struct gfs2_inode *ip, uint64_t block, const char *btype)
 /**
  * free_block_if_notdup - free blocks associated with an inode, but if it's a
  *                        duplicate, just remove that designation instead.
- * Returns: 0 if the block was freed, 1 if a duplicate reference was removed
+ * Returns: 1 if the block was freed, 0 if a duplicate reference was removed
+ * Note: The return code is handled this way because there are places in
+ *       metawalk.c that assume "1" means "change was made" and "0" means
+ *       change was not made.
  */
 int free_block_if_notdup(struct gfs2_inode *ip, uint64_t block,
 			 const char *btype)
 {
-	if (!find_remove_dup(ip, block, btype))
+	if (!find_remove_dup(ip, block, btype)) { /* not a dup */
 		fsck_blockmap_set(ip, block, btype, gfs2_block_free);
+		return 1;
+	}
 	return 0;
 }
 
@@ -1446,16 +1460,36 @@ int delete_data(struct gfs2_inode *ip, uint64_t block, void *private)
 int delete_eattr_indir(struct gfs2_inode *ip, uint64_t block, uint64_t parent,
 		       struct gfs2_buffer_head **bh, void *private)
 {
-	return delete_block_if_notdup(ip, block, NULL,
-				      _("indirect extended attribute"),
-				      private);
+	int ret;
+
+	ret = delete_block_if_notdup(ip, block, NULL,
+				     _("indirect extended attribute"),
+				     private);
+	/* Even if it's a duplicate reference, we want to eliminate the
+	   reference itself, and adjust di_blocks accordingly. */
+	if (ip->i_di.di_eattr) {
+		ip->i_di.di_blocks--;
+		if (block == ip->i_di.di_eattr)
+			ip->i_di.di_eattr = 0;
+		bmodified(ip->i_bh);
+	}
+	return ret;
 }
 
 int delete_eattr_leaf(struct gfs2_inode *ip, uint64_t block, uint64_t parent,
 		      struct gfs2_buffer_head **bh, void *private)
 {
-	return delete_block_if_notdup(ip, block, NULL, _("extended attribute"),
-				      private);
+	int ret;
+
+	ret = delete_block_if_notdup(ip, block, NULL, _("extended attribute"),
+				     private);
+	if (ip->i_di.di_eattr) {
+		ip->i_di.di_blocks--;
+		if (block == ip->i_di.di_eattr)
+			ip->i_di.di_eattr = 0;
+		bmodified(ip->i_bh);
+	}
+	return ret;
 }
 
 static int alloc_metalist(struct gfs2_inode *ip, uint64_t block,
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 32ebfba..3e6b816 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -1181,9 +1181,7 @@ static int handle_ip(struct gfs2_sbd *sdp, struct gfs2_inode *ip)
 			  (unsigned long long)ip->i_di.di_num.no_addr,
 			  (unsigned long long)ip->i_di.di_num.no_addr);
 		check_metatree(ip, &invalidate_fxns);
-		if (fsck_blockmap_set(ip, block, _("invalid mode"),
-				      gfs2_inode_invalid))
-			goto bad_dinode;
+		check_inode_eattr(ip, &invalidate_fxns);
 		return 0;
 	} else if (error)
 		goto bad_dinode;
diff --git a/gfs2/fsck/pass1c.c b/gfs2/fsck/pass1c.c
index 150dc2f..f7a7842 100644
--- a/gfs2/fsck/pass1c.c
+++ b/gfs2/fsck/pass1c.c
@@ -62,9 +62,10 @@ static int ask_remove_eattr(struct gfs2_inode *ip)
 		ip->i_di.di_eattr = 0;
 		bmodified(ip->i_bh);
 		log_err( _("Bad Extended Attribute removed.\n"));
-	} else
-		log_err( _("Bad Extended Attribute not removed.\n"));
-	return 1;
+		return 1;
+	}
+	log_err( _("Bad Extended Attribute not removed.\n"));
+	return 0;
 }
 
 static int check_eattr_indir(struct gfs2_inode *ip, uint64_t block,
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index 7e20315..e02fdd0 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -203,9 +203,9 @@ static int delete_eattr_extentry(struct gfs2_inode *ip, uint64_t *ea_data_ptr,
 				 struct gfs2_ea_header *ea_hdr_prev,
 				 void *private)
 {
-        uint64_t block = be64_to_cpu(*ea_data_ptr);
+	uint64_t block = be64_to_cpu(*ea_data_ptr);
 
-        return delete_metadata(ip, block, NULL, 0, private);
+	return delete_metadata(ip, block, NULL, 0, private);
 }
 
 struct metawalk_fxns pass2_fxns_delete = {
@@ -343,7 +343,10 @@ static int check_dentry(struct gfs2_inode *ip, struct gfs2_dirent *dent,
 				entry_ip = ip;
 			else
 				entry_ip = fsck_load_inode(sdp, entryblock);
-			check_inode_eattr(entry_ip, &pass2_fxns_delete);
+			if (ip->i_di.di_eattr) {
+				check_inode_eattr(entry_ip,
+						  &pass2_fxns_delete);
+			}
 			check_metatree(entry_ip, &pass2_fxns_delete);
 			if (entry_ip != ip)
 				fsck_inode_put(&entry_ip);
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 48/66] libgfs2: Make rebuild functions not re-read ip
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (46 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 47/66] fsck.gfs2: Bad extended attributes not deleted properly rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 49/66] fsck.gfs2: Shorten debug output rpeterso
                   ` (17 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

Before this patch, the libgfs2 rebuild functions in structures.c
were not consistent about reading in the gfs2_inode in-core struct.
Some of the functions did and some didn't.  The previous patch to
make fsck.gfs2 operate on gfs1 introduced a problem because the code
was changed to re-read the inum and statfs files if they were rebuilt.
But since the functions already did the read, it was a double-read.
A double-read is a bad thing because inode writes are now done on
the last inode put, and the double-read messed up the counter.
(Number of inode gets should match puts).  This patch makes all the
build functions consistent: they all put the inode after building,
except for root and master which have no parent inodes.

There was also a minor problem whereby leaf searches were getting
the number of entries from the directory buffer rather than from
the dinode itself.  (The buffer may be out of date, but the dinode
should always be current).  So there were circumstances where you
could add a new dirent to "master" but the count of entries was not
correct in the buffer, which caused the search to stop prematurely.

rhbz#675723
---
 gfs2/convert/gfs2_convert.c |    3 +++
 gfs2/fsck/initialize.c      |    5 +++++
 gfs2/libgfs2/fs_ops.c       |   10 +++++-----
 gfs2/libgfs2/structures.c   |    4 ++--
 gfs2/mkfs/main_mkfs.c       |    2 ++
 5 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 9cc3258..43d0093 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -2158,9 +2158,12 @@ int main(int argc, char **argv)
 		build_per_node(&sb2);
 		/* Create the empty inode number file */
 		build_inum(&sb2); /* Does not do inode_put */
+		gfs2_lookupi(sb2.master_dir, "inum", 4, &sb2.md.inum);
 		/* Create the statfs file */
 		build_statfs(&sb2); /* Does not do inode_put */
 
+		gfs2_lookupi(sb2.master_dir, "statfs", 6, &sb2.md.statfs);
+		do_init_statfs(&sb2);
 		/* Create the resource group index file */
 		build_rindex(&sb2);
 		/* Create the quota file */
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index cee1f49..75b363b 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -392,6 +392,7 @@ static int rebuild_master(struct gfs2_sbd *sdp)
 			IF2DT(S_IFREG | 0600));
 	} else {
 		build_inum(sdp);
+		gfs2_lookupi(sdp->master_dir, "inum", 4, &sdp->md.inum);
 	}
 
 	if (fix_md.statfs) {
@@ -401,6 +402,7 @@ static int rebuild_master(struct gfs2_sbd *sdp)
 			IF2DT(S_IFREG | 0600));
 	} else {
 		build_statfs(sdp);
+		gfs2_lookupi(sdp->master_dir, "statfs", 6, &sdp->md.statfs);
 	}
 
 	if (fix_md.riinode) {
@@ -422,6 +424,8 @@ static int rebuild_master(struct gfs2_sbd *sdp)
 	}
 
 	log_err(_("Master directory rebuilt.\n"));
+	inode_put(&sdp->md.inum);
+	inode_put(&sdp->md.statfs);
 	inode_put(&sdp->master_dir);
 	return 0;
 }
@@ -635,6 +639,7 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
 				   "a valid statfs file; aborting.\n"));
 			goto fail;
 		}
+		do_init_statfs(sdp);
 	}
 	buf = malloc(sdp->md.statfs->i_di.di_size);
 	// FIXME: handle failed malloc
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index e99cc2a..0163371 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -1243,6 +1243,7 @@ static void dir_l_add(struct gfs2_inode *dip, const char *filename, int len,
 	dent->de_hash = cpu_to_be32(dent->de_hash);
 	dent->de_type = cpu_to_be16(type);
 	memcpy((char *)(dent + 1), filename, len);
+	bmodified(dip->i_bh);
 }
 
 void dir_add(struct gfs2_inode *dip, const char *filename, int len,
@@ -1437,10 +1438,9 @@ static int leaf_search(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
 	if (type == IS_LEAF){
 		struct gfs2_leaf *leaf = (struct gfs2_leaf *)bh->b_data;
 		entries = be16_to_cpu(leaf->lf_entries);
-	} else if (type == IS_DINODE) {
-		struct gfs2_dinode *dinode = (struct gfs2_dinode *)bh->b_data;
-		entries = be32_to_cpu(dinode->di_entries);
-	} else
+	} else if (type == IS_DINODE)
+		entries = dip->i_di.di_entries;
+	else
 		return -1;
 
 	hash = gfs2_disk_hash(filename, len);
@@ -1453,7 +1453,7 @@ static int leaf_search(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
 		
 		if (be32_to_cpu(dent->de_hash) == hash &&
 			gfs2_filecmp(filename, (char *)(dent + 1),
-						 be16_to_cpu(dent->de_name_len))){
+				     be16_to_cpu(dent->de_name_len))) {
 			*dent_out = dent;
 			if (dent_prev)
 				*dent_prev = prev;
diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c
index f53b4af..b998f2d 100644
--- a/gfs2/libgfs2/structures.c
+++ b/gfs2/libgfs2/structures.c
@@ -284,7 +284,7 @@ int build_inum(struct gfs2_sbd *sdp)
 		gfs2_dinode_print(&ip->i_di);
 	}
 
-	sdp->md.inum = ip;
+	inode_put(&ip);
 	return 0;
 }
 
@@ -300,7 +300,7 @@ int build_statfs(struct gfs2_sbd *sdp)
 		gfs2_dinode_print(&ip->i_di);
 	}
 
-	sdp->md.statfs = ip;
+	inode_put(&ip);
 	return 0;
 }
 
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index 3db3b14..ee2a5da 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -650,7 +650,9 @@ void main_mkfs(int argc, char *argv[])
 	build_jindex(sdp);
 	build_per_node(sdp);
 	build_inum(sdp);
+	gfs2_lookupi(sdp->master_dir, "inum", 4, &sdp->md.inum);
 	build_statfs(sdp);
+	gfs2_lookupi(sdp->master_dir, "statfs", 6, &sdp->md.statfs);
 	build_rindex(sdp);
 	build_quota(sdp);
 
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 49/66] fsck.gfs2: Shorten debug output
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (47 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 48/66] libgfs2: Make rebuild functions not re-read ip rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 50/66] fsck.gfs2: Increment link count reporting wrong dinode rpeterso
                   ` (16 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch considerably shortens the debug output of fsck.gfs2 by
doing a few things.  First, if fsck is just reporting the setting
of block types, it abbreviates the output by just listing other
blocks in parenthesis.  Second, some of the key debug messages now give
only the block number in hexadecimal rather than both decimal and hex.
In one fsck.gfs2 run I did, it reduced the output from 32GB to 6.7GB.

rhbz#675723
---
 gfs2/fsck/link.c     |   38 ++++++++++++---------------
 gfs2/fsck/metawalk.c |   69 ++++++++++++++++++++++++++++++++-----------------
 gfs2/fsck/pass2.c    |    6 ++--
 3 files changed, 65 insertions(+), 48 deletions(-)

diff --git a/gfs2/fsck/link.c b/gfs2/fsck/link.c
index 18aeeb9..47365d8 100644
--- a/gfs2/fsck/link.c
+++ b/gfs2/fsck/link.c
@@ -35,22 +35,20 @@ int incr_link_count(uint64_t inode_no, uint64_t referenced_from,
 	struct inode_info *ii = NULL;
 
 	ii = inodetree_find(inode_no);
-	/* If the list has entries, look for one that matches
-	 * inode_no */
+	/* If the list has entries, look for one that matches inode_no */
 	if (ii) {
 		ii->counted_links++;
-		log_debug( _("Directory %lld (0x%llx) incremented counted "
-			     "links to %u for %"PRIu64" (0x%" PRIx64 ") "
-			     "via %s\n"),
+		log_debug( _("Dir (0x%llx) incremented counted "
+			     "links to %u for (0x%llx) via %s\n"),
 			   (unsigned long long)referenced_from,
-			   (unsigned long long)referenced_from,
-			   ii->counted_links, inode_no, inode_no, why);
+			   ii->counted_links, (unsigned long long)inode_no,
+			   why);
 		return 0;
 	}
-	log_debug( _("Ref: %lld (0x%llx) No match found when incrementing "
-		     "link for %" PRIu64 " (0x%" PRIx64 ")!\n"),
+	log_debug( _("Ref: (0x%llx) No match found when incrementing "
+		     "link for (0x%llx)!\n"),
 		   (unsigned long long)referenced_from,
-		   (unsigned long long)referenced_from, inode_no, inode_no);
+		   (unsigned long long)inode_no);
 	/* If no match was found, add a new entry and set its
 	 * counted links to 1 */
 	ii = inodetree_insert(inode_no);
@@ -71,24 +69,22 @@ int decr_link_count(uint64_t inode_no, uint64_t referenced_from,
 	 * inode_no */
 	if (ii) {
 		if (!ii->counted_links) {
-			log_debug( _("Directory %lld (0x%llx)'s link to "
-			     " %"PRIu64" (0x%" PRIx64 ") via %s is zero!\n"),
-			   (unsigned long long)referenced_from,
+			log_debug( _("Dir (0x%llx)'s link to "
+			     "(0x%llx) via %s is zero!\n"),
 			   (unsigned long long)referenced_from,
-			   inode_no, inode_no, why);
+			   (unsigned long long)inode_no, why);
 			return 0;
 		}
 		ii->counted_links--;
-		log_debug( _("Directory %lld (0x%llx) decremented counted "
-			     "links to %u for %"PRIu64" (0x%" PRIx64 ") "
-			     "via %s\n"),
-			   (unsigned long long)referenced_from,
+		log_debug( _("Dir (0x%llx) decremented counted "
+			     "links to %u for (0x%llx) via %s\n"),
 			   (unsigned long long)referenced_from,
-			   ii->counted_links, inode_no, inode_no, why);
+			   ii->counted_links, (unsigned long long)inode_no,
+			   why);
 		return 0;
 	}
-	log_debug( _("No match found when decrementing link for %" PRIu64
-			  " (0x%" PRIx64 ")!\n"), inode_no, inode_no);
+	log_debug( _("No match found when decrementing link for (0x%llx)!\n"),
+		   (unsigned long long)inode_no);
 	return -1;
 
 }
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index db7168b..6ddc936 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -107,36 +107,57 @@ int _fsck_blockmap_set(struct gfs2_inode *ip, uint64_t bblock,
 		       const char *caller, int fline)
 {
 	int error;
+	static int prev_ino_addr = 0;
+	static enum gfs2_mark_block prev_mark = 0;
+	static int prevcount = 0;
 
 	if (print_level >= MSG_DEBUG) {
+		if ((ip->i_di.di_num.no_addr == prev_ino_addr) &&
+		    (mark == prev_mark)) {
+			log_info("(0x%llx) ", (unsigned long long)bblock);
+			prevcount++;
+			if (prevcount > 10) {
+				log_info("\n");
+				prevcount = 0;
+			}
 		/* I'm circumventing the log levels here on purpose to make the
 		   output easier to debug. */
-		if (ip->i_di.di_num.no_addr == bblock) {
-			print_fsck_log(MSG_DEBUG, caller, fline,
-				       _("%s inode found at block "
-					 "0x%llx: marking as '%s'\n"),
-				       btype, (unsigned long long)
-				       ip->i_di.di_num.no_addr,
-				       block_type_string(mark));
+		} else if (ip->i_di.di_num.no_addr == bblock) {
+			if (prevcount) {
+				log_info("\n");
+				prevcount = 0;
+			}
+			printf( _("(%s:%d) %s inode found at block "
+				  "(0x%llx): marking as '%s'\n"), caller, fline,
+			       btype,
+			       (unsigned long long)ip->i_di.di_num.no_addr,
+			       block_type_string(mark));
+
 		} else if (mark == gfs2_bad_block || mark == gfs2_meta_inval) {
-			print_fsck_log(MSG_DEBUG, caller, fline,
-				       _("inode 0x%llx references "
-					 "%s block 0x%llx: "
-					 "marking as '%s'\n"),
-				       (unsigned long long)
-				       ip->i_di.di_num.no_addr,
-				       btype, (unsigned long long)bblock,
-				       block_type_string(mark));
+			if (prevcount) {
+				log_info("\n");
+				prevcount = 0;
+			}
+			printf( _("(%s:%d) inode (0x%llx) references %s block"
+				  " (0x%llx): marking as '%s'\n"),
+			       caller, fline,
+			       (unsigned long long)ip->i_di.di_num.no_addr,
+			       btype, (unsigned long long)bblock,
+			       block_type_string(mark));
 		} else {
-			print_fsck_log(MSG_DEBUG, caller, fline,
-				       _("inode 0x%llx references "
-					 "%s block 0x%llx: "
-					 "marking as '%s'\n"),
-				       (unsigned long long)
-				       ip->i_di.di_num.no_addr, btype,
-				       (unsigned long long)bblock,
-				       block_type_string(mark));
+			if (prevcount) {
+				log_info("\n");
+				prevcount = 0;
+			}
+			printf( _("(%s:%d) inode (0x%llx) references %s block"
+				  " (0x%llx): marking as '%s'\n"),
+			       caller, fline,
+			       (unsigned long long)ip->i_di.di_num.no_addr,
+			       btype, (unsigned long long)bblock,
+			       block_type_string(mark));
 		}
+		prev_ino_addr = ip->i_di.di_num.no_addr;
+		prev_mark = mark;
 	}
 
 	/* First, check the rgrp bitmap against what we think it should be.
@@ -699,7 +720,7 @@ static int check_leaf_blks(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 			if (!leaf.lf_next || error)
 				break;
 			leaf_no = leaf.lf_next;
-			log_debug( _("Leaf chain 0x%llx detected.\n"),
+			log_debug( _("Leaf chain (0x%llx) detected.\n"),
 				   (unsigned long long)leaf_no);
 		} while (1); /* while we have chained leaf blocks */
 	} /* for every leaf block */
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index e02fdd0..be0e5fe 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -69,7 +69,7 @@ static int set_dotdot_dir(struct gfs2_sbd *sdp, uint64_t childblock,
 	}
 	if (di->dinode != childblock) {
 		log_debug("'..' doesn't point to what we found: childblock "
-			  "0x%llx != dinode 0x%llx\n",
+			  "(0x%llx) != dinode (0x%llx)\n",
 			  (unsigned long long)childblock,
 			  (unsigned long long)di->dinode);
 		return -1;
@@ -86,8 +86,8 @@ static int set_dotdot_dir(struct gfs2_sbd *sdp, uint64_t childblock,
 			  (unsigned long long)di->dotdot_parent);
 		return -1;
 	}
-	log_debug("Setting '..' for directory block 0x%llx to parent 0x%llx\n",
-		  (unsigned long long)childblock,
+	log_debug("Setting '..' for directory block (0x%llx) to parent "
+		  "(0x%llx)\n", (unsigned long long)childblock,
 		  (unsigned long long)parentblock);
 	di->dotdot_parent = parentblock;
 	return 0;
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 50/66] fsck.gfs2: Increment link count reporting wrong dinode
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (48 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 49/66] fsck.gfs2: Shorten debug output rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 51/66] fsck.gfs2: system dinodes take priority over user dinodes rpeterso
                   ` (15 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

The output from fsck.gfs2 was wrong when it reported about a
link count change for lost+found.  This patch fixes the message
so it reports the correct dinode block number.

rhbz#675723
---
 gfs2/fsck/lost_n_found.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index af4189f..c028f8d 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -268,7 +268,7 @@ int add_inode_to_lf(struct gfs2_inode *ip){
 	/* If it's a directory, lost+found is back-linked to it via .. */
 	if (is_dir(&ip->i_di, sdp->gfs1))
 		incr_link_count(lf_dip->i_di.di_num.no_addr,
-				ip->i_di.di_mode, _("to lost+found"));
+				ip->i_di.di_num.no_addr, _("to lost+found"));
 
 	log_notice( _("Added inode #%llu (0x%llx) to lost+found\n"),
 		    (unsigned long long)ip->i_di.di_num.no_addr,
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 51/66] fsck.gfs2: system dinodes take priority over user dinodes
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (49 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 50/66] fsck.gfs2: Increment link count reporting wrong dinode rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 52/66] fsck.gfs2: Recognize partially gfs2-converted dinodes rpeterso
                   ` (14 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

In testing fsck.gfs2 I noticed some incorrect behavior: If a block
was referenced incorrectly by two dinodes, fsck deleted which
ever reference it found first.  Therefore, if a system dinode
and a user dinode referenced the same block, fsck.gfs2 could
mistakenly delete the system dinode.  For example, a journal could
get deleted because a user dinode improperly referenced one of its
blocks.  This patch gives priority to system dinodes when resolving
duplicates.

rhbz#675723
---
 gfs2/fsck/pass1b.c |    9 ++++++++-
 gfs2/fsck/util.c   |   14 ++++++++++++--
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index b7be683..da71f99 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -483,7 +483,14 @@ static int resolve_dup_references(struct gfs2_sbd *sdp, struct duptree *b,
 				continue; /* don't delete the dinode */
 			}
 		}
-
+		/* If this reference is from a system inode, for example, if
+		   it's data or metadata inside a journal, the reference
+		   should take priority over user dinodes that reference the
+		   block. */
+		if (!found_good_ref && fsck_system_inode(sdp, id->block_no)) {
+			found_good_ref = 1;
+			continue; /* don't delete the dinode */
+		}
 		log_warn( _("Inode %s (%lld/0x%llx) references block "
 			    "%llu (0x%llx) as '%s', but the block is "
 			    "really %s.\n"),
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index 69bf328..0be86de 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -280,8 +280,18 @@ int add_duplicate_ref(struct gfs2_inode *ip, uint64_t block,
 		   inode reference list otherwise put it on the normal list. */
 		if (!inode_valid || q == gfs2_inode_invalid)
 			osi_list_add_prev(&id->list, &dt->ref_invinode_list);
-		else
-			osi_list_add_prev(&id->list, &dt->ref_inode_list);
+		else {
+			/* If this is a system dinode, we want the duplicate
+			   processing to find it first. That way references
+			   from inside journals, et al, will take priority.
+			   We don't want to delete journals in favor of dinodes
+			   that reference a block inside a journal. */
+			if (fsck_system_inode(ip->i_sbd, id->block_no))
+				osi_list_add(&id->list, &dt->ref_inode_list);
+			else
+				osi_list_add_prev(&id->list,
+						  &dt->ref_inode_list);
+		}
 	}
 	id->reftypecount[reftype]++;
 	id->dup_count++;
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 52/66] fsck.gfs2: Recognize partially gfs2-converted dinodes
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (50 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 51/66] fsck.gfs2: system dinodes take priority over user dinodes rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 53/66] fsck.gfs2: Print step 2 duplicate debug msg first rpeterso
                   ` (13 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

In testing fsck.gfs2 I noticed that if a file system had some
leftover gfs2 dinodes (due to an interrupted gfs2_convert or
in my case, because I had previously loaded gfs2 metadata that
left gfs2 blocks laying around the gfs1 file system) those gfs2
dinodes were not properly processed.  In particular, it would not
recognize gfs2-style directories as directories because of the
difference in where dinode mode information is kept.  This patch
gives fsck.gfs2 the ability to correctly identify gfs2 dinodes
when checking a gfs1 file system.

rhbz#675723
---
 gfs2/fsck/lost_n_found.c |    4 ++--
 gfs2/fsck/util.c         |    2 +-
 gfs2/fsck/util.h         |   11 +++++++++--
 3 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index c028f8d..16afb11 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -207,7 +207,7 @@ int add_inode_to_lf(struct gfs2_inode *ip){
 	lf_blocks = lf_dip->i_di.di_blocks;
 
 	if (sdp->gfs1)
-		mode = gfs_to_gfs2_mode(ip->i_di.__pad1);
+		mode = gfs_to_gfs2_mode(ip);
 	else
 		mode = ip->i_di.di_mode & S_IFMT;
 
@@ -266,7 +266,7 @@ int add_inode_to_lf(struct gfs2_inode *ip){
 	incr_link_count(ip->i_di.di_num.no_addr, lf_dip->i_di.di_num.no_addr,
 			_("from lost+found"));
 	/* If it's a directory, lost+found is back-linked to it via .. */
-	if (is_dir(&ip->i_di, sdp->gfs1))
+	if (mode == S_IFDIR)
 		incr_link_count(lf_dip->i_di.di_num.no_addr,
 				ip->i_di.di_num.no_addr, _("to lost+found"));
 
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index 0be86de..92818fb 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -479,7 +479,7 @@ int set_ip_blockmap(struct gfs2_inode *ip, int instree)
 	uint32_t mode;
 
 	if (sdp->gfs1)
-		mode = gfs_to_gfs2_mode(ip->i_di.__pad1);
+		mode = gfs_to_gfs2_mode(ip);
 	else
 		mode = ip->i_di.di_mode & S_IFMT;
 
diff --git a/gfs2/fsck/util.h b/gfs2/fsck/util.h
index 6581cb1..2f74af3 100644
--- a/gfs2/fsck/util.h
+++ b/gfs2/fsck/util.h
@@ -143,8 +143,10 @@ static inline int is_dir(struct gfs2_dinode *dinode, int gfs1)
 	return 0;
 }
 
-static inline uint32_t gfs_to_gfs2_mode(uint32_t gfs1mode)
+static inline uint32_t gfs_to_gfs2_mode(struct gfs2_inode *ip)
 {
+	uint16_t gfs1mode = ip->i_di.__pad1;
+
 	switch (gfs1mode) {
 	case GFS_FILE_DIR:
 		return S_IFDIR;
@@ -161,7 +163,12 @@ static inline uint32_t gfs_to_gfs2_mode(uint32_t gfs1mode)
 	case GFS_FILE_SOCK:
 		return S_IFSOCK;
 	default:
-		return S_IFREG;
+		/* This could be an aborted gfs2_convert so look for both. */
+		if (ip->i_di.di_entries ||
+		    (ip->i_di.di_mode & S_IFMT) == S_IFDIR)
+			return S_IFDIR;
+		else
+			return S_IFREG;
 	}
 }
 
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 53/66] fsck.gfs2: Print step 2 duplicate debug msg first
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (51 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 52/66] fsck.gfs2: Recognize partially gfs2-converted dinodes rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 54/66] fsck.gfs2: pass1c counts percentage backward rpeterso
                   ` (12 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

In testing fsck.gfs2 I noticed that when duplicates were resolved,
the "step 2" debug message was printed after step 2 was actually
done.  That's misleading, so this patch changes it.

rhbz#675723
---
 gfs2/fsck/pass1b.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/gfs2/fsck/pass1b.c b/gfs2/fsck/pass1b.c
index da71f99..39c3289 100644
--- a/gfs2/fsck/pass1b.c
+++ b/gfs2/fsck/pass1b.c
@@ -642,15 +642,15 @@ static int handle_dup_blk(struct gfs2_sbd *sdp, struct duptree *b)
 	 *          directory inode referencing a data block as a leaf block.
 	 */
 	if (!last_reference) {
-		last_reference = resolve_dup_references(sdp, b,
-							&b->ref_inode_list,
-							&dh, 0,
-							acceptable_ref);
 		log_debug( _("----------------------------------------------\n"
 			     "Step 2: Eliminate references to block %llu "
 			     "(0x%llx) that need the wrong block type.\n"),
 			   (unsigned long long)b->block,
 			   (unsigned long long)b->block);
+		last_reference = resolve_dup_references(sdp, b,
+							&b->ref_inode_list,
+							&dh, 0,
+							acceptable_ref);
 	}
 	/* Step 3 - We have multiple dinodes referencing it as the correct
 	 *          type.  Just blast one of them.
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 54/66] fsck.gfs2: pass1c counts percentage backward
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (52 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 53/66] fsck.gfs2: Print step 2 duplicate debug msg first rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 55/66] fsck.gfs2: Speed up rangecheck functions rpeterso
                   ` (11 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

In testing I noticed that pass1c, which checks all extended
attributes, counted percent-complete backwards.  It's better to
count forward because disk block seeks will be more efficient.
This patch changes the special_list functions of block_list to
add items as "prev" so that they're processed in block order.

rhbz#675723
---
 gfs2/libgfs2/block_list.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/gfs2/libgfs2/block_list.c b/gfs2/libgfs2/block_list.c
index 65003b0..554a1ef 100644
--- a/gfs2/libgfs2/block_list.c
+++ b/gfs2/libgfs2/block_list.c
@@ -42,7 +42,7 @@ void gfs2_special_add(struct special_blocks *blocklist, uint64_t block)
 	if (b) {
 		memset(b, 0, sizeof(*b));
 		b->block = block;
-		osi_list_add(&b->list, &blocklist->list);
+		osi_list_add_prev(&b->list, &blocklist->list);
 	}
 }
 
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 55/66] fsck.gfs2: Speed up rangecheck functions
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (53 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 54/66] fsck.gfs2: pass1c counts percentage backward rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 56/66] libgfs2: Make in-core rgrps use rbtree rpeterso
                   ` (10 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch speeds up the block rangecheck functions by passing
the block type in as an integer rather than a translated string
constant.  The translation functions were a bit costly.

rhbz#675723
---
 gfs2/fsck/pass1.c |   26 ++++++++++++++------------
 1 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 3e6b816..60e7cce 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -1052,9 +1052,14 @@ static int invalidate_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
  * be trusted. Thus it needs to be in a separate loop.
  * Returns: 0 if good range, otherwise != 0
  */
+enum b_types { btype_meta, btype_leaf, btype_data, btype_ieattr, btype_eattr};
+const char *btypes[5] = {
+	"metadata", "leaf", "data", "indirect extended attribute",
+	"extended attribute" };
+
 static int rangecheck_block(struct gfs2_inode *ip, uint64_t block,
-			    struct gfs2_buffer_head **bh,
-			    const char *btype, void *private)
+			    struct gfs2_buffer_head **bh, enum b_types btype,
+			    void *private)
 {
 	long *bad_pointers = (long *)private;
 	uint8_t q;
@@ -1063,7 +1068,7 @@ static int rangecheck_block(struct gfs2_inode *ip, uint64_t block,
 		(*bad_pointers)++;
 		log_info( _("Bad %s block pointer (invalid or out of range "
 			    "#%ld) found in inode %lld (0x%llx).\n"),
-			  btype, *bad_pointers,
+			  btypes[btype], *bad_pointers,
 			  (unsigned long long)ip->i_di.di_num.no_addr,
 			  (unsigned long long)ip->i_di.di_num.no_addr);
 		if ((*bad_pointers) <= BAD_POINTER_TOLERANCE)
@@ -1077,7 +1082,7 @@ static int rangecheck_block(struct gfs2_inode *ip, uint64_t block,
 		(*bad_pointers)++;
 		log_info( _("Duplicated %s block pointer (violation %ld, block"
 			    " %lld (0x%llx)) found in inode %lld (0x%llx).\n"),
-			  btype, *bad_pointers,
+			  btypes[btype], *bad_pointers,
 			  (unsigned long long)block, (unsigned long long)block,
 			  (unsigned long long)ip->i_di.di_num.no_addr,
 			  (unsigned long long)ip->i_di.di_num.no_addr);
@@ -1093,36 +1098,33 @@ static int rangecheck_metadata(struct gfs2_inode *ip, uint64_t block,
 			       struct gfs2_buffer_head **bh, int h,
 			       void *private)
 {
-	return rangecheck_block(ip, block, bh, _("metadata"), private);
+	return rangecheck_block(ip, block, bh, btype_meta, private);
 }
 
 static int rangecheck_leaf(struct gfs2_inode *ip, uint64_t block,
 			   void *private)
 {
-	return rangecheck_block(ip, block, NULL, _("leaf"), private);
+	return rangecheck_block(ip, block, NULL, btype_leaf, private);
 }
 
 static int rangecheck_data(struct gfs2_inode *ip, uint64_t block,
 			   void *private)
 {
-	return rangecheck_block(ip, block, NULL, _("data"), private);
+	return rangecheck_block(ip, block, NULL, btype_data, private);
 }
 
 static int rangecheck_eattr_indir(struct gfs2_inode *ip, uint64_t block,
 				  uint64_t parent,
 				  struct gfs2_buffer_head **bh, void *private)
 {
-	return rangecheck_block(ip, block, NULL,
-				_("indirect extended attribute"),
-				private);
+	return rangecheck_block(ip, block, NULL, btype_ieattr, private);
 }
 
 static int rangecheck_eattr_leaf(struct gfs2_inode *ip, uint64_t block,
 				 uint64_t parent, struct gfs2_buffer_head **bh,
 				 void *private)
 {
-	return rangecheck_block(ip, block, NULL, _("extended attribute"),
-				private);
+	return rangecheck_block(ip, block, NULL, btype_eattr, private);
 }
 
 struct metawalk_fxns rangecheck_fxns = {
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 56/66] libgfs2: Make in-core rgrps use rbtree
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (54 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 55/66] fsck.gfs2: Speed up rangecheck functions rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 57/66] fsck.gfs2: Fix memory leaks rpeterso
                   ` (9 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch changes the in-core structure used for resource groups
from a linked list to an rbtree.

rhbz#675723
---
 gfs2/convert/gfs2_convert.c |   61 ++++++------
 gfs2/edit/extended.c        |    2 +-
 gfs2/edit/hexedit.c         |   56 ++++++-----
 gfs2/edit/hexedit.h         |    4 +-
 gfs2/edit/savemeta.c        |   26 +++---
 gfs2/fsck/initialize.c      |   26 +++---
 gfs2/fsck/lost_n_found.c    |   12 +-
 gfs2/fsck/main.c            |    9 +-
 gfs2/fsck/metawalk.c        |    2 +-
 gfs2/fsck/pass1.c           |   14 ++--
 gfs2/fsck/pass5.c           |   11 +-
 gfs2/fsck/rgrepair.c        |  220 ++++++++++++++++---------------------------
 gfs2/libgfs2/fs_bits.c      |    4 +-
 gfs2/libgfs2/fs_geometry.c  |   58 ++++++------
 gfs2/libgfs2/fs_ops.c       |   16 ++--
 gfs2/libgfs2/libgfs2.h      |   34 ++++---
 gfs2/libgfs2/rgrp.c         |   78 ++++++++++------
 gfs2/libgfs2/structures.c   |   26 +++---
 gfs2/libgfs2/super.c        |   27 ++---
 gfs2/mkfs/main_grow.c       |   62 +++++++------
 gfs2/mkfs/main_mkfs.c       |    6 +-
 21 files changed, 365 insertions(+), 389 deletions(-)

diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 43d0093..8ed2c1a 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -168,7 +168,7 @@ void print_it(const char *label, const char *fmt, const char *fmt2, ...)
 /*                   Fixes all unallocated metadata bitmap states (which are */
 /*                   valid in gfs1 but invalid in gfs2).                     */
 /* ------------------------------------------------------------------------- */
-static void convert_bitmaps(struct gfs2_sbd *sdp, struct rgrp_list *rg)
+static void convert_bitmaps(struct gfs2_sbd *sdp, struct rgrp_tree *rg)
 {
 	uint32_t blk;
 	int x, y;
@@ -196,16 +196,18 @@ static void convert_bitmaps(struct gfs2_sbd *sdp, struct rgrp_list *rg)
 /* ------------------------------------------------------------------------- */
 static int convert_rgs(struct gfs2_sbd *sbp)
 {
-	struct rgrp_list *rgd;
-	osi_list_t *tmp;
+	struct rgrp_tree *rgd;
+	struct osi_node *n, *next = NULL;
 	struct gfs1_rgrp *rgd1;
 	int rgs = 0;
 
 	/* --------------------------------- */
 	/* Now convert its rgs into gfs2 rgs */
 	/* --------------------------------- */
-	osi_list_foreach(tmp, &sbp->rglist) {
-		rgd = osi_list_entry(tmp, struct rgrp_list, list);
+	for (n = osi_first(&sbp->rgtree); n; n = next) {
+		next = osi_next(n);
+		rgd = (struct rgrp_tree *)n;
+
 		rgd1 = (struct gfs1_rgrp *)&rgd->rg; /* recast as gfs1 structure */
 		/* rg_freemeta is a gfs1 structure, so libgfs2 doesn't know to */
 		/* convert from be to cpu. We must do it now. */
@@ -978,8 +980,8 @@ static int adjust_inode(struct gfs2_sbd *sbp, struct gfs2_buffer_head *bh)
 /* ------------------------------------------------------------------------- */
 static int inode_renumber(struct gfs2_sbd *sbp, uint64_t root_inode_addr, osi_list_t *cdpn_to_fix)
 {
-	struct rgrp_list *rgd;
-	osi_list_t *tmp;
+	struct rgrp_tree *rgd;
+	struct osi_node *n, *next = NULL;
 	uint64_t block;
 	struct gfs2_buffer_head *bh;
 	int first;
@@ -994,9 +996,10 @@ static int inode_renumber(struct gfs2_sbd *sbp, uint64_t root_inode_addr, osi_li
 	/* ---------------------------------------------------------------- */
 	/* Traverse the resource groups to figure out where the inodes are. */
 	/* ---------------------------------------------------------------- */
-	osi_list_foreach(tmp, &sbp->rglist) {
+	for (n = osi_first(&sbp->rgtree); n; n = next) {
+		next = osi_next(n);
+		rgd = (struct rgrp_tree *)n;
 		rgs_processed++;
-		rgd = osi_list_entry(tmp, struct rgrp_list, list);
 		first = 1;
 		while (1) {    /* for all inodes in the resource group */
 			gettimeofday(&tv, NULL);
@@ -1498,7 +1501,7 @@ static int init(struct gfs2_sbd *sbp)
 	sbp->dinodes_alloced = 0; /* dinodes allocated - total them up later */
 	sbp->sd_sb.sb_bsize = GFS2_DEFAULT_BSIZE;
 	sbp->bsize = sbp->sd_sb.sb_bsize;
-	osi_list_init(&sbp->rglist);
+	sbp->rgtree.osi_node = NULL;
 	if (compute_constants(sbp)) {
 		log_crit("Error: Bad constants (1)\n");
 		exit(-1);
@@ -1726,9 +1729,10 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp)
 	int error = 0;
 	int j, x;
 	struct gfs1_jindex *jndx;
-	struct rgrp_list *rgd, *rgdhigh;
-	osi_list_t *tmp;
+	struct rgrp_tree *rgd, *rgdhigh;
+	struct osi_node *n, *next = NULL;
 	struct gfs2_meta_header mh;
+	uint64_t ri_addr;
 
 	mh.mh_magic = GFS2_MAGIC;
 	mh.mh_type = GFS2_METATYPE_RB;
@@ -1746,8 +1750,9 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp)
 		   by jadd.  gfs_grow adds rgs out of order, so we can't count
 		   on them being in ascending order. */
 		rgdhigh = NULL;
-		osi_list_foreach(tmp, &sdp->rglist) {
-			rgd = osi_list_entry(tmp, struct rgrp_list, list);
+		for (n = osi_first(&sdp->rgtree); n; n = next) {
+			next = osi_next(n);
+			rgd = (struct rgrp_tree *)n;
 			if (rgd->ri.ri_addr < jndx->ji_addr &&
 				((rgdhigh == NULL) ||
 				 (rgd->ri.ri_addr > rgdhigh->ri.ri_addr)))
@@ -1760,15 +1765,12 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp)
 			log_crit("Error: No suitable rg found for journal.\n");
 			return -1;
 		}
+		ri_addr = jndx->ji_addr;
 		/* Allocate a new rgd entry which includes rg and ri. */
+		rgd = rgrp_insert(&sdp->rgtree, ri_addr);
 		/* convert the gfs1 rgrp into a new gfs2 rgrp */
-		rgd = malloc(sizeof(struct rgrp_list));
-		if (!rgd) {
-			log_crit("Error: unable to allocate memory for rg conversion.\n");
-			return -1;
-		}
-		memset(rgd, 0, sizeof(struct rgrp_list));
-		size = jndx->ji_nsegment * be32_to_cpu(raw_gfs1_ondisk_sb.sb_seg_size);
+		size = jndx->ji_nsegment *
+			be32_to_cpu(raw_gfs1_ondisk_sb.sb_seg_size);
 		rgd->rg.rg_header.mh_magic = GFS2_MAGIC;
 		rgd->rg.rg_header.mh_type = GFS2_METATYPE_RG;
 		rgd->rg.rg_header.mh_format = GFS2_FORMAT_RG;
@@ -1811,9 +1813,6 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp)
 			else
 				gfs2_rgrp_out(&rgd->rg, rgd->bh[x]);
 		}
-		/* Add the new gfs2 rg to our list: We'll output the rg index later. */
-		osi_list_add_prev((osi_list_t *)&rgd->list,
-						  (osi_list_t *)&sdp->rglist);
 	} /* for each journal */
 	return error;
 }/* journ_space_to_rg */
@@ -1989,16 +1988,17 @@ static int check_fit(struct gfs2_sbd *sdp)
 
 	/* build_rindex() */
 	{
-		osi_list_t *tmp, *head;
+		struct osi_node *n, *next = NULL;
 		unsigned int rg_count = 0;
 
 		blks_need++; /* creationg of 'rindex' disk inode */
 		/* find the total # of rindex entries, gives size of rindex inode */
-		for (head = &sdp->rglist, tmp = head->next; tmp != head;
-		     tmp = tmp->next)
+		for (n = osi_first(&sdp->rgtree); n; n = next) {
+			next = osi_next(n);
 			rg_count++;
-		blks_need += 
-			total_file_blocks(sdp, rg_count * sizeof(struct gfs2_rindex), 1);
+		}
+		blks_need += total_file_blocks(sdp, rg_count *
+					       sizeof(struct gfs2_rindex), 1);
 	}
 	/* build_quota() */
 	blks_need++; /* quota inode block and uid=gid=0 quota - total 1 block */
@@ -2133,6 +2133,7 @@ int main(int argc, char **argv)
 	/* ---------------------------------------------- */
 	if (!error) {
 		int jreduce = 0;
+
 		/* Now we've got to treat it as a gfs2 file system */
 		if (compute_constants(&sb2)) {
 			log_crit("Error: Bad constants (1)\n");
@@ -2191,7 +2192,7 @@ int main(int argc, char **argv)
 		fsync(sb2.device_fd); /* write the buffers to disk */
 
 		/* Now free all the in memory */
-		gfs2_rgrp_free(&sb2.rglist);
+		gfs2_rgrp_free(&sb2.rgtree);
 		log_notice("Committing changes to disk.\n");
 		fflush(stdout);
 		/* Set filesystem type in superblock to gfs2.  We do this at the */
diff --git a/gfs2/edit/extended.c b/gfs2/edit/extended.c
index 6326ec3..07c6421 100644
--- a/gfs2/edit/extended.c
+++ b/gfs2/edit/extended.c
@@ -661,7 +661,7 @@ int display_extended(void)
 		return -1;
 	else if (display_indirect(indirect, indirect_blocks, 0, 0) == 0)
 		return -1;
-	else if (block_is_rglist()) {
+	else if (block_is_rgtree()) {
 		if (sbd.gfs1)
 			tmp_bh = bread(&sbd, sbd1->sb_rindex_di.no_addr);
 		else
diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index a2ccc60..a36f9a3 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -1148,7 +1148,7 @@ int display_block_type(int from_restore)
 		return ret_type;
 	if (termlines && dmode == HEX_MODE) {
 		int type;
-		struct rgrp_list *rgd;
+		struct rgrp_tree *rgd;
 
 		rgd = gfs2_blk2rgrpd(&sbd, block);
 		if (rgd) {
@@ -1467,7 +1467,7 @@ static void rgcount(void)
 	       (unsigned long long)sbd.md.riinode->i_di.di_size /
 	       sizeof(struct gfs2_rindex));
 	inode_put(&sbd.md.riinode);
-	gfs2_rgrp_free(&sbd.rglist);
+	gfs2_rgrp_free(&sbd.rgtree);
 	exit(EXIT_SUCCESS);
 }
 
@@ -1695,7 +1695,7 @@ static int block_has_extended_info(void)
 {
 	if (has_indirect_blocks() ||
 	    block_is_rindex() ||
-	    block_is_rglist() ||
+	    block_is_rgtree() ||
 	    block_is_jindex() ||
 	    block_is_inum_file() ||
 	    block_is_statfs_file() ||
@@ -1722,7 +1722,7 @@ static void read_superblock(int fd)
 	sbd.utsize = GFS2_DEFAULT_UTSIZE;
 	sbd.qcsize = GFS2_DEFAULT_QCSIZE;
 	sbd.time = time(NULL);
-	osi_list_init(&sbd.rglist);
+	sbd.rgtree.osi_node = NULL;
 	gfs2_sb_in(&sbd.sd_sb, bh); /* parse it out into the sb structure */
 	/* Check to see if this is really gfs1 */
 	if (sbd1->sb_fs_format == GFS_FORMAT_FS &&
@@ -2039,7 +2039,7 @@ static uint64_t find_metablockoftype_slow(uint64_t startblk, int metatype, int p
 		else
 			printf("%llu\n", (unsigned long long)blk);
 	}
-	gfs2_rgrp_free(&sbd.rglist);
+	gfs2_rgrp_free(&sbd.rgtree);
 	if (print)
 		exit(0);
 	return blk;
@@ -2054,16 +2054,17 @@ static uint64_t find_metablockoftype_slow(uint64_t startblk, int metatype, int p
 /* ------------------------------------------------------------------------ */
 static uint64_t find_metablockoftype_rg(uint64_t startblk, int metatype, int print)
 {
+	struct osi_node *n, *next = NULL;
 	uint64_t blk;
 	int first = 1, found = 0;
-	struct rgrp_list *rgd;
+	struct rgrp_tree *rgd;
 	struct gfs2_rindex *ri;
-	osi_list_t *tmp;
 
 	blk = 0;
 	/* Skip the rgs prior to the block we've been given */
-	for(tmp = sbd.rglist.next; tmp != &sbd.rglist; tmp = tmp->next){
-		rgd = osi_list_entry(tmp, struct rgrp_list, list);
+	for (n = osi_first(&sbd.rgtree); n; n = next) {
+		next = osi_next(n);
+		rgd = (struct rgrp_tree *)n;
 		ri = &rgd->ri;
 		if (first && startblk <= ri->ri_data0) {
 			startblk = ri->ri_data0;
@@ -2078,12 +2079,13 @@ static uint64_t find_metablockoftype_rg(uint64_t startblk, int metatype, int pri
 	if (!rgd) {
 		if (print)
 			printf("0\n");
-		gfs2_rgrp_free(&sbd.rglist);
+		gfs2_rgrp_free(&sbd.rgtree);
 		if (print)
 			exit(-1);
 	}
-	for(; !found && tmp != &sbd.rglist; tmp = tmp->next){
-		rgd = osi_list_entry(tmp, struct rgrp_list, list);	
+	for (; !found && n; n = next){
+		next = osi_next(n);
+		rgd = (struct rgrp_tree *)n;
 		first = 1;
 		do {
 			if (gfs2_next_rg_metatype(&sbd, rgd, &blk, metatype,
@@ -2104,7 +2106,7 @@ static uint64_t find_metablockoftype_rg(uint64_t startblk, int metatype, int pri
 		else
 			printf("%llu\n", (unsigned long long)blk);
 	}
-	gfs2_rgrp_free(&sbd.rglist);
+	gfs2_rgrp_free(&sbd.rgtree);
 	if (print)
 		exit(0);
 	return blk;
@@ -2138,7 +2140,7 @@ static uint64_t find_metablockoftype(const char *strtype, int print)
 			"specified: must be one of:\n");
 		fprintf(stderr, "sb rg rb di in lf jd lh ld"
 			" ea ed lb 13 qc\n");
-		gfs2_rgrp_free(&sbd.rglist);
+		gfs2_rgrp_free(&sbd.rgtree);
 		exit(-1);
 	}
 	return blk;
@@ -2439,7 +2441,7 @@ static void find_print_block_type(void)
 	type = get_block_type(lbh);
 	print_block_type(tblock, type, "");
 	brelse(lbh);
-	gfs2_rgrp_free(&sbd.rglist);
+	gfs2_rgrp_free(&sbd.rgtree);
 	exit(0);
 }
 
@@ -2450,7 +2452,7 @@ static void find_print_block_rg(int bitmap)
 {
 	uint64_t rblock, rgblock;
 	int i;
-	struct rgrp_list *rgd;
+	struct rgrp_tree *rgd;
 
 	rblock = blockstack[blockhist % BLOCK_STACK_SIZE].block;
 	if (rblock == sbd.sb_addr)
@@ -2482,7 +2484,7 @@ static void find_print_block_rg(int bitmap)
 			printf("-1 (block invalid or part of an rgrp).\n");
 		}
 	}
-	gfs2_rgrp_free(&sbd.rglist);
+	gfs2_rgrp_free(&sbd.rgtree);
 	exit(0);
 }
 
@@ -2493,7 +2495,7 @@ static void find_change_block_alloc(int *newval)
 {
 	uint64_t ablock;
 	int type;
-	struct rgrp_list *rgd;
+	struct rgrp_tree *rgd;
 
 	if (newval &&
 	    (*newval < GFS2_BLKST_FREE || *newval > GFS2_BLKST_DINODE)) {
@@ -2503,7 +2505,7 @@ static void find_change_block_alloc(int *newval)
 		       *newval);
 		for (i = GFS2_BLKST_FREE; i <= GFS2_BLKST_DINODE; i++)
 			printf("%d - %s\n", i, allocdesc[sbd.gfs1][i]);
-		gfs2_rgrp_free(&sbd.rglist);
+		gfs2_rgrp_free(&sbd.rgtree);
 		exit(-1);
 	}
 	ablock = blockstack[blockhist % BLOCK_STACK_SIZE].block;
@@ -2529,12 +2531,12 @@ static void find_change_block_alloc(int *newval)
 			}
 			gfs2_rgrp_relse(rgd);
 		} else {
-			gfs2_rgrp_free(&sbd.rglist);
+			gfs2_rgrp_free(&sbd.rgtree);
 			printf("-1 (block invalid or part of an rgrp).\n");
 			exit(-1);
 		}
 	}
-	gfs2_rgrp_free(&sbd.rglist);
+	gfs2_rgrp_free(&sbd.rgtree);
 	if (newval)
 		fsync(sbd.device_fd);
 	exit(0);
@@ -3461,7 +3463,7 @@ static void process_parameters(int argc, char *argv[], int pass)
 				printf("Error: field not specified.\n");
 				printf("Format is: %s -p <block> field "
 				       "<field> [newvalue]\n", argv[0]);
-				gfs2_rgrp_free(&sbd.rglist);
+				gfs2_rgrp_free(&sbd.rgtree);
 				exit(EXIT_FAILURE);
 			}
 			process_field(argv[i], argv[i + 1]);
@@ -3494,7 +3496,7 @@ static void process_parameters(int argc, char *argv[], int pass)
 				printf("Error: rg # not specified.\n");
 				printf("Format is: %s rgflags rgnum"
 				       "[newvalue]\n", argv[0]);
-				gfs2_rgrp_free(&sbd.rglist);
+				gfs2_rgrp_free(&sbd.rgtree);
 				exit(EXIT_FAILURE);
 			}
 			if (argv[i][0]=='0' && argv[i][1]=='x')
@@ -3511,7 +3513,7 @@ static void process_parameters(int argc, char *argv[], int pass)
 					new_flags = atoi(argv[i]);
 			}
 			set_rgrp_flags(rg, new_flags, set, FALSE);
-			gfs2_rgrp_free(&sbd.rglist);
+			gfs2_rgrp_free(&sbd.rgtree);
 			exit(EXIT_SUCCESS);
 		} else if (!strcmp(argv[i], "rg")) {
 			int rg;
@@ -3520,7 +3522,7 @@ static void process_parameters(int argc, char *argv[], int pass)
 			if (i >= argc - 1) {
 				printf("Error: rg # not specified.\n");
 				printf("Format is: %s rg rgnum\n", argv[0]);
-				gfs2_rgrp_free(&sbd.rglist);
+				gfs2_rgrp_free(&sbd.rgtree);
 				exit(EXIT_FAILURE);
 			}
 			rg = atoi(argv[i]);
@@ -3529,7 +3531,7 @@ static void process_parameters(int argc, char *argv[], int pass)
 				push_block(temp_blk);
 			} else {
 				set_rgrp_flags(rg, 0, FALSE, TRUE);
-				gfs2_rgrp_free(&sbd.rglist);
+				gfs2_rgrp_free(&sbd.rgtree);
 				exit(EXIT_SUCCESS);
 			}
 		}
@@ -3639,6 +3641,6 @@ int main(int argc, char *argv[])
 	close(fd);
 	if (indirect)
 		free(indirect);
-	gfs2_rgrp_free(&sbd.rglist);
+	gfs2_rgrp_free(&sbd.rgtree);
  	exit(EXIT_SUCCESS);
 }
diff --git a/gfs2/edit/hexedit.h b/gfs2/edit/hexedit.h
index 07125bd..02281cf 100644
--- a/gfs2/edit/hexedit.h
+++ b/gfs2/edit/hexedit.h
@@ -111,11 +111,11 @@ extern int indirect_blocks;  /* count of indirect blocks */
 extern enum dsp_mode dmode;
 
 /* ------------------------------------------------------------------------ */
-/* block_is_rglist - there's no such block as the rglist.  This is a        */
+/* block_is_rgtree - there's no such block as the rglist.  This is a        */
 /*                   special case meant to parse the rindex and follow the  */
 /*                   blocks to the real rgs.                                */
 /* ------------------------------------------------------------------------ */
-static inline int block_is_rglist(void)
+static inline int block_is_rgtree(void)
 {
 	if (block == RGLIST_DUMMY_BLOCK)
 		return TRUE;
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index 8ccbf8a..33f2970 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -587,7 +587,7 @@ static void get_journal_inode_blocks(void)
 	}
 }
 
-static int next_rg_freemeta(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
+static int next_rg_freemeta(struct gfs2_sbd *sdp, struct rgrp_tree *rgd,
 			    uint64_t *nrfblock, int first)
 {
 	struct gfs2_bitmap *bits = NULL;
@@ -629,11 +629,10 @@ static int next_rg_freemeta(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
 void savemeta(char *out_fn, int saveoption, int gziplevel)
 {
 	int slow, ret;
-	osi_list_t *tmp;
 	int rgcount;
 	uint64_t jindex_block;
 	struct gfs2_buffer_head *lbh;
-	struct rgrp_list *last_rgd, *prev_rgd;
+	struct rgrp_tree *last_rgd, *prev_rgd;
 	struct metafd mfd;
 
 	slow = (saveoption == 1);
@@ -659,7 +658,7 @@ void savemeta(char *out_fn, int saveoption, int gziplevel)
 				sbd.device.length << GFS2_BASIC_BLOCK_SHIFT);
 			exit(-1);
 		}
-		osi_list_init(&sbd.rglist);
+		sbd.rgtree.osi_node = NULL;
 		if (!sbd.gfs1)
 			sbd.sd_sb.sb_bsize = GFS2_DEFAULT_BSIZE;
 		if (compute_constants(&sbd)) {
@@ -700,6 +699,7 @@ void savemeta(char *out_fn, int saveoption, int gziplevel)
 	if (!slow) {
 		int sane;
 		uint64_t fssize;
+		struct osi_node *n;
 
 		printf("Reading resource groups...");
 		fflush(stdout);
@@ -707,10 +707,10 @@ void savemeta(char *out_fn, int saveoption, int gziplevel)
 			slow = gfs1_ri_update(&sbd, 0, &rgcount, 0);
 		else
 			slow = ri_update(&sbd, 0, &rgcount, &sane);
-		last_rgd = osi_list_entry(sbd.rglist.prev,
-					  struct rgrp_list, list);
-		prev_rgd = osi_list_entry(last_rgd->list.prev,
-					  struct rgrp_list, list);
+		n = osi_last(&sbd.rgtree);
+		last_rgd = (struct rgrp_tree *)n;
+		n = osi_prev(n);
+		prev_rgd = (struct rgrp_tree *)n;
 		fssize = last_rgd->ri.ri_addr +
 			(last_rgd->ri.ri_addr - prev_rgd->ri.ri_addr);
 		last_fs_block = fssize;
@@ -721,6 +721,8 @@ void savemeta(char *out_fn, int saveoption, int gziplevel)
 	}
 	get_journal_inode_blocks();
 	if (!slow) {
+		struct osi_node *n, *next = NULL;
+
 		/* Save off the superblock */
 		save_block(sbd.device_fd, &mfd, 0x10 * (4096 / sbd.bsize));
 		/* If this is gfs1, save off the rindex because it's not
@@ -742,12 +744,12 @@ void savemeta(char *out_fn, int saveoption, int gziplevel)
 			}
 		}
 		/* Walk through the resource groups saving everything within */
-		for (tmp = sbd.rglist.next; tmp != &sbd.rglist;
-		     tmp = tmp->next){
-			struct rgrp_list *rgd;
+		for (n = osi_first(&sbd.rgtree); n; n = next) {
 			int first;
+			struct rgrp_tree *rgd;
 
-			rgd = osi_list_entry(tmp, struct rgrp_list, list);
+			next = osi_next(n);
+			rgd = (struct rgrp_tree *)n;
 			slow = gfs2_rgrp_read(&sbd, rgd);
 			if (slow)
 				continue;
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 75b363b..06121bc 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -108,7 +108,7 @@ static void gfs2_inodetree_free(void)
 static void empty_super_block(struct gfs2_sbd *sdp)
 {
 	log_info( _("Freeing buffers.\n"));
-	gfs2_rgrp_free(&sdp->rglist);
+	gfs2_rgrp_free(&sdp->rgtree);
 
 	if (bl)
 		gfs2_bmap_destroy(sdp, bl);
@@ -129,10 +129,9 @@ static void empty_super_block(struct gfs2_sbd *sdp)
  */
 static int set_block_ranges(struct gfs2_sbd *sdp)
 {
-
-	struct rgrp_list *rgd;
+	struct osi_node *n, *next = NULL;
+	struct rgrp_tree *rgd;
 	struct gfs2_rindex *ri;
-	osi_list_t *tmp;
 	char buf[sdp->sd_sb.sb_bsize];
 	uint64_t rmax = 0;
 	uint64_t rmin = 0;
@@ -140,9 +139,9 @@ static int set_block_ranges(struct gfs2_sbd *sdp)
 
 	log_info( _("Setting block ranges...\n"));
 
-	for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next)
-	{
-		rgd = osi_list_entry(tmp, struct rgrp_list, list);
+	for (n = osi_first(&sdp->rgtree); n; n = next) {
+		next = osi_next(n);
+		rgd = (struct rgrp_tree *)n;
 		ri = &rgd->ri;
 		if (ri->ri_data0 + ri->ri_data &&
 		    ri->ri_data0 + ri->ri_data - 1 > rmax)
@@ -188,7 +187,7 @@ static int set_block_ranges(struct gfs2_sbd *sdp)
 /**
  * check_rgrp_integrity - verify a rgrp free block count against the bitmap
  */
-static void check_rgrp_integrity(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
+static void check_rgrp_integrity(struct gfs2_sbd *sdp, struct rgrp_tree *rgd,
 				 int *fixit, int *this_rg_fixed,
 				 int *this_rg_bad)
 {
@@ -317,17 +316,18 @@ static void check_rgrp_integrity(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
  */
 static int check_rgrps_integrity(struct gfs2_sbd *sdp)
 {
+	struct osi_node *n, *next = NULL;
 	int rgs_good = 0, rgs_bad = 0, rgs_fixed = 0;
 	int was_bad = 0, was_fixed = 0, error = 0;
-	osi_list_t *tmp;
-	struct rgrp_list *rgd;
+	struct rgrp_tree *rgd;
 	int reclaim_unlinked = 0;
 
 	log_info( _("Checking the integrity of all resource groups.\n"));
-	for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
+	for (n = osi_first(&sdp->rgtree); n; n = next) {
+		next = osi_next(n);
+		rgd = (struct rgrp_tree *)n;
 		if (fsck_abort)
 			return 0;
-		rgd = osi_list_entry(tmp, struct rgrp_list, list);
 		check_rgrp_integrity(sdp, rgd, &reclaim_unlinked,
 				     &was_fixed, &was_bad);
 		if (was_fixed)
@@ -1155,7 +1155,7 @@ static int fill_super_block(struct gfs2_sbd *sdp)
 	 ***************** First, initialize all lists **********************
 	 ********************************************************************/
 	log_info( _("Initializing lists...\n"));
-	osi_list_init(&sdp->rglist);
+	sdp->rgtree.osi_node = NULL;
 
 	/********************************************************************
 	 ************  next, read in on-disk SB and set constants  **********
diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index 16afb11..d109283 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -81,8 +81,8 @@ static void add_dotdot(struct gfs2_inode *ip)
 
 static uint64_t find_free_blk(struct gfs2_sbd *sdp)
 {
-	osi_list_t *tmp, *head;
-	struct rgrp_list *rl = NULL;
+	struct osi_node *n, *next = NULL;
+	struct rgrp_tree *rl = NULL;
 	struct gfs2_rindex *ri;
 	struct gfs2_rgrp *rg;
 	unsigned int block, bn = 0, x = 0, y = 0;
@@ -90,14 +90,14 @@ static uint64_t find_free_blk(struct gfs2_sbd *sdp)
 	struct gfs2_buffer_head *bh;
 
 	memset(&rg, 0, sizeof(rg));
-	for (head = &sdp->rglist, tmp = head->next; tmp != head;
-	     tmp = tmp->next) {
-		rl = osi_list_entry(tmp, struct rgrp_list, list);
+	for (n = osi_first(&sdp->rgtree); n; n = next) {
+		next = osi_next(n);
+		rl = (struct rgrp_tree *)n;
 		if (rl->rg.rg_free)
 			break;
 	}
 
-	if (tmp == head)
+	if (n == NULL)
 		return 0;
 
 	ri = &rl->ri;
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index 75ccc11..7b768b0 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -147,8 +147,8 @@ static void interrupt(int sig)
 
 static void check_statfs(struct gfs2_sbd *sdp)
 {
-	osi_list_t *tmp;
-	struct rgrp_list *rgd;
+	struct osi_node *n, *next = NULL;
+	struct rgrp_tree *rgd;
 	struct gfs2_rindex *ri;
 	struct gfs2_statfs_change sc;
 	char buf[sizeof(struct gfs2_statfs_change)];
@@ -169,8 +169,9 @@ static void check_statfs(struct gfs2_sbd *sdp)
 	sdp->blks_alloced = 0;
 	sdp->dinodes_alloced = 0;
 
-	for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
-		rgd = osi_list_entry(tmp, struct rgrp_list, list);
+	for (n = osi_first(&sdp->rgtree); n; n = next) {
+		next = osi_next(n);
+		rgd = (struct rgrp_tree *)n;
 		ri = &rgd->ri;
 		sdp->blks_total += ri->ri_data;
 		sdp->blks_alloced += (ri->ri_data - rgd->rg.rg_free);
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 6ddc936..c313c3b 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -29,7 +29,7 @@ int check_n_fix_bitmap(struct gfs2_sbd *sdp, uint64_t blk,
 		       enum gfs2_mark_block new_blockmap_state)
 {
 	int old_bitmap_state, new_bitmap_state;
-	struct rgrp_list *rgd;
+	struct rgrp_tree *rgd;
 
 	rgd = gfs2_blk2rgrpd(sdp, blk);
 
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index 60e7cce..de5de2b 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -1531,10 +1531,10 @@ static int check_system_inodes(struct gfs2_sbd *sdp)
  */
 int pass1(struct gfs2_sbd *sdp)
 {
+	struct osi_node *n, *next = NULL;
 	struct gfs2_buffer_head *bh;
-	osi_list_t *tmp;
 	uint64_t block;
-	struct rgrp_list *rgd;
+	struct rgrp_tree *rgd;
 	int first;
 	uint64_t i;
 	uint64_t blk_count;
@@ -1561,11 +1561,11 @@ int pass1(struct gfs2_sbd *sdp)
 	 * uses the rg bitmaps, so maybe that's the best way to start
 	 * things - we can change the method later if necessary.
 	 */
-	for (tmp = sdp->rglist.next; tmp != &sdp->rglist;
-	     tmp = tmp->next, rg_count++) {
-		log_debug( _("Checking metadata in Resource Group #%" PRIu64 "\n"),
-				 rg_count);
-		rgd = osi_list_entry(tmp, struct rgrp_list, list);
+	for (n = osi_first(&sdp->rgtree); n; n = next, rg_count++) {
+		next = osi_next(n);
+		log_debug( _("Checking metadata in Resource Group #%llu\n"),
+				 (unsigned long long)rg_count);
+		rgd = (struct rgrp_tree *)n;
 		for (i = 0; i < rgd->ri.ri_length; i++) {
 			log_debug( _("rgrp block %lld (0x%llx) "
 				     "is now marked as 'rgrp data'\n"),
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index 3cf420b..ea033a0 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -191,7 +191,7 @@ static int check_block_status(struct gfs2_sbd *sdp, char *buffer,
 	return 0;
 }
 
-static void update_rgrp(struct gfs2_sbd *sdp, struct rgrp_list *rgp,
+static void update_rgrp(struct gfs2_sbd *sdp, struct rgrp_tree *rgp,
 			uint32_t *count)
 {
 	uint32_t i;
@@ -276,18 +276,19 @@ static void update_rgrp(struct gfs2_sbd *sdp, struct rgrp_list *rgp,
  */
 int pass5(struct gfs2_sbd *sdp)
 {
-	osi_list_t *tmp;
-	struct rgrp_list *rgp = NULL;
+	struct osi_node *n, *next = NULL;
+	struct rgrp_tree *rgp = NULL;
 	uint32_t count[5];
 	uint64_t rg_count = 0;
 
 	/* Reconcile RG bitmaps with fsck bitmap */
-	for(tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next){
+	for (n = osi_first(&sdp->rgtree); n; n = next) {
+		next = osi_next(n);
 		if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
 			return FSCK_OK;
 		log_info( _("Verifying Resource Group #%" PRIu64 "\n"), rg_count);
 		memset(count, 0, sizeof(count));
-		rgp = osi_list_entry(tmp, struct rgrp_list, list);
+		rgp = (struct rgrp_tree *)n;
 
 		rg_count++;
 		/* Compare the bitmaps and report the differences */
diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c
index 28ed451..c3015b7 100644
--- a/gfs2/fsck/rgrepair.c
+++ b/gfs2/fsck/rgrepair.c
@@ -228,25 +228,25 @@ static uint64_t count_usedspace(struct gfs2_sbd *sdp, int first,
  * This function finds the distance to the next rgrp for these cases.
  */
 static uint64_t find_next_rgrp_dist(struct gfs2_sbd *sdp, uint64_t blk,
-				    struct rgrp_list *prevrgd)
+				    struct rgrp_tree *prevrgd)
 {
+	struct osi_node *n, *next = NULL;
 	uint64_t rgrp_dist = 0, used_blocks, block, next_block, twogigs;
-	osi_list_t *tmp;
-	struct rgrp_list *rgd = NULL, *next_rgd;
+	struct rgrp_tree *rgd = NULL, *next_rgd;
 	struct gfs2_buffer_head *bh;
 	struct gfs2_meta_header mh;
 	int first, length, b, found, mega_in_blocks;
 	uint32_t free_blocks;
 
-	for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
-		rgd = osi_list_entry(tmp, struct rgrp_list, list);
+	for (n = osi_first(&sdp->rgtree); n; n = next) {
+		next = osi_next(n);
+		rgd = (struct rgrp_tree *)n;
 		if (rgd->ri.ri_addr == blk)
 			break;
 	}
-	if (rgd && tmp && tmp != &sdp->rglist && tmp->next &&
-	    rgd->ri.ri_addr == blk) {
-		tmp = tmp->next;
-		next_rgd = osi_list_entry(tmp, struct rgrp_list, list);
+	if (rgd && n && osi_next(n) && rgd->ri.ri_addr == blk) {
+		n = osi_next(n);
+		next_rgd = (struct rgrp_tree *)n;
 		rgrp_dist = next_rgd->ri.ri_addr - rgd->ri.ri_addr;
 		return rgrp_dist;
 	}
@@ -343,7 +343,7 @@ static uint64_t find_next_rgrp_dist(struct gfs2_sbd *sdp, uint64_t blk,
  * boundaries, and also corrupt.  So we have to go out searching for one.
  */
 static uint64_t hunt_and_peck(struct gfs2_sbd *sdp, uint64_t blk,
-			      struct rgrp_list *prevrgd, uint64_t last_bump)
+			      struct rgrp_tree *prevrgd, uint64_t last_bump)
 {
 	uint64_t rgrp_dist = 0, block, twogigs, last_block, last_meg;
 	struct gfs2_buffer_head *bh;
@@ -428,20 +428,20 @@ static uint64_t hunt_and_peck(struct gfs2_sbd *sdp, uint64_t blk,
  * from gfs1 to gfs2 after a gfs_grow operation.  In that case, the rgrps
  * will not be on predictable boundaries.
  */
-static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list,
-			       int *num_rgs, int gfs_grow)
+static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, int *num_rgs,
+			       int gfs_grow)
 {
+	struct osi_node *n, *next = NULL;
 	struct gfs2_buffer_head *bh;
 	uint64_t shortest_dist_btwn_rgs;
 	uint64_t blk;
 	uint64_t fwd_block, block_bump;
 	uint64_t first_rg_dist, initial_first_rg_dist;
-	struct rgrp_list *calc_rgd, *prev_rgd;
+	struct rgrp_tree *calc_rgd, *prev_rgd;
 	int number_of_rgs, rgi;
 	int rg_was_fnd = FALSE, corrupt_rgs = 0, bitmap_was_fnd;
-	osi_list_t *tmp;
 
-	osi_list_init(ret_list);
+	sdp->rgcalc.osi_node = NULL;
 	initial_first_rg_dist = first_rg_dist = sdp->sb_addr + 1;
 	shortest_dist_btwn_rgs = find_shortest_rgdist(sdp,
 						      &initial_first_rg_dist,
@@ -460,15 +460,12 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list,
 		rg_was_fnd = (!gfs2_check_meta(bh, GFS2_METATYPE_RG));
 		brelse(bh);
 		/* Allocate a new RG and index. */
-		calc_rgd = malloc(sizeof(struct rgrp_list));
+		calc_rgd = rgrp_insert(&sdp->rgcalc, blk);
 		if (!calc_rgd) {
 			log_crit( _("Can't allocate memory for rgrp repair.\n"));
 			return -1;
 		}
-		memset(calc_rgd, 0, sizeof(struct rgrp_list));
-		osi_list_add_prev(&calc_rgd->list, ret_list);
 		calc_rgd->ri.ri_length = 1;
-		calc_rgd->ri.ri_addr = blk;
 		if (!rg_was_fnd) { /* if not an RG */
 			/* ------------------------------------------------- */
 			/* This SHOULD be an RG but isn't.                   */
@@ -584,9 +581,9 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list,
         /* Now dump out the information (if verbose mode) */      
         /* ---------------------------------------------- */
         log_debug( _("rindex rebuilt as follows:\n"));
-        for (tmp = ret_list->next, rgi = 0; tmp != ret_list;
-	     tmp = tmp->next, rgi++) {
-                calc_rgd = osi_list_entry(tmp, struct rgrp_list, list);
+	for (n = osi_first(&sdp->rgcalc), rgi = 0; n; n = next, rgi++) {
+		next = osi_next(n);
+		calc_rgd = (struct rgrp_tree *)n;
                 log_debug("%d: 0x%llx / %x / 0x%llx"
 			  " / 0x%x / 0x%x\n", rgi + 1,
 			  (unsigned long long)calc_rgd->ri.ri_addr,
@@ -611,8 +608,7 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list,
  * Sets:    sdp->rglist to a linked list of fsck_rgrp structs representing
  *          what we think the rindex should really look like.
  */
-static int gfs2_rindex_calculate(struct gfs2_sbd *sdp, osi_list_t *ret_list,
-			   int *num_rgs)
+static int gfs2_rindex_calculate(struct gfs2_sbd *sdp, int *num_rgs)
 {
 	uint64_t num_rgrps = 0;
 
@@ -625,7 +621,7 @@ static int gfs2_rindex_calculate(struct gfs2_sbd *sdp, osi_list_t *ret_list,
 	/* ----------------------------------------------------------------- */
 	*num_rgs = sdp->md.riinode->i_di.di_size / sizeof(struct gfs2_rindex);
 
-	osi_list_init(ret_list);
+	sdp->rgcalc.osi_node = NULL;
 	if (device_geometry(sdp)) {
 		fprintf(stderr, _("Geometry error\n"));
 		exit(-1);
@@ -648,16 +644,11 @@ static int gfs2_rindex_calculate(struct gfs2_sbd *sdp, osi_list_t *ret_list,
 		}
 	}
 	/* Compute the default resource group layout as mkfs would have done */
-	compute_rgrp_layout(sdp, TRUE);
+	compute_rgrp_layout(sdp, &sdp->rgcalc, TRUE);
 	build_rgrps(sdp, FALSE); /* FALSE = calc but don't write to disk. */
 	log_debug( _("fs_total_size = 0x%" PRIX64 " blocks.\n"),
 		  sdp->device.length);
 	log_warn( _("L3: number of rgs in the index = %d.\n"), *num_rgs);
-	/* Move the rg list to the return list */
-	ret_list->next = sdp->rglist.next;
-	ret_list->prev = sdp->rglist.prev;
-	ret_list->next->prev = ret_list;
-	ret_list->prev->next = ret_list;
 	return 0;
 }
 
@@ -665,8 +656,8 @@ static int gfs2_rindex_calculate(struct gfs2_sbd *sdp, osi_list_t *ret_list,
  * rewrite_rg_block - rewrite ("fix") a buffer with rg or bitmap data
  * returns: 0 if the rg was repaired, otherwise 1
  */
-static int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_list *rg,
-		     uint64_t errblock)
+static int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_tree *rg,
+			    uint64_t errblock)
 {
 	int x = errblock - rg->ri.ri_addr;
 	const char *typedesc = x ? "GFS2_METATYPE_RB" : "GFS2_METATYPE_RG";
@@ -712,18 +703,16 @@ static int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_list *rg,
  *                        values as our expected values and assume the
  *                        damage is only to the rgrps themselves.
  */
-static int expect_rindex_sanity(struct gfs2_sbd *sdp, osi_list_t *ret_list,
-				int *num_rgs)
+static int expect_rindex_sanity(struct gfs2_sbd *sdp, int *num_rgs)
 {
-	osi_list_t *tmp;
-	struct rgrp_list *exp, *rgd; /* expected, actual */
+	struct osi_node *n, *next = NULL;
+	struct rgrp_tree *rgd, *exp;
 
 	*num_rgs = sdp->md.riinode->i_di.di_size / sizeof(struct gfs2_rindex) ;
-	osi_list_init(ret_list);
-	for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
-		rgd = osi_list_entry(tmp, struct rgrp_list, list);
-
-		exp = calloc(1, sizeof(struct rgrp_list));
+	for (n = osi_first(&sdp->rgtree); n; n = next) {
+		next = osi_next(n);
+		rgd = (struct rgrp_tree *)n;
+		exp = rgrp_insert(&sdp->rgcalc, rgd->ri.ri_addr);
 		if (exp == NULL) {
 			fprintf(stderr, "Out of memory in %s\n", __FUNCTION__);
 			exit(-1);
@@ -735,45 +724,12 @@ static int expect_rindex_sanity(struct gfs2_sbd *sdp, osi_list_t *ret_list,
 		exp->bits = NULL;
 		exp->bh = NULL;
 		gfs2_compute_bitstructs(sdp, exp);
-		osi_list_add_prev(&exp->list, ret_list);
 	}
 	sdp->rgrps = *num_rgs;
 	return 0;
 }
 
 /*
- * sort_rgrp_list - sort the rgrp list
- *
- * A bit crude, perhaps, but we're talking about thousands, not millions of
- * entries to sort, and the list will be almost sorted anyway, so there
- * should be very few swaps.
- */
-static void sort_rgrp_list(osi_list_t *head)
-{
-	struct rgrp_list *thisr, *nextr;
-	osi_list_t *tmp, *x, *next;
-	int swaps;
-
-	while (1) {
-		swaps = 0;
-		osi_list_foreach_safe(tmp, head, x) {
-			next = tmp->next;
-			if (next == head) /* at the end */
-				break;
-			thisr = osi_list_entry(tmp, struct rgrp_list, list);
-			nextr = osi_list_entry(next, struct rgrp_list, list);
-			if (thisr->ri.ri_addr > nextr->ri.ri_addr) {
-				osi_list_del(next);
-				osi_list_add_prev(next, tmp);
-				swaps++;
-			}
-		}
-		if (!swaps)
-			break;
-	}
-}
-
-/*
  * rg_repair - try to repair a damaged rg index (rindex)
  * trust_lvl - This is how much we trust the rindex file.
  *             blind_faith means we take the rindex at face value.
@@ -786,10 +742,9 @@ static void sort_rgrp_list(osi_list_t *head)
  */
 int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count, int *sane)
 {
+	struct osi_node *n, *next = NULL, *e, *enext;
 	int error, discrepancies, percent;
-	osi_list_t expected_rglist;
 	int calc_rg_count = 0, rgcount_from_index, rg;
-	osi_list_t *exp, *act; /* expected, actual */
 	struct gfs2_rindex buf;
 
 	if (trust_lvl == blind_faith)
@@ -803,57 +758,53 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count, int *sane)
 				  "expectations.\n"));
 			return -1;
 		}
-		error = expect_rindex_sanity(sdp, &expected_rglist,
-					     &calc_rg_count);
+		error = expect_rindex_sanity(sdp, &calc_rg_count);
 		if (error) {
-			gfs2_rgrp_free(&expected_rglist);
+			gfs2_rgrp_free(&sdp->rgcalc);
 			return error;
 		}
 	} else if (trust_lvl == open_minded) { /* If we can't trust RG index */
 		/* Free previous incarnations in memory, if any. */
-		gfs2_rgrp_free(&sdp->rglist);
+		gfs2_rgrp_free(&sdp->rgtree);
 
 		/* Calculate our own RG index for comparison */
-		error = gfs2_rindex_calculate(sdp, &expected_rglist,
-					      &calc_rg_count);
+		error = gfs2_rindex_calculate(sdp, &calc_rg_count);
 		if (error) { /* If calculated RGs don't match the fs */
-			gfs2_rgrp_free(&expected_rglist);
+			gfs2_rgrp_free(&sdp->rgcalc);
 			return -1;
 		}
 	}
 	else if (trust_lvl == distrust) { /* If we can't trust RG index */
 		/* Free previous incarnations in memory, if any. */
-		gfs2_rgrp_free(&sdp->rglist);
+		gfs2_rgrp_free(&sdp->rgtree);
 
-		error = gfs2_rindex_rebuild(sdp, &expected_rglist,
-					    &calc_rg_count, 0);
+		error = gfs2_rindex_rebuild(sdp, &calc_rg_count, 0);
 		if (error) {
 			log_crit( _("Error rebuilding rgrp list.\n"));
-			gfs2_rgrp_free(&expected_rglist);
+			gfs2_rgrp_free(&sdp->rgcalc);
 			return -1;
 		}
 		sdp->rgrps = calc_rg_count;
 	}
 	else if (trust_lvl == indignation) { /* If we can't trust anything */
 		/* Free previous incarnations in memory, if any. */
-		gfs2_rgrp_free(&sdp->rglist);
+		gfs2_rgrp_free(&sdp->rgtree);
 
-		error = gfs2_rindex_rebuild(sdp, &expected_rglist,
-					    &calc_rg_count, 1);
+		error = gfs2_rindex_rebuild(sdp, &calc_rg_count, 1);
 		if (error) {
 			log_crit( _("Error rebuilding rgrp list.\n"));
-			gfs2_rgrp_free(&expected_rglist);
+			gfs2_rgrp_free(&sdp->rgcalc);
 			return -1;
 		}
 		sdp->rgrps = calc_rg_count;
 	}
 	/* Read in the rindex */
-	osi_list_init(&sdp->rglist); /* Just to be safe */
+	sdp->rgtree.osi_node = NULL; /* Just to be safe */
 	rindex_read(sdp, 0, &rgcount_from_index, sane);
 	if (sdp->md.riinode->i_di.di_size % sizeof(struct gfs2_rindex)) {
 		log_warn( _("WARNING: rindex file is corrupt.\n"));
-		gfs2_rgrp_free(&expected_rglist);
-		gfs2_rgrp_free(&sdp->rglist);
+		gfs2_rgrp_free(&sdp->rgcalc);
+		gfs2_rgrp_free(&sdp->rgtree);
 		return -1;
 	}
 	log_warn( _("L%d: number of rgs expected     = %lld.\n"), trust_lvl + 1,
@@ -863,20 +814,11 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count, int *sane)
 			    "extended, (2) an odd\n"), trust_lvl + 1);
 		log_warn( _("L%d: rgrp size was used, or (3) we have a corrupt "
 			    "rg index.\n"), trust_lvl + 1);
-		gfs2_rgrp_free(&expected_rglist);
-		gfs2_rgrp_free(&sdp->rglist);
+		gfs2_rgrp_free(&sdp->rgcalc);
+		gfs2_rgrp_free(&sdp->rgtree);
 		return -1;
 	}
 	/* ------------------------------------------------------------- */
-	/* Sort the rindex list.  Older versions of gfs_grow got the     */
-	/* rindex out of sorted order.  But rebuilding the rindex from   */
-	/* scratch will rebuild it in sorted order.                      */
-	/* The gfs2_grow program should, in theory, drop new rgrps into  */
-	/* the rindex in sorted order, so this should only matter for    */
-	/* gfs1 converted file systems.                                  */
-	/* ------------------------------------------------------------- */
-	sort_rgrp_list(&sdp->rglist);
-	/* ------------------------------------------------------------- */
 	/* Now compare the rindex to what we think it should be.         */
 	/* See how far off our expected values are.  If too much, abort. */
 	/* The theory is: if we calculated the index to have 32 RGs and  */
@@ -884,22 +826,24 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count, int *sane)
 	/* abandon this method of recovery and try a better one.         */
 	/* ------------------------------------------------------------- */
 	discrepancies = 0;
-	for (rg = 0, act = sdp->rglist.next, exp = expected_rglist.next;
-	     act != &sdp->rglist && exp != &expected_rglist && !fsck_abort;
-	     rg++) {
-		struct rgrp_list *expected, *actual;
+	for (rg = 0, n = osi_first(&sdp->rgtree), e = osi_first(&sdp->rgcalc);
+	     n && e && !fsck_abort; rg++) {
+		struct rgrp_tree *expected, *actual;
+
+		next = osi_next(n);
+		enext = osi_next(e);
 
-		expected = osi_list_entry(exp, struct rgrp_list, list);
-		actual = osi_list_entry(act, struct rgrp_list, list);
+		expected = (struct rgrp_tree *)e;
+		actual = (struct rgrp_tree *)n;
 		if (actual->ri.ri_addr < expected->ri.ri_addr) {
-			act = act->next;
+			n = next;
 			discrepancies++;
 			log_info(_("%d addr: 0x%llx < 0x%llx * mismatch\n"),
 				 rg + 1, actual->ri.ri_addr,
 				 expected->ri.ri_addr);
 			continue;
 		} else if (expected->ri.ri_addr < actual->ri.ri_addr) {
-			exp = exp->next;
+			e = enext;
 			discrepancies++;
 			log_info(_("%d addr: 0x%llx > 0x%llx * mismatch\n"),
 				 rg + 1, actual->ri.ri_addr,
@@ -915,8 +859,8 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count, int *sane)
 				 rg + 1, actual->ri.ri_addr,
 				 expected->ri.ri_addr);
 		}
-		act = act->next;
-		exp = exp->next;
+		n = next;
+		e = enext;
 	}
 	if (rg) {
 		/* Check to see if more than 2% of the rgrps are wrong.  */
@@ -927,8 +871,8 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count, int *sane)
 			log_warn( _("%d out of %d rgrps (%d percent) did not "
 				    "match what was expected.\n"),
 				  discrepancies, rg, percent);
-			gfs2_rgrp_free(&expected_rglist);
-			gfs2_rgrp_free(&sdp->rglist);
+			gfs2_rgrp_free(&sdp->rgcalc);
+			gfs2_rgrp_free(&sdp->rgtree);
 			return -1;
 		}
 	}
@@ -937,28 +881,29 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count, int *sane)
 	/* Our rindex should be pretty predictable unless we've grown    */
 	/* so look for index problems first before looking at the rgs.   */
 	/* ------------------------------------------------------------- */
-	for (rg = 0, act = sdp->rglist.next, exp = expected_rglist.next;
-	     exp != &expected_rglist && !fsck_abort; rg++) {
-		struct rgrp_list *expected, *actual;
+	for (rg = 0, n = osi_first(&sdp->rgtree), e = osi_first(&sdp->rgcalc);
+	     e && !fsck_abort; rg++) {
+		struct rgrp_tree *expected, *actual;
 
-		expected = osi_list_entry(exp, struct rgrp_list, list);
+		if (n)
+			next = osi_next(n);
+		enext = osi_next(e);
+		expected = (struct rgrp_tree *)e;
 
 		/* If we ran out of actual rindex entries due to rindex
 		   damage, fill in a new one with the expected values. */
-		if (act == &sdp->rglist) { /* end of actual rindex */
+		if (!n) { /* end of actual rindex */
 			log_err( _("Entry missing from rindex: 0x%llx\n"),
 				 (unsigned long long)expected->ri.ri_addr);
-			actual = (struct rgrp_list *)
-				malloc(sizeof(struct rgrp_list));
+			actual = rgrp_insert(&sdp->rgtree,
+					     expected->ri.ri_addr);
 			if (!actual) {
 				log_err(_("Out of memory!\n"));
 				break;
 			}
-			memset(actual, 0, sizeof(struct rgrp_list));
-			osi_list_add_prev(&actual->list, &sdp->rglist);
 			rindex_modified = 1;
 		} else {
-			actual = osi_list_entry(act, struct rgrp_list, list);
+			actual = (struct rgrp_tree *)n;
 			ri_compare(rg, actual->ri, expected->ri, ri_addr,
 				   "llx");
 			ri_compare(rg, actual->ri, expected->ri, ri_length,
@@ -997,26 +942,27 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count, int *sane)
 			gfs2_compute_bitstructs(sdp, actual);
 			rindex_modified = FALSE;
 		}
-		exp = exp->next;
-		if (act != &sdp->rglist)
-			act = act->next;
+		e = enext;
+		if (n)
+			n = next;
 	}
 	/* ------------------------------------------------------------- */
 	/* Read the real RGs and check their integrity.                  */
 	/* Now we can somewhat trust the rindex and the RG addresses,    */
 	/* so let's read them in, check them and optionally fix them.    */
 	/* ------------------------------------------------------------- */
-	for (rg = 0, act = sdp->rglist.next; act != &sdp->rglist &&
-		     !fsck_abort; act = act->next, rg++) {
-		struct rgrp_list *rgd;
+	for (rg = 0, n = osi_first(&sdp->rgtree); n && !fsck_abort;
+	     n = next, rg++) {
+		struct rgrp_tree *rgd;
 		uint64_t prev_err = 0, errblock;
 		int i;
 
+		next = osi_next(n);
 		/* Now we try repeatedly to read in the rg.  For every block */
 		/* we encounter that has errors, repair it and try again.    */
 		i = 0;
 		do {
-			rgd = osi_list_entry(act, struct rgrp_list, list);
+			rgd = (struct rgrp_tree *)n;
 			errblock = gfs2_rgrp_read(sdp, rgd);
 			if (errblock) {
 				if (errblock == prev_err)
@@ -1031,7 +977,7 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count, int *sane)
 		} while (i < rgd->ri.ri_length);
 	}
 	*rg_count = rg;
-	gfs2_rgrp_free(&expected_rglist);
-	gfs2_rgrp_free(&sdp->rglist);
+	gfs2_rgrp_free(&sdp->rgcalc);
+	gfs2_rgrp_free(&sdp->rgtree);
 	return 0;
 }
diff --git a/gfs2/libgfs2/fs_bits.c b/gfs2/libgfs2/fs_bits.c
index b39effe..f45aabe 100644
--- a/gfs2/libgfs2/fs_bits.c
+++ b/gfs2/libgfs2/fs_bits.c
@@ -175,7 +175,7 @@ int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int state)
 	int           buf;
 	uint32_t        rgrp_block;
 	struct gfs2_bitmap *bits = NULL;
-	struct rgrp_list *rgd;
+	struct rgrp_tree *rgd;
 	unsigned char *byte, cur_state;
 	unsigned int bit;
 
@@ -223,7 +223,7 @@ int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int state)
  * Returns: state on success, -1 on error
  */
 int gfs2_get_bitmap(struct gfs2_sbd *sdp, uint64_t blkno,
-		    struct rgrp_list *rgd)
+		    struct rgrp_tree *rgd)
 {
 	int           i, val;
 	uint32_t        rgrp_block;
diff --git a/gfs2/libgfs2/fs_geometry.c b/gfs2/libgfs2/fs_geometry.c
index 7c07891..067c5f3 100644
--- a/gfs2/libgfs2/fs_geometry.c
+++ b/gfs2/libgfs2/fs_geometry.c
@@ -72,13 +72,14 @@ uint64_t how_many_rgrps(struct gfs2_sbd *sdp, struct device *dev, int rgsize_spe
  * Returns: a list of rgrp_list_t structures
  */
 
-void compute_rgrp_layout(struct gfs2_sbd *sdp, int rgsize_specified)
+void compute_rgrp_layout(struct gfs2_sbd *sdp, struct osi_root *rgtree,
+			 int rgsize_specified)
 {
 	struct device *dev;
-	struct rgrp_list *rl, *rlast = NULL, *rlast2 = NULL;
-	osi_list_t *tmp, *head = &sdp->rglist;
-	unsigned int rgrp = 0, nrgrp;
-	uint64_t rglength;
+	struct rgrp_tree *rl, *rlast = NULL, *rlast2 = NULL;
+	struct osi_node *n, *next = NULL;
+	unsigned int rgrp = 0, nrgrp, rglength;
+	uint64_t rgaddr;
 
 	sdp->new_rgrps = 0;
 	dev = &sdp->device;
@@ -89,7 +90,7 @@ void compute_rgrp_layout(struct gfs2_sbd *sdp, int rgsize_specified)
 	/* If this is a new file system, compute the length and number */
 	/* of rgs based on the size of the device.                     */
 	/* If we have existing RGs (i.e. gfs2_grow) find the last one. */
-	if (osi_list_empty(&sdp->rglist)) {
+	if (!rgtree->osi_node) {
 		dev->length -= sdp->sb_addr + 1;
 		nrgrp = how_many_rgrps(sdp, dev, rgsize_specified);
 		rglength = dev->length / nrgrp;
@@ -98,9 +99,10 @@ void compute_rgrp_layout(struct gfs2_sbd *sdp, int rgsize_specified)
 		uint64_t old_length, new_chunk;
 
 		log_info("Existing resource groups:\n");
-		for (rgrp = 0, tmp = head->next; tmp != head;
-		     tmp = tmp->next, rgrp++) {
-			rl = osi_list_entry(tmp, struct rgrp_list, list);
+		for (rgrp = 0, n = osi_first(rgtree); n; n = next, rgrp++) {
+			next = osi_next(n);
+			rl = (struct rgrp_tree *)n;
+
 			log_info("%d: start: %" PRIu64 " (0x%"
 				 PRIx64 "), length = %"PRIu64" (0x%"
 				 PRIx64 ")\n", rgrp + 1, rl->start, rl->start,
@@ -120,36 +122,31 @@ void compute_rgrp_layout(struct gfs2_sbd *sdp, int rgsize_specified)
 	if (rgrp < nrgrp)
 		log_info("\nNew resource groups:\n");
 	for (; rgrp < nrgrp; rgrp++) {
-		rl = calloc(1, sizeof(struct rgrp_list));
-		if (rl == NULL) {
-			fprintf(stderr, "Out of memory in %s\n", __FUNCTION__);
-			exit(-1);
-		}
-
 		if (rgrp) {
-			rl->start = rlast->start + rlast->length;
+			rgaddr = rlast->start + rlast->length;
+			rl = rgrp_insert(rgtree, rgaddr);
 			rl->length = rglength;
 		} else {
-			rl->start = dev->start;
+			rgaddr = dev->start;
+			rl = rgrp_insert(rgtree, rgaddr);
 			rl->length = dev->length -
 				(nrgrp - 1) * (dev->length / nrgrp);
 		}
-
+		rl->start = rgaddr;
 		log_info("%d: start: %" PRIu64 " (0x%"
 			 PRIx64 "), length = %"PRIu64" (0x%"
 			 PRIx64 ")\n", rgrp + 1, rl->start, rl->start,
 			 rl->length, rl->length);
-		osi_list_add_prev(&rl->list, head);
 		rlast = rl;
 	}
 
 	sdp->rgrps = nrgrp;
-
 	if (sdp->debug) {
 		log_info("\n");
 
-		for (tmp = head->next; tmp != head; tmp = tmp->next) {
-			rl = osi_list_entry(tmp, struct rgrp_list, list);
+		for (n = osi_first(rgtree); n; n = next) {
+			next = osi_next(n);
+			rl = (struct rgrp_tree *)n;
 			log_info("rg_o = %llu, rg_l = %llu\n",
 				 (unsigned long long)rl->start,
 				 (unsigned long long)rl->length);
@@ -200,8 +197,8 @@ void rgblocks2bitblocks(unsigned int bsize, uint32_t *rgblocks, uint32_t *bitblo
  */
 void build_rgrps(struct gfs2_sbd *sdp, int do_write)
 {
-	osi_list_t *tmp, *head;
-	struct rgrp_list *rl;
+	struct osi_node *n, *next = NULL;
+	struct rgrp_tree *rl;
 	uint32_t rgblocks, bitblocks;
 	struct gfs2_rindex *ri;
 	struct gfs2_meta_header mh;
@@ -210,11 +207,14 @@ void build_rgrps(struct gfs2_sbd *sdp, int do_write)
 	mh.mh_magic = GFS2_MAGIC;
 	mh.mh_type = GFS2_METATYPE_RB;
 	mh.mh_format = GFS2_FORMAT_RB;
-
-	for (head = &sdp->rglist, tmp = head->next;
-	     tmp != head;
-	     tmp = tmp->next) {
-		rl = osi_list_entry(tmp, struct rgrp_list, list);
+	if (do_write)
+		n = osi_first(&sdp->rgtree);
+	else
+		n = osi_first(&sdp->rgcalc);
+
+	for (; n; n = next) {
+		next = osi_next(n);
+		rl = (struct rgrp_tree *)n;
 		ri = &rl->ri;
 
 		rgblocks = rl->length;
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index 0163371..5053c90 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -114,8 +114,8 @@ void inode_put(struct gfs2_inode **ip_in)
 
 static uint64_t blk_alloc_i(struct gfs2_sbd *sdp, unsigned int type)
 {
-	osi_list_t *tmp, *head;
-	struct rgrp_list *rl = NULL;
+	struct osi_node *n, *next = NULL;
+	struct rgrp_tree *rl = NULL;
 	struct gfs2_rindex *ri;
 	struct gfs2_rgrp *rg;
 	unsigned int block, bn = 0, x = 0, y = 0;
@@ -123,14 +123,14 @@ static uint64_t blk_alloc_i(struct gfs2_sbd *sdp, unsigned int type)
 	struct gfs2_buffer_head *bh;
 
 	memset(&rg, 0, sizeof(rg));
-	for (head = &sdp->rglist, tmp = head->next; tmp != head;
-	     tmp = tmp->next) {
-		rl = osi_list_entry(tmp, struct rgrp_list, list);
+	for (n = osi_first(&sdp->rgtree); n; n = next) {
+		next = osi_next(n);
+		rl = (struct rgrp_tree *)n;
 		if (rl->rg.rg_free)
 			break;
 	}
 
-	if (tmp == head)
+	if (n == NULL)
 		die("out of space\n");
 
 	ri = &rl->ri;
@@ -1742,7 +1742,7 @@ int gfs2_lookupi(struct gfs2_inode *dip, const char *filename, int len,
  */
 void gfs2_free_block(struct gfs2_sbd *sdp, uint64_t block)
 {
-	struct rgrp_list *rgd;
+	struct rgrp_tree *rgd;
 
 	/* Adjust the free space count for the freed block */
 	rgd = gfs2_blk2rgrpd(sdp, block); /* find the rg for indir block */
@@ -1767,7 +1767,7 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock)
 	struct gfs2_buffer_head *bh, *nbh;
 	int h, head_size;
 	uint64_t *ptr, block;
-	struct rgrp_list *rgd;
+	struct rgrp_tree *rgd;
 	uint32_t height;
 	osi_list_t metalist[GFS2_MAX_META_HEIGHT];
 	osi_list_t *cur_list, *next_list, *tmp;
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index b1574fb..bb47580 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -17,6 +17,7 @@
 
 #include <linux/gfs2_ondisk.h>
 #include "osi_list.h"
+#include "osi_tree.h"
 
 __BEGIN_DECLS
 
@@ -96,8 +97,8 @@ struct gfs2_bitmap
 	uint32_t   bi_len;     /* The number of bytes in this block */
 };
 
-struct rgrp_list {
-	osi_list_t list;
+struct rgrp_tree {
+	struct osi_node node;
 	uint64_t start;	   /* The offset of the beginning of this resource group */
 	uint64_t length;	/* The length of this resource group */
 
@@ -223,7 +224,8 @@ struct gfs2_sbd {
 	uint64_t orig_rgrps;
 	uint64_t rgrps;
 	uint64_t new_rgrps;
-	osi_list_t rglist;
+	struct osi_root rgtree;
+	struct osi_root rgcalc;
 
 	unsigned int orig_journals;
 
@@ -318,7 +320,7 @@ extern unsigned long gfs2_bitfit(const unsigned char *buffer,
 				 unsigned long goal, unsigned char old_state);
 
 /* functions with blk #'s that are rgrp relative */
-extern uint32_t gfs2_blkalloc_internal(struct rgrp_list *rgd, uint32_t goal,
+extern uint32_t gfs2_blkalloc_internal(struct rgrp_tree *rgd, uint32_t goal,
 				       unsigned char old_state,
 				       unsigned char new_state, int do_it);
 extern int gfs2_check_range(struct gfs2_sbd *sdp, uint64_t blkno);
@@ -326,7 +328,7 @@ extern int gfs2_check_range(struct gfs2_sbd *sdp, uint64_t blkno);
 /* functions with blk #'s that are file system relative */
 extern int valid_block(struct gfs2_sbd *sdp, uint64_t blkno);
 extern int gfs2_get_bitmap(struct gfs2_sbd *sdp, uint64_t blkno,
-			   struct rgrp_list *rgd);
+			   struct rgrp_tree *rgd);
 extern int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int state);
 
 /* fs_geometry.c */
@@ -334,7 +336,8 @@ extern void rgblocks2bitblocks(unsigned int bsize, uint32_t *rgblocks,
 			       uint32_t *bitblocks);
 extern uint64_t how_many_rgrps(struct gfs2_sbd *sdp, struct device *dev,
 			       int rgsize_specified);
-extern void compute_rgrp_layout(struct gfs2_sbd *sdp, int rgsize_specified);
+extern void compute_rgrp_layout(struct gfs2_sbd *sdp, struct osi_root *rgtree,
+				int rgsize_specified);
 extern void build_rgrps(struct gfs2_sbd *sdp, int write);
 
 /* fs_ops.c */
@@ -697,12 +700,13 @@ extern int gfs2_find_jhead(struct gfs2_inode *ip, struct gfs2_log_header *head);
 extern int clean_journal(struct gfs2_inode *ip, struct gfs2_log_header *head);
 
 /* rgrp.c */
-extern int gfs2_compute_bitstructs(struct gfs2_sbd *sdp, struct rgrp_list *rgd);
-extern struct rgrp_list *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, uint64_t blk);
-extern uint64_t __gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd);
-extern uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd);
-extern void gfs2_rgrp_relse(struct rgrp_list *rgd);
-extern void gfs2_rgrp_free(osi_list_t *rglist);
+extern int gfs2_compute_bitstructs(struct gfs2_sbd *sdp, struct rgrp_tree *rgd);
+extern struct rgrp_tree *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, uint64_t blk);
+extern uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_tree *rgd);
+extern void gfs2_rgrp_relse(struct rgrp_tree *rgd);
+extern struct rgrp_tree *rgrp_insert(struct osi_root *rgtree,
+				     uint64_t rgblock);
+extern void gfs2_rgrp_free(struct osi_root *rgrp_tree);
 
 /* structures.c */
 extern int build_master(struct gfs2_sbd *sdp);
@@ -719,11 +723,11 @@ extern int build_root(struct gfs2_sbd *sdp);
 extern int do_init_inum(struct gfs2_sbd *sdp);
 extern int do_init_statfs(struct gfs2_sbd *sdp);
 extern int gfs2_check_meta(struct gfs2_buffer_head *bh, int type);
-extern int gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block,
+extern int gfs2_next_rg_meta(struct rgrp_tree *rgd, uint64_t *block,
 			     int first);
-extern int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
+extern int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_tree *rgd,
 				 uint64_t *block, uint32_t type, int first);
-extern int gfs2_next_rg_freemeta(struct rgrp_list *rgd, uint64_t *block,
+extern int gfs2_next_rg_freemeta(struct rgrp_tree *rgd, uint64_t *block,
 				 int first);
 
 /* super.c */
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index cd3667f..0fcea3c 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -13,7 +13,7 @@
  *
  * Returns: 0 on success, -1 on error
  */
-int gfs2_compute_bitstructs(struct gfs2_sbd *sdp, struct rgrp_list *rgd)
+int gfs2_compute_bitstructs(struct gfs2_sbd *sdp, struct rgrp_tree *rgd)
 {
 	struct gfs2_bitmap *bits;
 	uint32_t length = rgd->ri.ri_length;
@@ -93,33 +93,21 @@ int gfs2_compute_bitstructs(struct gfs2_sbd *sdp, struct rgrp_list *rgd)
  *
  * Returns: Ths resource group, or NULL if not found
  */
-struct rgrp_list *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, uint64_t blk)
+struct rgrp_tree *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, uint64_t blk)
 {
-	osi_list_t *tmp;
-	struct rgrp_list *rgd;
-	static struct rgrp_list *prev_rgd = NULL;
+	struct osi_node *node = sdp->rgtree.osi_node;
 	struct gfs2_rindex *ri;
 
-	if (prev_rgd) {
-		ri = &prev_rgd->ri;
-		if (ri->ri_data0 <= blk && blk < ri->ri_data0 + ri->ri_data)
-			return prev_rgd;
-		if (blk >= ri->ri_addr && blk < ri->ri_addr + ri->ri_length)
-			return prev_rgd;
-	}
-
-	for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
-		rgd = osi_list_entry(tmp, struct rgrp_list, list);
+	while (node) {
+		struct rgrp_tree *rgd = (struct rgrp_tree *)node;
 		ri = &rgd->ri;
 
-		if (blk >= ri->ri_addr && blk < ri->ri_addr + ri->ri_length) {
-			prev_rgd = rgd;
-			return rgd;
-		}
-		if (ri->ri_data0 <= blk && blk < ri->ri_data0 + ri->ri_data) {
-			prev_rgd = rgd;
+		if (blk < ri->ri_addr)
+			node = node->osi_left;
+		else if (blk > ri->ri_data0 + ri->ri_data)
+			node = node->osi_right;
+		else
 			return rgd;
-		}
 	}
 	return NULL;
 }
@@ -129,7 +117,7 @@ struct rgrp_list *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, uint64_t blk)
  * @rgd - resource group structure
  * returns: 0 if no error, otherwise the block number that failed
  */
-uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd)
+uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_tree *rgd)
 {
 	int x, length = rgd->ri.ri_length;
 	uint64_t max_rgrp_bitbytes, max_rgrp_len;
@@ -165,7 +153,7 @@ uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd)
 	return 0;
 }
 
-void gfs2_rgrp_relse(struct rgrp_list *rgd)
+void gfs2_rgrp_relse(struct rgrp_tree *rgd)
 {
 	int x, length = rgd->ri.ri_length;
 
@@ -178,14 +166,46 @@ void gfs2_rgrp_relse(struct rgrp_list *rgd)
 	}
 }
 
-void gfs2_rgrp_free(osi_list_t *rglist)
+struct rgrp_tree *rgrp_insert(struct osi_root *rgtree, uint64_t rgblock)
+{
+	struct osi_node **newn = &rgtree->osi_node, *parent = NULL;
+	struct rgrp_tree *data;
+
+	/* Figure out where to put new node */
+	while (*newn) {
+		struct rgrp_tree *cur = (struct rgrp_tree *)*newn;
+
+		parent = *newn;
+		if (rgblock < cur->ri.ri_addr)
+			newn = &((*newn)->osi_left);
+		else if (rgblock > cur->ri.ri_addr)
+			newn = &((*newn)->osi_right);
+		else
+			return cur;
+	}
+
+	data = malloc(sizeof(struct rgrp_tree));
+	if (!data)
+		return NULL;
+	if (!memset(data, 0, sizeof(struct rgrp_tree)))
+		return NULL;
+	/* Add new node and rebalance tree. */
+	data->ri.ri_addr = rgblock;
+	osi_link_node(&data->node, parent, newn);
+	osi_insert_color(&data->node, rgtree);
+
+	return data;
+}
+
+void gfs2_rgrp_free(struct osi_root *rgrp_tree)
 {
-	struct rgrp_list *rgd;
+	struct rgrp_tree *rgd;
 	int rgs_since_sync = 0;
+	struct osi_node *n;
 	struct gfs2_sbd *sdp = NULL;
 
-	while(!osi_list_empty(rglist->next)){
-		rgd = osi_list_entry(rglist->next, struct rgrp_list, list);
+	while ((n = osi_first(rgrp_tree))) {
+		rgd = (struct rgrp_tree *)n;
 		if (rgd->bh && rgd->bh[0]) { /* if a buffer exists        */
 			rgs_since_sync++;
 			if (rgs_since_sync >= RG_SYNC_TOLERANCE) {
@@ -202,7 +222,7 @@ void gfs2_rgrp_free(osi_list_t *rglist)
 			free(rgd->bh);
 			rgd->bh = NULL;
 		}
-		osi_list_del(&rgd->list);
+		osi_erase(&rgd->node, rgrp_tree);
 		free(rgd);
 	}
 }
diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c
index b998f2d..9024353 100644
--- a/gfs2/libgfs2/structures.c
+++ b/gfs2/libgfs2/structures.c
@@ -307,8 +307,8 @@ int build_statfs(struct gfs2_sbd *sdp)
 int build_rindex(struct gfs2_sbd *sdp)
 {
 	struct gfs2_inode *ip;
-	osi_list_t *tmp, *head;
-	struct rgrp_list *rl;
+	struct osi_node *n, *next = NULL;
+	struct rgrp_tree *rl;
 	char buf[sizeof(struct gfs2_rindex)];
 	int count;
 
@@ -317,9 +317,9 @@ int build_rindex(struct gfs2_sbd *sdp)
 	ip->i_di.di_payload_format = GFS2_FORMAT_RI;
 	bmodified(ip->i_bh);
 
-	for (head = &sdp->rglist, tmp = head->next; tmp != head;
-	     tmp = tmp->next) {
-		rl = osi_list_entry(tmp, struct rgrp_list, list);
+	for (n = osi_first(&sdp->rgtree); n; n = next) {
+		next = osi_next(n);
+		rl = (struct rgrp_tree *)n;
 
 		gfs2_rindex_out(&rl->ri, buf);
 
@@ -459,7 +459,7 @@ int gfs2_check_meta(struct gfs2_buffer_head *bh, int type)
  *
  * Returns: 0 on success, -1 when finished
  */
-static int __gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block,
+static int __gfs2_next_rg_meta(struct rgrp_tree *rgd, uint64_t *block,
 			       int first, unsigned char state)
 {
 	struct gfs2_bitmap *bits = NULL;
@@ -467,17 +467,17 @@ static int __gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block,
 	uint32_t blk = (first)? 0: (uint32_t)((*block + 1) - rgd->ri.ri_data0);
 	int i;
 
-	if(!first && (*block < rgd->ri.ri_data0)) {
+	if (!first && (*block < rgd->ri.ri_data0)) {
 		log_err("next_rg_meta:  Start block is outside rgrp bounds.\n");
 		exit(1);
 	}
-	for(i = 0; i < length; i++){
+	for (i = 0; i < length; i++){
 		bits = &rgd->bits[i];
 		if (blk < bits->bi_len * GFS2_NBBY)
 			break;
 		blk -= bits->bi_len * GFS2_NBBY;
 	}
-	for(; i < length; i++){
+	for (; i < length; i++){
 		bits = &rgd->bits[i];
 		blk = gfs2_bitfit((unsigned char *)rgd->bh[i]->b_data +
 				  bits->bi_offset, bits->bi_len, blk, state);
@@ -488,17 +488,17 @@ static int __gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block,
 		}
 		blk = 0;
 	}
-	if(i == length)
+	if (i == length)
 		return -1;
 	return 0;
 }
 
-int gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block, int first)
+int gfs2_next_rg_meta(struct rgrp_tree *rgd, uint64_t *block, int first)
 {
 	return __gfs2_next_rg_meta(rgd, block, first, GFS2_BLKST_DINODE);
 }
 
-int gfs2_next_rg_freemeta(struct rgrp_list *rgd, uint64_t *block, int first)
+int gfs2_next_rg_freemeta(struct rgrp_tree *rgd, uint64_t *block, int first)
 {
 	return __gfs2_next_rg_meta(rgd, block, first, GFS2_BLKST_UNLINKED);
 }
@@ -512,7 +512,7 @@ int gfs2_next_rg_freemeta(struct rgrp_list *rgd, uint64_t *block, int first)
  *
  * Returns: 0 on success, -1 on error or finished
  */
-int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
+int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_tree *rgd,
 			  uint64_t *block, uint32_t type, int first)
 {
 	struct gfs2_buffer_head *bh = NULL;
diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c
index 27f6c2c..2cac1c3 100644
--- a/gfs2/libgfs2/super.c
+++ b/gfs2/libgfs2/super.c
@@ -147,12 +147,12 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *sane)
 		struct gfs_rindex bufgfs1;
 		struct gfs2_rindex bufgfs2;
 	} buf;
-	struct rgrp_list *rgd, *prev_rgd;
+	struct gfs2_rindex ri;
+	struct rgrp_tree *rgd = NULL, *prev_rgd = NULL;
 	uint64_t prev_length = 0;
 
 	*sane = 1;
 	*count1 = 0;
-	prev_rgd = NULL;
 	if (!fd && sdp->md.riinode->i_di.di_size % sizeof(struct gfs2_rindex))
 		*sane = 0; /* rindex file size must be a multiple of 96 */
 	for (rg = 0; ; rg++) {
@@ -168,15 +168,9 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *sane)
 		if (error != sizeof(struct gfs2_rindex))
 			return -1;
 
-		rgd = (struct rgrp_list *)malloc(sizeof(struct rgrp_list));
-		if (!rgd) {
-			log_crit("Cannot allocate memory for rindex.\n");
-			exit(-1);
-		}
-		memset(rgd, 0, sizeof(struct rgrp_list));
-		osi_list_add_prev(&rgd->list, &sdp->rglist);
-
-		gfs2_rindex_in(&rgd->ri, (char *)&buf.bufgfs2);
+		gfs2_rindex_in(&ri, (char *)&buf.bufgfs2);
+		rgd = rgrp_insert(&sdp->rgtree, ri.ri_addr);
+		memcpy(&rgd->ri, &ri, sizeof(struct gfs2_rindex));
 
 		rgd->start = rgd->ri.ri_addr;
 		if (prev_rgd) {
@@ -226,17 +220,18 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *sane)
 static int __ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int *sane,
 		       int quiet)
 {
-	struct rgrp_list *rgd;
+	struct rgrp_tree *rgd;
 	struct gfs2_rindex *ri;
-	osi_list_t *tmp;
 	int count1 = 0, count2 = 0;
 	uint64_t errblock = 0;
 	uint64_t rmax = 0;
+	struct osi_node *n, *next = NULL;
 
 	if (rindex_read(sdp, fd, &count1, sane))
 		goto fail;
-	for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
-		rgd = osi_list_entry(tmp, struct rgrp_list, list);
+	for (n = osi_first(&sdp->rgtree); n; n = next) {
+		next = osi_next(n);
+		rgd = (struct rgrp_tree *)n;
 		errblock = gfs2_rgrp_read(sdp, rgd);
 		if (errblock)
 			return errblock;
@@ -258,7 +253,7 @@ static int __ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int *sane,
 	return 0;
 
  fail:
-	gfs2_rgrp_free(&sdp->rglist);
+	gfs2_rgrp_free(&sdp->rgtree);
 	return -1;
 }
 
diff --git a/gfs2/mkfs/main_grow.c b/gfs2/mkfs/main_grow.c
index a28bdc3..d2d5e05 100644
--- a/gfs2/mkfs/main_grow.c
+++ b/gfs2/mkfs/main_grow.c
@@ -125,12 +125,14 @@ static void decode_arguments(int argc, char *argv[], struct gfs2_sbd *sdp)
  */
 static void figure_out_rgsize(struct gfs2_sbd *sdp, unsigned int *orgsize)
 {
-	osi_list_t *head = &sdp->rglist;
-	struct rgrp_list *r1, *r2;
+	struct osi_node *n = osi_first(&sdp->rgtree), *next = NULL;
+	struct rgrp_tree *r1, *r2;
 
 	sdp->rgsize = GFS2_DEFAULT_RGSIZE;
-	r1 = osi_list_entry(head->next->next, struct rgrp_list, list);
-	r2 = osi_list_entry(head->next->next->next, struct rgrp_list, list);
+	next = osi_next(n);
+	r1 = (struct rgrp_tree *)next;
+	next = osi_next(next);
+	r2 = (struct rgrp_tree *)next;
 
 	*orgsize = r2->ri.ri_addr - r1->ri.ri_addr;
 }
@@ -146,16 +148,13 @@ static void figure_out_rgsize(struct gfs2_sbd *sdp, unsigned int *orgsize)
 
 static uint64_t filesystem_size(struct gfs2_sbd *sdp)
 {
-	osi_list_t *tmp;
-	struct rgrp_list *rgl;
+	struct osi_node *n, *next = NULL;
+	struct rgrp_tree *rgl;
 	uint64_t size = 0, extent;
 
-	tmp = &sdp->rglist;
-	for (;;) {
-		tmp = tmp->next;
-		if (tmp == &sdp->rglist)
-			break;
-		rgl = osi_list_entry(tmp, struct rgrp_list, list);
+	for (n = osi_first(&sdp->rgtree); n; n = next) {
+		next = osi_next(n);
+		rgl = (struct rgrp_tree *)n;
 		extent = rgl->ri.ri_addr + rgl->ri.ri_length + rgl->ri.ri_data;
 		if (extent > size)
 			size = extent;
@@ -168,19 +167,22 @@ static uint64_t filesystem_size(struct gfs2_sbd *sdp)
  */
 static void initialize_new_portion(struct gfs2_sbd *sdp, int *old_rg_count)
 {
+	struct osi_node *n, *next = NULL;
 	uint64_t rgrp = 0;
-	osi_list_t *head = &sdp->rglist;
-	struct rgrp_list *rl;
+	struct rgrp_tree *rl;
 
 	*old_rg_count = 0;
 	/* Delete the old RGs from the rglist */
-	for (rgrp = 0; !osi_list_empty(head) &&
-		     rgrp < (sdp->rgrps - sdp->new_rgrps); rgrp++) {
+	for (rgrp = 0, n = osi_first(&sdp->rgtree);
+	     n && rgrp < (sdp->rgrps - sdp->new_rgrps); n = next, rgrp++) {
+		next = osi_next(n);
 		(*old_rg_count)++;
-		osi_list_del(head->next);
+		rl = (struct rgrp_tree *)n;
+		osi_erase(&rl->node, &sdp->rgtree);
+		free(rl);
 	}
 	/* Issue a discard ioctl for the new portion */
-	rl = osi_list_entry(sdp->rglist.next, struct rgrp_list, list);
+	rl = (struct rgrp_tree *)n;
 	discard_blocks(sdp->device_fd, rl->start * sdp->bsize,
 		       (sdp->device.length - rl->start) * sdp->bsize);
 	/* Build the remaining resource groups */
@@ -198,17 +200,19 @@ static void initialize_new_portion(struct gfs2_sbd *sdp, int *old_rg_count)
  */
 static void fix_rindex(struct gfs2_sbd *sdp, int rindex_fd, int old_rg_count)
 {
+	struct osi_node *n, *next = NULL;
 	int count, rg;
-	struct rgrp_list *rl;
+	struct rgrp_tree *rl;
 	char *buf, *bufptr;
-	osi_list_t *tmp;
 	ssize_t writelen;
 	struct stat statbuf;
 
 	/* Count the number of new RGs. */
 	rg = 0;
-	osi_list_foreach(tmp, &sdp->rglist)
+	for (n = osi_first(&sdp->rgtree); n; n = next) {
+		next = osi_next(n);
 		rg++;
+	}
 	log_info( _("%d new rindex entries.\n"), rg);
 	writelen = rg * sizeof(struct gfs2_rindex);
 	buf = calloc(1, writelen);
@@ -220,13 +224,14 @@ static void fix_rindex(struct gfs2_sbd *sdp, int rindex_fd, int old_rg_count)
 	/* need to use the gfs2 kernel code rather than the libgfs2 */
 	/* code so we have a live update while mounted.             */
 	bufptr = buf;
-	osi_list_foreach(tmp, &sdp->rglist) {
+	for (n = osi_first(&sdp->rgtree); n; n = next) {
+		next = osi_next(n);
 		rg++;
-		rl = osi_list_entry(tmp, struct rgrp_list, list);
+		rl = (struct rgrp_tree *)n;
 		gfs2_rindex_out(&rl->ri, bufptr);
 		bufptr += sizeof(struct gfs2_rindex);
 	}
-	gfs2_rgrp_free(&sdp->rglist);
+	gfs2_rgrp_free(&sdp->rgtree);
 	fsync(sdp->device_fd);
 	if (!test) {
 		if (fstat(rindex_fd, &statbuf) != 0) {
@@ -306,7 +311,6 @@ main_grow(int argc, char *argv[])
 	struct gfs2_sbd sbd, *sdp = &sbd;
 	int rgcount, rindex_fd;
 	char rindex_name[PATH_MAX];
-	osi_list_t *head = &sdp->rglist;
 
 	memset(sdp, 0, sizeof(struct gfs2_sbd));
 	sdp->bsize = GFS2_DEFAULT_BSIZE;
@@ -344,7 +348,8 @@ main_grow(int argc, char *argv[])
 			exit(-1);
 		}
 		log_info( _("Initializing lists...\n"));
-		osi_list_init(&sdp->rglist);
+		sdp->rgtree.osi_node = NULL;
+		sdp->rgcalc.osi_node = NULL;
 
 		sdp->sd_sb.sb_bsize = GFS2_DEFAULT_BSIZE;
 		sdp->bsize = sdp->sd_sb.sb_bsize;
@@ -397,14 +402,13 @@ main_grow(int argc, char *argv[])
 		else {
 			int old_rg_count;
 
-			compute_rgrp_layout(sdp, TRUE);
+			compute_rgrp_layout(sdp, &sdp->rgtree, TRUE);
 			print_info(sdp);
 			initialize_new_portion(sdp, &old_rg_count);
 			fix_rindex(sdp, rindex_fd, old_rg_count);
 		}
 		/* Delete the remaining RGs from the rglist */
-		while (!osi_list_empty(head))
-			osi_list_del(head->next);
+		gfs2_rgrp_free(&sdp->rgtree);
 		close(rindex_fd);
 		cleanup_metafs(sdp);
 		close(sdp->device_fd);
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index ee2a5da..bcc60e4 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -550,7 +550,7 @@ void main_mkfs(int argc, char *argv[])
 	sdp->qcsize = GFS2_DEFAULT_QCSIZE;
 	strcpy(sdp->lockproto, GFS2_DEFAULT_LOCKPROTO);
 	sdp->time = time(NULL);
-	osi_list_init(&sdp->rglist);
+	sdp->rgtree.osi_node = NULL;
 
 	decode_arguments(argc, argv, sdp);
 	if (sdp->rgsize == -1)                 /* if rg size not specified */
@@ -636,7 +636,7 @@ void main_mkfs(int argc, char *argv[])
 
 	/* Compute the resource group layouts */
 
-	compute_rgrp_layout(sdp, rgsize_specified);
+	compute_rgrp_layout(sdp, &sdp->rgtree, rgsize_specified);
 
 	/* Generate a random uuid */
 	get_random_bytes(uuid, sizeof(uuid));
@@ -666,7 +666,7 @@ void main_mkfs(int argc, char *argv[])
 	inode_put(&sdp->md.inum);
 	inode_put(&sdp->md.statfs);
 
-	gfs2_rgrp_free(&sdp->rglist);
+	gfs2_rgrp_free(&sdp->rgtree);
 	error = fsync(sdp->device_fd);
 	if (error)
 		die( _("can't fsync device (%d): %s\n"),
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 57/66] fsck.gfs2: Fix memory leaks
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (55 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 56/66] libgfs2: Make in-core rgrps use rbtree rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 58/66] Change man pages and gfs2_convert messages to include GFS rpeterso
                   ` (8 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch fixes some memory leaks in fsck.gfs2 that I discovered
by using valgrind.

rhbz#675723
---
 gfs2/fsck/fs_recovery.c |    2 ++
 gfs2/fsck/initialize.c  |   16 ++++++++++------
 gfs2/fsck/main.c        |    2 ++
 gfs2/fsck/metawalk.c    |   10 ++++++++--
 gfs2/fsck/pass1.c       |    6 +++++-
 5 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c
index 907e37f..d3c742a 100644
--- a/gfs2/fsck/fs_recovery.c
+++ b/gfs2/fsck/fs_recovery.c
@@ -611,6 +611,8 @@ int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check,
 		inode_put(&sdp->md.journal[i]);
 	}
 	inode_put(&sdp->md.jiinode);
+	free(sdp->md.journal);
+	sdp->md.journal = NULL;
 	/* Sync the buffers to disk so we get a fresh start. */
 	fsync(sdp->device_fd);
 	return error;
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 06121bc..95a6a65 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -641,12 +641,16 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
 		}
 		do_init_statfs(sdp);
 	}
-	buf = malloc(sdp->md.statfs->i_di.di_size);
-	// FIXME: handle failed malloc
-	gfs2_readi(sdp->md.statfs, buf, 0, sdp->md.statfs->i_di.di_size);
-	/* call gfs2_inum_range_in() to retrieve range */
-	gfs2_statfs_change_in(&sc, buf);
-	free(buf);
+	if (sdp->md.statfs->i_di.di_size) {
+		buf = malloc(sdp->md.statfs->i_di.di_size);
+		if (buf) {
+			gfs2_readi(sdp->md.statfs, buf, 0,
+				   sdp->md.statfs->i_di.di_size);
+			/* call gfs2_inum_range_in() to retrieve range */
+			gfs2_statfs_change_in(&sc, buf);
+			free(buf);
+		}
+	}
 
 	if (sdp->gfs1)
 		sdp->md.qinode = inode_read(sdp, sbd1->sb_quota_di.no_addr);
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index 7b768b0..676b676 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -349,6 +349,8 @@ int main(int argc, char **argv)
 	inode_put(&sdp->md.statfs);
 	for (j = 0; j < sdp->md.journals; j++)
 		inode_put(&sdp->md.journal[j]);
+	free(sdp->md.journal);
+	sdp->md.journal = NULL;
 	inode_put(&sdp->md.jiinode);
 	inode_put(&sdp->md.riinode);
 	inode_put(&sdp->md.qinode);
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index c313c3b..8723adc 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -1168,8 +1168,10 @@ static int build_and_check_metalist(struct gfs2_inode *ip, osi_list_t *mlp,
 			for (ptr = (uint64_t *)(bh->b_data + head_size);
 			     (char *)ptr < (bh->b_data + ip->i_sbd->bsize);
 			     ptr++) {
-				if (skip_this_pass || fsck_abort)
+				if (skip_this_pass || fsck_abort) {
+					free_metalist(ip, mlp);
 					return FSCK_OK;
+				}
 				nbh = NULL;
 
 				if (!*ptr)
@@ -1281,6 +1283,7 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 	error = build_and_check_metalist(ip, &metalist[0], pass);
 	if (error) {
 		stack;
+		free_metalist(ip, &metalist[0]);
 		return error;
 	}
 
@@ -1317,8 +1320,10 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 		last_reported_fblock = -10000000;
 
 	while (error >= 0 && !osi_list_empty(list)) {
-		if (fsck_abort)
+		if (fsck_abort) {
+			free_metalist(ip, &metalist[0]);
 			return 0;
+		}
 		bh = osi_list_entry(list->next, struct gfs2_buffer_head,
 				    b_altlist);
 
@@ -1371,6 +1376,7 @@ int check_metatree(struct gfs2_inode *ip, struct metawalk_fxns *pass)
 			    (unsigned long long)ip->i_di.di_num.no_addr);
 		fflush(stdout);
 	}
+	free_metalist(ip, &metalist[0]);
 	return error;
 }
 
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index de5de2b..b3ef7d4 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -430,6 +430,7 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block,
 			fsck_blockmap_set(ip, block, _("bad indirect"),
 					  gfs2_meta_inval);
 			brelse(nbh);
+			nbh = NULL;
 			return 1;
 		}
 		brelse(nbh);
@@ -439,8 +440,11 @@ static int check_metalist(struct gfs2_inode *ip, uint64_t block,
 
 	bc->indir_count++;
 	if (found_dup) {
-		if (nbh)
+		if (nbh) {
 			brelse(nbh);
+			nbh = NULL;
+			*bh = NULL;
+		}
 		return 1; /* don't process the metadata again */
 	} else
 		fsck_blockmap_set(ip, block, _("indirect"),
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 58/66] Change man pages and gfs2_convert messages to include GFS
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (56 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 57/66] fsck.gfs2: Fix memory leaks rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 59/66] gfs2_edit: Fix memory leaks rpeterso
                   ` (7 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

Since fsck.gfs2 can now handle GFS1 file systems, this patch changes
the message in gfs2_convert and the man pages to reflect that.

rhbz#675723
---
 gfs2/convert/gfs2_convert.c |    2 +-
 gfs2/man/fsck.gfs2.8        |    9 +++++----
 gfs2/man/gfs2_convert.8     |    2 +-
 3 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 8ed2c1a..fa6461f 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -1604,7 +1604,7 @@ static void give_warning(void)
 	printf("WARNING: This can't be undone.  It is strongly advised "	\
 		   "that you:\n\n");
 	printf("   1. Back up your entire filesystem first.\n");
-	printf("   2. Run gfs_fsck first to ensure filesystem integrity.\n");
+	printf("   2. Run fsck.gfs2 first to ensure filesystem integrity.\n");
 	printf("   3. Make sure the filesystem is NOT mounted from any node.\n");
 	printf("   4. Make sure you have the latest software versions.\n");
 }/* give_warning */
diff --git a/gfs2/man/fsck.gfs2.8 b/gfs2/man/fsck.gfs2.8
index 462e918..3ecfbe3 100644
--- a/gfs2/man/fsck.gfs2.8
+++ b/gfs2/man/fsck.gfs2.8
@@ -1,18 +1,19 @@
 .TH fsck.gfs2 8
 
 .SH NAME
-fsck.gfs2 - Offline GFS2 file system checker
+fsck.gfs2 - Offline GFS and GFS2 file system checker
 
 .SH SYNOPSIS
 .B fsck.gfs2
 [\fIOPTION\fR]... \fIDEVICE\fR
 
 .SH WARNING
-All GFS2 nodes \fImust\fP have the GFS2 filesystem unmounted before running
-fsck.gfs2.  Failure to unmount all nodes may result in filesystem corruption.
+All computers \fImust\fP have the filesystem unmounted before running
+fsck.gfs2.  Failure to unmount from all nodes in a cluster will likely result
+in filesystem corruption.
 
 .SH DESCRIPTION
-fsck.gfs2 will check that the GFS2 file system on a device is structurally valid.
+fsck.gfs2 will check that the GFS or GFS2 file system on a device is structurally valid.
 It should not be run on a mounted file system.  If file system corruption is
 detected, it will attempt to repair the file system.  There is a limit to what
 fsck.gfs2 can do.  If important file system structures are destroyed, such that
diff --git a/gfs2/man/gfs2_convert.8 b/gfs2/man/gfs2_convert.8
index 5969432..ca0f64f 100644
--- a/gfs2/man/gfs2_convert.8
+++ b/gfs2/man/gfs2_convert.8
@@ -10,7 +10,7 @@ gfs2_convert - Convert a GFS1 filesystem to GFS2
 .SH DESCRIPTION
 gfs2_convert is used to convert a filesystem from GFS1 to GFS2. It is
 required that the GFS1 filesystem be checked and fixed for errors using 
-\fBgfs_fsck\fP and that the filesystem be backed up before
+\fBfsck.gfs2\fP and that the filesystem be backed up before
 attempting to convert it. The convert process is irreversible and any
 error encountered during the conversion can result in the abrupt
 termination of the program and consequently an unusable filesystem.
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 59/66] gfs2_edit: Fix memory leaks
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (57 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 58/66] Change man pages and gfs2_convert messages to include GFS rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 60/66] fsck.gfs2: Journals not properly checked rpeterso
                   ` (6 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch plugs a couple memory leaks found by valgrind.

rhbz#675723
---
 gfs2/edit/savemeta.c |   10 ++++++++--
 1 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index 33f2970..1b9d0a8 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -132,6 +132,7 @@ static int get_gfs_struct_info(struct gfs2_buffer_head *lbh, int *block_type,
 			*gstruct_len = sizeof(struct gfs2_dinode);
 		else
 			*gstruct_len = sbd.bsize;
+		inode_put(&inode);
 		break;
 	case GFS2_METATYPE_IN:   /* 5 (indir inode blklst) */
 		*gstruct_len = sbd.bsize; /*sizeof(struct gfs_indirect);*/
@@ -490,7 +491,10 @@ static void save_inode_data(struct metafd *mfd)
 			mybh = osi_list_entry(cur_list->next,
 					    struct gfs2_buffer_head,
 					    b_altlist);
-			osi_list_del(&mybh->b_altlist);
+			if (mybh == inode->i_bh)
+				osi_list_del(&mybh->b_altlist);
+			else
+				brelse(mybh);
 		}
 	}
 	/* Process directory exhash inodes */
@@ -808,6 +812,8 @@ void savemeta(char *out_fn, int saveoption, int gziplevel)
 	free(savedata);
 	savemetaclose(&mfd);
 	close(sbd.device_fd);
+	free(indirect);
+	gfs2_rgrp_free(&sbd.rgtree);
 	exit(0);
 }
 
@@ -1032,6 +1038,6 @@ void restoremeta(const char *in_fn, const char *out_device,
 	gzclose(gzfd);
 	if (!printblocksonly)
 		close(sbd.device_fd);
-
+	free(indirect);
 	exit(error);
 }
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 60/66] fsck.gfs2: Journals not properly checked
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (58 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 59/66] gfs2_edit: Fix memory leaks rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 61/66] fsck.gfs2: Rearrange block types to group all inode types rpeterso
                   ` (5 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

The coverity tool found a problem with the previous set of patches that
led me to discover a problem with how journals were being processed
under the new code.  The problem was that the journal index was read
in after journal replay.  But journal replay relies upon information
in the jindex.  This patch rearranges the initializeation sequence
of fsck.gfs2 so that the journal index and rindex are read in and
processed prior to journal recovery.

rhbz#675723
---
 gfs2/fsck/fs_recovery.c |   12 ---
 gfs2/fsck/initialize.c  |  183 +++++++++++++++++++++++++++++++----------------
 2 files changed, 122 insertions(+), 73 deletions(-)

diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c
index d3c742a..52303dd 100644
--- a/gfs2/fsck/fs_recovery.c
+++ b/gfs2/fsck/fs_recovery.c
@@ -572,14 +572,6 @@ int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check,
 	*clean_journals = 0;
 
 	sdp->jsize = GFS2_DEFAULT_JSIZE;
-	/* Get master dinode */
-	gfs2_lookupi(sdp->master_dir, "jindex", 6, &sdp->md.jiinode);
-
-	/* read in the journal index data */
-	if (ji_update(sdp)){
-		log_err( _("Unable to read in jindex inode.\n"));
-		return -1;
-	}
 
 	for(i = 0; i < sdp->md.journals; i++) {
 		if (!sdp->md.journal[i]) {
@@ -608,11 +600,7 @@ int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check,
 			}
 			*clean_journals += clean;
 		}
-		inode_put(&sdp->md.journal[i]);
 	}
-	inode_put(&sdp->md.jiinode);
-	free(sdp->md.journal);
-	sdp->md.journal = NULL;
 	/* Sync the buffers to disk so we get a fresh start. */
 	fsync(sdp->device_fd);
 	return error;
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 95a6a65..608eb32 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -477,18 +477,13 @@ static void lookup_per_node(struct gfs2_sbd *sdp, int allow_rebuild)
 }
 
 /**
- * init_system_inodes
- *
- * Returns: 0 on success, -1 on failure
+ * fetch_rgrps - fetch the resource groups from disk, and check their integrity
  */
-static int init_system_inodes(struct gfs2_sbd *sdp)
+static int fetch_rgrps(struct gfs2_sbd *sdp)
 {
-	uint64_t inumbuf;
-	char *buf;
-	struct gfs2_statfs_change sc;
-	int rgcount, sane = 1, err = 0;
 	enum rgindex_trust_level trust_lvl;
-	uint64_t addl_mem_needed;
+	int rgcount, sane = 1;
+
 	const char *level_desc[] = {
 		_("Checking if all rgrp and rindex values are good"),
 		_("Checking if rindex values may be easily repaired"),
@@ -503,48 +498,6 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
 		_("Too many rgrp misses: rgrps must be unevenly spaced"),
 		_("Too much damage found: we cannot rebuild this rindex"),
 	};
-
-	/*******************************************************************
-	 ******************  Initialize important inodes  ******************
-	 *******************************************************************/
-
-	log_info( _("Initializing special inodes...\n"));
-
-	/* Get root dinode */
-	sdp->md.rooti = inode_read(sdp, sdp->sd_sb.sb_root_dir.no_addr);
-
-	if (sdp->gfs1)
-		sdp->md.riinode = inode_read(sdp, sbd1->sb_rindex_di.no_addr);
-	else
-		gfs2_lookupi(sdp->master_dir, "rindex", 6, &sdp->md.riinode);
-	if (!sdp->md.riinode) {
-		if (query( _("The gfs2 system rindex inode is missing. "
-			     "Okay to rebuild it? (y/n) ")))
-			build_rindex(sdp);
-	}
-
-	/*******************************************************************
-	 ******************  Fill in journal information  ******************
-	 *******************************************************************/
-
-	/* rgrepair requires the journals be read in in order to distinguish
-	   "real" rgrps from rgrps that are just copies left in journals. */
-	if (sdp->gfs1)
-		sdp->md.jiinode = inode_read(sdp, sbd1->sb_jindex_di.no_addr);
-	else
-		gfs2_lookupi(sdp->master_dir, "jindex", 6, &sdp->md.jiinode);
-	if (!sdp->md.jiinode) {
-		if (query( _("The gfs2 system jindex inode is missing. "
-			     "Okay to rebuild it? (y/n) ")))
-			build_jindex(sdp);
-	}
-
-	/* read in the ji data */
-	if (ji_update(sdp)){
-		log_err( _("Unable to read in jindex inode.\n"));
-		return -1;
-	}
-
 	/*******************************************************************
 	 ********  Validate and read in resource group information  ********
 	 *******************************************************************/
@@ -580,6 +533,34 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
 	log_info( _("%u resource groups found.\n"), rgcount);
 
 	check_rgrps_integrity(sdp);
+	return 0;
+}
+
+/**
+ * init_system_inodes
+ *
+ * Returns: 0 on success, -1 on failure
+ */
+static int init_system_inodes(struct gfs2_sbd *sdp)
+{
+	uint64_t inumbuf = 0;
+	char *buf;
+	struct gfs2_statfs_change sc;
+	uint64_t addl_mem_needed;
+	int err;
+
+	/*******************************************************************
+	 ******************  Initialize important inodes  ******************
+	 *******************************************************************/
+
+	log_info( _("Initializing special inodes...\n"));
+
+	/* Get root dinode */
+	sdp->md.rooti = inode_read(sdp, sdp->sd_sb.sb_root_dir.no_addr);
+
+	err = fetch_rgrps(sdp);
+	if (err)
+		return err;
 
 	/*******************************************************************
 	 *****************  Initialize more system inodes  *****************
@@ -1232,8 +1213,6 @@ static int reconstruct_single_journal(struct gfs2_sbd *sdp, int jnum,
 	log_info("Clearing journal %d\n", jnum);
 
 	for (seg = 0; seg < ji_nsegment; seg++){
-		bh = bget(sdp, lh.lh_first * sdp->bsize);
-		memset(bh->b_data, 0, sdp->bsize);
 		memset(&lh, 0, sizeof(struct gfs_log_header));
 
 		lh.lh_header.mh_magic = GFS2_MAGIC;
@@ -1245,6 +1224,8 @@ static int reconstruct_single_journal(struct gfs2_sbd *sdp, int jnum,
 			(seg * sbd1->sb_seg_size);
 		lh.lh_sequence = sequence;
 
+		bh = bget(sdp, lh.lh_first * sdp->bsize);
+		memset(bh->b_data, 0, sdp->bsize);
 		gfs_log_header_out(&lh, bh->b_data);
 		gfs_log_header_out(&lh, bh->b_data + GFS2_BASIC_BLOCK -
 				   sizeof(struct gfs_log_header));
@@ -1269,7 +1250,7 @@ static int reconstruct_journals(struct gfs2_sbd *sdp)
 	struct gfs_jindex ji;
 	char buf[sizeof(struct gfs_jindex)];
 
-	log_err("Clearing GFS journals (this may take a while)");
+	log_err("Clearing GFS journals (this may take a while)\n");
 	for (i = 0; i < sdp->md.journals; i++) {
 		gfs2_readi(sdp->md.jiinode, buf, i * sizeof(struct gfs_jindex),
 			   sizeof(struct gfs_jindex));
@@ -1284,6 +1265,81 @@ static int reconstruct_journals(struct gfs2_sbd *sdp)
 }
 
 /**
+ * init_rindex - read in the rindex file
+ */
+static int init_rindex(struct gfs2_sbd *sdp)
+{
+	int err;
+
+	if (sdp->gfs1)
+		sdp->md.riinode = inode_read(sdp, sbd1->sb_rindex_di.no_addr);
+	else
+		gfs2_lookupi(sdp->master_dir, "rindex", 6, &sdp->md.riinode);
+
+	if (sdp->md.riinode)
+		return 0;
+
+	if (!query( _("The gfs2 system rindex inode is missing. "
+		      "Okay to rebuild it? (y/n) "))) {
+		log_crit(_("Error: Cannot proceed without a valid rindex.\n"));
+		return -1;
+	}
+	if ((err = build_rindex(sdp))) {
+		log_crit(_("Error %d rebuilding rindex\n"), err);
+		return -1;
+	}
+	return 0;
+}
+
+/**
+ * init_jindex - read in the rindex file
+ */
+static int init_jindex(struct gfs2_sbd *sdp)
+{
+	/*******************************************************************
+	 ******************  Fill in journal information  ******************
+	 *******************************************************************/
+
+	/* rgrepair requires the journals be read in in order to distinguish
+	   "real" rgrps from rgrps that are just copies left in journals. */
+	if (sdp->gfs1)
+		sdp->md.jiinode = inode_read(sdp, sbd1->sb_jindex_di.no_addr);
+	else
+		gfs2_lookupi(sdp->master_dir, "jindex", 6, &sdp->md.jiinode);
+
+	if (!sdp->md.jiinode) {
+		int err;
+
+		if (!query( _("The gfs2 system jindex inode is missing. "
+			      "Okay to rebuild it? (y/n) "))) {
+			log_crit(_("Error: cannot proceed without a valid "
+				   "jindex file.\n"));
+			return -1;
+		}
+		/* In order to rebuild jindex, we need some valid
+		   rgrps in memory.  Temporarily read those in. */
+		err = fetch_rgrps(sdp);
+		if (err)
+			return err;
+
+		err = build_jindex(sdp);
+		/* Free rgrps read in earlier (re-read them later) */
+		gfs2_rgrp_free(&sdp->rgtree);
+		if (err) {
+			log_crit(_("Error %d rebuilding jindex\n"), err);
+			return err;
+		}
+	}
+
+	/* read in the ji data */
+	if (ji_update(sdp)){
+		log_err( _("Unable to read in jindex inode.\n"));
+		return -1;
+	}
+	return 0;
+}
+
+/**
  * initialize - initialize superblock pointer
  *
  */
@@ -1372,7 +1428,17 @@ int initialize(struct gfs2_sbd *sdp, int force_check, int preen,
 	if (!sdp->gfs1)
 		lookup_per_node(sdp, 0);
 
-	/* verify various things */
+	/* We need rindex first in case jindex is missing and needs to read
+	   in the rgrps before rebuilding it. */
+	if (init_rindex(sdp))
+		return FSCK_ERROR;
+
+	/* We need to read in jindex in order to replay the journals */
+	if (init_jindex(sdp))
+		return FSCK_ERROR;
+
+	/* If GFS, rebuild the journals.  If GFS2, replay them.  We don't have
+	   the smarts to replay GFS1 journals (neither did gfs_fsck). */
 
 	if (sdp->gfs1) {
 		if (reconstruct_journals(sdp))
@@ -1403,7 +1469,7 @@ mount_fail:
 	return FSCK_USAGE;
 }
 
-static void destroy_sdp(struct gfs2_sbd *sdp)
+void destroy(struct gfs2_sbd *sdp)
 {
 	if (!opts.no) {
 		if (block_mounters(sdp, 0)) {
@@ -1425,8 +1491,3 @@ static void destroy_sdp(struct gfs2_sbd *sdp)
 				   "caches.\n"));
 	}
 }
-
-void destroy(struct gfs2_sbd *sdp)
-{
-	destroy_sdp(sdp);
-}
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 61/66] fsck.gfs2: Rearrange block types to group all inode types
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (59 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 60/66] fsck.gfs2: Journals not properly checked rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 62/66] fsck.gfs2: Fix initialization error return codes rpeterso
                   ` (4 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch rearranges the declares in util.h such that all the inode
types are grouped together.  There's a place in fsck.gfs2 that checks
whether a block is an inode by checking the range of block types.
But that's only valid if they are all grouped together.  Since a
previous patch put GFS journaled data blocks in the range, they could
mistakenly pass that test and be treated as an inode for that test.
I never saw an error resulting from this mistake, but I'm fixing it
anyway.

rhbz#675723
---
 gfs2/fsck/util.h |   22 ++++++++++++----------
 1 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/gfs2/fsck/util.h b/gfs2/fsck/util.h
index 2f74af3..b56fe69 100644
--- a/gfs2/fsck/util.h
+++ b/gfs2/fsck/util.h
@@ -40,16 +40,18 @@ enum gfs2_mark_block {
 	gfs2_block_free    = (0x0),
 	gfs2_block_used    = (0x1),
 	gfs2_indir_blk     = (0x2),
+	/* These are inode block types (only): */
 	gfs2_inode_dir     = (0x3),
 	gfs2_inode_file    = (0x4),
 
 	gfs2_inode_lnk     = (0x5),
 	gfs2_inode_device  = (0x6), /* char or block device */
-	gfs2_jdata         = (0x7), /* gfs journaled data blocks */
-	gfs2_inode_fifo    = (0x8),
-	gfs2_inode_sock    = (0x9),
+	gfs2_inode_fifo    = (0x7),
+	gfs2_inode_sock    = (0x8),
+	gfs2_inode_invalid = (0x9),
 
-	gfs2_inode_invalid = (0xa),
+	/* misc block types: */
+	gfs2_jdata         = (0xa), /* gfs journaled data blocks */
 	gfs2_meta_inval    = (0xb),
 	gfs2_leaf_blk      = (0xc),
 	gfs2_freemeta      = (0xd), /* was: gfs2_meta_rgrp */
@@ -69,11 +71,11 @@ static const inline char *block_type_string(uint8_t q)
 
 		"symlink",
 		"device",
-		"journaled data",
 		"fifo",
 		"socket",
-
 		"invalid inode",
+
+		"journaled data",
 		"invalid meta",
 		"dir leaf",
 		"free metadata",
@@ -99,11 +101,11 @@ static inline int blockmap_to_bitmap(enum gfs2_mark_block m, int gfs1)
 
 		 GFS2_BLKST_DINODE,  /* symlink */
 		 GFS2_BLKST_DINODE,  /* block or char device */
-		 GFS2_BLKST_USED,    /* journaled data */
 		 GFS2_BLKST_DINODE,  /* fifo */
 		 GFS2_BLKST_DINODE,  /* socket */
-
 		 GFS2_BLKST_FREE,  /* invalid inode */
+
+		 GFS2_BLKST_USED,    /* journaled data */
 		 GFS2_BLKST_FREE,  /* invalid meta */
 		 GFS2_BLKST_USED,  /* dir leaf */
 		 GFS2_BLKST_UNLINKED,  /* GFS unlinked metadata */
@@ -119,11 +121,11 @@ static inline int blockmap_to_bitmap(enum gfs2_mark_block m, int gfs1)
 
 		 GFS2_BLKST_DINODE,  /* symlink */
 		 GFS2_BLKST_DINODE,  /* block or char device */
-		 GFS2_BLKST_DINODE,  /* journaled data */
 		 GFS2_BLKST_DINODE,  /* fifo */
 		 GFS2_BLKST_DINODE,  /* socket */
-
 		 GFS2_BLKST_FREE,  /* invalid inode */
+
+		 GFS2_BLKST_DINODE,  /* journaled data */
 		 GFS2_BLKST_FREE,  /* invalid meta */
 		 GFS2_BLKST_DINODE,  /* dir leaf */
 		 GFS2_BLKST_UNLINKED, /* GFS unlinked metadata */
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 62/66] fsck.gfs2: Fix initialization error return codes
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (60 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 61/66] fsck.gfs2: Rearrange block types to group all inode types rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 63/66] fsck.gfs2: Don't use strerror for libgfs2 errors rpeterso
                   ` (3 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

In initialize.c there are several places where it can exit with an error.
These places return with -1 where they should return the standard fsck
error FSCK_ERROR.

rhbz#675723
---
 gfs2/fsck/initialize.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 608eb32..7171cdd 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -466,13 +466,13 @@ static void lookup_per_node(struct gfs2_sbd *sdp, int allow_rebuild)
 		if (err) {
 			log_crit(_("Error rebuilding per_node directory: %s\n"),
 				 strerror(err));
-			exit(-1);
+			exit(FSCK_ERROR);
 		}
 	}
 	gfs2_lookupi(sdp->master_dir, "per_node", 8, &sdp->md.pinode);
 	if (!sdp->md.pinode) {
 		log_err( _("Unable to rebuild per_node; aborting.\n"));
-		exit(-1);
+		exit(FSCK_ERROR);
 	}
 }
 
@@ -579,7 +579,7 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
 			if (err) {
 				log_crit(_("Error rebuilding inum inode: %s\n"),
 					 strerror(err));
-				exit(-1);
+				exit(FSCK_ERROR);
 			}
 			gfs2_lookupi(sdp->master_dir, "inum", 4,
 				     &sdp->md.inum);
@@ -611,7 +611,7 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
 		if (err) {
 			log_crit(_("Error rebuilding statfs inode: %s\n"),
 				 strerror(err));
-			exit(-1);
+			exit(FSCK_ERROR);
 		}
 		gfs2_lookupi(sdp->master_dir, "statfs", 6, &sdp->md.statfs);
 		if (!sdp->md.statfs) {
@@ -648,7 +648,7 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
 		if (err) {
 			log_crit(_("Error rebuilding quota inode: %s\n"),
 				 strerror(err));
-			exit(-1);
+			exit(FSCK_ERROR);
 		}
 		gfs2_lookupi(sdp->master_dir, "quota", 5, &sdp->md.qinode);
 		if (!sdp->md.qinode) {
@@ -1156,7 +1156,7 @@ static int fill_super_block(struct gfs2_sbd *sdp)
 
 	if (compute_constants(sdp)) {
 		log_crit(_("Bad constants (1)\n"));
-		exit(-1);
+		exit(FSCK_ERROR);
 	}
 	ret = read_sb(sdp, 1);
 	if (ret < 0) {
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 63/66] fsck.gfs2: Don't use strerror for libgfs2 errors
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (61 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 62/66] fsck.gfs2: Fix initialization error return codes rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 64/66] fsck.gfs2: Fix memory leak in initialize.c rpeterso
                   ` (2 subsequent siblings)
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch removes the calls to strerror from initialize.c.
The errors returned by libgfs2 currently don't conform to system
errors.  For example, they can return positive or negative numbers.
Therefore, strerror could segfault or give nonsense messages.
I hate numeric error messages as much as the next guy, but using
strerror won't work until we systematically go through libgfs2 and
make all the return codes conform to the rules strerror lives by.

rhbz#675723
---
 gfs2/fsck/initialize.c   |   14 ++++++--------
 gfs2/fsck/lost_n_found.c |    4 ++--
 2 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 7171cdd..7b47374 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -464,8 +464,8 @@ static void lookup_per_node(struct gfs2_sbd *sdp, int allow_rebuild)
 
 		err = build_per_node(sdp);
 		if (err) {
-			log_crit(_("Error rebuilding per_node directory: %s\n"),
-				 strerror(err));
+			log_crit(_("Error %d rebuilding per_node directory\n"),
+				 err);
 			exit(FSCK_ERROR);
 		}
 	}
@@ -577,8 +577,8 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
 			}
 			err = build_inum(sdp);
 			if (err) {
-				log_crit(_("Error rebuilding inum inode: %s\n"),
-					 strerror(err));
+				log_crit(_("Error %d rebuilding inum inode\n"),
+					 err);
 				exit(FSCK_ERROR);
 			}
 			gfs2_lookupi(sdp->master_dir, "inum", 4,
@@ -609,8 +609,7 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
 		}
 		err = build_statfs(sdp);
 		if (err) {
-			log_crit(_("Error rebuilding statfs inode: %s\n"),
-				 strerror(err));
+			log_crit(_("Error %d rebuilding statfs inode\n"), err);
 			exit(FSCK_ERROR);
 		}
 		gfs2_lookupi(sdp->master_dir, "statfs", 6, &sdp->md.statfs);
@@ -646,8 +645,7 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
 		}
 		err = build_quota(sdp);
 		if (err) {
-			log_crit(_("Error rebuilding quota inode: %s\n"),
-				 strerror(err));
+			log_crit(_("Error %d rebuilding quota inode\n"), err);
 			exit(FSCK_ERROR);
 		}
 		gfs2_lookupi(sdp->master_dir, "quota", 5, &sdp->md.qinode);
diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index d109283..70a9181 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -153,8 +153,8 @@ int add_inode_to_lf(struct gfs2_inode *ip){
 			lf_dip = createi(sdp->md.rooti, "lost+found",
 					 S_IFDIR | 0700, 0);
 		if (lf_dip == NULL) {
-			log_crit(_("Error creating lost+found: %s\n"),
-			         strerror(errno));
+			log_crit(_("Error %d creating lost+found: %s\n"),
+				 errno);
 			exit(FSCK_ERROR);
 		}
 
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 64/66] fsck.gfs2: Fix memory leak in initialize.c
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (62 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 63/66] fsck.gfs2: Don't use strerror for libgfs2 errors rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 65/66] fsck.gfs2: Add return code checks and initializations rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 66/66] libgfs2: Fix null pointer dereference in linked_leaf_search rpeterso
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch fixes a memory leak whereby dinodes were not being freed
under certain conditions.

rhbz#675723
---
 gfs2/fsck/initialize.c |   25 ++++++++++++++++---------
 1 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 7b47374..6a92992 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -777,7 +777,7 @@ static void peruse_system_dinode(struct gfs2_sbd *sdp, struct gfs2_dinode *di,
 	    (sdp->gfs1 && (di->di_flags & GFS2_DIF_JDATA) &&
 	     (di->di_size % sizeof(struct gfs_jindex) == 0))) {
 		if (fix_md.jiinode || is_journal_copy(ip, bh))
-			return;
+			goto out_discard_ip;
 		log_warn(_("Found system jindex file at: 0x%llx\n"),
 			 di->di_num.no_addr);
 		fix_md.jiinode = ip;
@@ -786,8 +786,10 @@ static void peruse_system_dinode(struct gfs2_sbd *sdp, struct gfs2_dinode *di,
 		   jindex: master */
 		gfs2_lookupi(ip, "jindex", 6, &child_ip);
 		if (child_ip) {
-			if (fix_md.jiinode || is_journal_copy(ip, bh))
-				return;
+			if (fix_md.jiinode || is_journal_copy(ip, bh)) {
+				inode_put(&child_ip);
+				goto out_discard_ip;
+			}
 			fix_md.jiinode = child_ip;
 			sdp->sd_sb.sb_master_dir.no_addr = di->di_num.no_addr;
 			log_warn(_("Found system master directory at: "
@@ -799,8 +801,9 @@ static void peruse_system_dinode(struct gfs2_sbd *sdp, struct gfs2_dinode *di,
 		   has a statfs_change: per_node, and its .. will be master. */
 		gfs2_lookupi(ip, "statfs_change0", 14, &child_ip);
 		if (child_ip) {
+			inode_put(&child_ip);
 			if (fix_md.pinode || is_journal_copy(ip, bh))
-				return;
+				goto out_discard_ip;
 			log_warn(_("Found system per_node directory at: "
 				   "0x%llx\n"), ip->i_di.di_num.no_addr);
 			fix_md.pinode = ip;
@@ -816,22 +819,22 @@ static void peruse_system_dinode(struct gfs2_sbd *sdp, struct gfs2_dinode *di,
 		}
 		log_debug(_("Unknown system directory at block 0x%llx\n"),
 			  di->di_num.no_addr);
-		inode_put(&ip);
+		goto out_discard_ip;
 	} else if (!sdp->gfs1 && di->di_size == 8) {
 		if (fix_md.inum || is_journal_copy(ip, bh))
-			return;
+			goto out_discard_ip;
 		fix_md.inum = ip;
 		log_warn(_("Found system inum file at: 0x%llx\n"),
 			 di->di_num.no_addr);
 	} else if (di->di_size == 24) {
 		if (fix_md.statfs || is_journal_copy(ip, bh))
-			return;
+			goto out_discard_ip;
 		fix_md.statfs = ip;
 		log_warn(_("Found system statfs file at: 0x%llx\n"),
 			 di->di_num.no_addr);
 	} else if ((di->di_size % 96) == 0) {
 		if (fix_md.riinode || is_journal_copy(ip, bh))
-			return;
+			goto out_discard_ip;
 		fix_md.riinode = ip;
 		log_warn(_("Found system rindex file at: 0x%llx\n"),
 			 di->di_num.no_addr);
@@ -839,11 +842,15 @@ static void peruse_system_dinode(struct gfs2_sbd *sdp, struct gfs2_dinode *di,
 		   di->di_num.no_formal_ino >= 12 &&
 		   di->di_num.no_formal_ino <= 100) {
 		if (is_journal_copy(ip, bh))
-			return;
+			goto out_discard_ip;
 		fix_md.qinode = ip;
 		log_warn(_("Found system quota file at: 0x%llx\n"),
 			 di->di_num.no_addr);
 	}
+	return;
+
+out_discard_ip:
+	inode_put(&ip);
 }
 
 /**
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 65/66] fsck.gfs2: Add return code checks and initializations
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (63 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 64/66] fsck.gfs2: Fix memory leak in initialize.c rpeterso
@ 2012-01-20 15:10 ` rpeterso
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 66/66] libgfs2: Fix null pointer dereference in linked_leaf_search rpeterso
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

This patch fixes several problems detected by the coverity
tool whereby variables could be accessed without being
initialized, and where return codes should be checked and
were not.

rhbz#675723
---
 gfs2/fsck/fs_recovery.c  |    9 ++++
 gfs2/fsck/initialize.c   |  107 +++++++++++++++++++++++++++++++++++++---------
 gfs2/fsck/lost_n_found.c |   18 ++++++-
 gfs2/fsck/pass1.c        |   19 ++++++---
 gfs2/fsck/pass2.c        |   25 ++++++++---
 gfs2/fsck/pass3.c        |   11 +++-
 gfs2/fsck/pass5.c        |   17 ++++++--
 gfs2/libgfs2/fs_ops.c    |   41 ++++++++++++------
 gfs2/libgfs2/libgfs2.h   |    2 +-
 9 files changed, 190 insertions(+), 59 deletions(-)

diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c
index 52303dd..d07a515 100644
--- a/gfs2/fsck/fs_recovery.c
+++ b/gfs2/fsck/fs_recovery.c
@@ -125,6 +125,10 @@ static int buf_lo_scan_elements(struct gfs2_inode *ip, unsigned int start,
 			  (unsigned long long)blkno, (unsigned long long)blkno,
 			  start);
 		bh_ip = bget(sdp, blkno);
+		if (!bh_ip) {
+			log_err(_("Out of memory when replaying journals.\n"));
+			return FSCK_ERROR;
+		}
 		memcpy(bh_ip->b_data, bh_log->b_data, sdp->bsize);
 
 		check_magic = ((struct gfs2_meta_header *)
@@ -233,6 +237,10 @@ static int databuf_lo_scan_elements(struct gfs2_inode *ip, unsigned int start,
 			  (unsigned long long)blkno, (unsigned long long)blkno,
 			  start);
 		bh_ip = bget(sdp, blkno);
+		if (!bh_ip) {
+			log_err(_("Out of memory when replaying journals.\n"));
+			return FSCK_ERROR;
+		}
 		memcpy(bh_ip->b_data, bh_log->b_data, sdp->bsize);
 
 		/* Unescape */
@@ -357,6 +365,7 @@ static int fix_journal_seq_no(struct gfs2_inode *ip)
 	uint32_t extlen;
 	struct gfs2_buffer_head *bh;
 
+	memset(&lh, 0, sizeof(lh));
 	for (blk = 0; blk < jd_blocks; blk++) {
 		error = get_log_header(ip, blk, &lh);
 		if (error == 1) /* if not a log header */
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index 6a92992..28fe03d 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -352,6 +352,7 @@ static int rebuild_master(struct gfs2_sbd *sdp)
 {
 	struct gfs2_inum inum;
 	struct gfs2_buffer_head *bh;
+	int err = 0;
 
 	log_err(_("The system master directory seems to be destroyed.\n"));
 	if (!query(_("Okay to rebuild it? (y/n)"))) {
@@ -368,59 +369,109 @@ static int rebuild_master(struct gfs2_sbd *sdp)
 	if (fix_md.jiinode) {
 		inum.no_formal_ino = sdp->md.next_inum++;
 		inum.no_addr = fix_md.jiinode->i_di.di_num.no_addr;
-		dir_add(sdp->master_dir, "jindex", 6, &inum,
-			IF2DT(S_IFDIR | 0700));
+		err = dir_add(sdp->master_dir, "jindex", 6, &inum,
+		              IF2DT(S_IFDIR | 0700));
+		if (err) {
+			log_crit(_("Error %d adding jindex directory\n"), errno);
+			exit(FSCK_ERROR);
+		}
 		sdp->master_dir->i_di.di_nlink++;
 	} else {
-		build_jindex(sdp);
+		err = build_jindex(sdp);
+		if (err) {
+			log_crit(_("Error %d building jindex\n"), err);
+			exit(FSCK_ERROR);
+		}
 	}
 
 	if (fix_md.pinode) {
 		inum.no_formal_ino = sdp->md.next_inum++;
 		inum.no_addr = fix_md.pinode->i_di.di_num.no_addr;
-		dir_add(sdp->master_dir, "per_node", 8, &inum,
+		err = dir_add(sdp->master_dir, "per_node", 8, &inum,
 			IF2DT(S_IFDIR | 0700));
+		if (err) {
+			log_crit(_("Error %d adding per_node directory\n"),
+				 errno);
+			exit(FSCK_ERROR);
+		}
 		sdp->master_dir->i_di.di_nlink++;
 	} else {
-		build_per_node(sdp);
+		err = build_per_node(sdp);
+		if (err) {
+			log_crit(_("Error %d building per_node directory\n"),
+			         err);
+			exit(FSCK_ERROR);
+		}
 	}
 
 	if (fix_md.inum) {
 		inum.no_formal_ino = sdp->md.next_inum++;
 		inum.no_addr = fix_md.inum->i_di.di_num.no_addr;
-		dir_add(sdp->master_dir, "inum", 4, &inum,
+		err = dir_add(sdp->master_dir, "inum", 4, &inum,
 			IF2DT(S_IFREG | 0600));
+		if (err) {
+			log_crit(_("Error %d adding inum inode\n"), errno);
+			exit(FSCK_ERROR);
+		}
 	} else {
-		build_inum(sdp);
+		err = build_inum(sdp);
+		if (err) {
+			log_crit(_("Error %d building inum inode\n"), err);
+			exit(FSCK_ERROR);
+		}
 		gfs2_lookupi(sdp->master_dir, "inum", 4, &sdp->md.inum);
 	}
 
 	if (fix_md.statfs) {
 		inum.no_formal_ino = sdp->md.next_inum++;
 		inum.no_addr = fix_md.statfs->i_di.di_num.no_addr;
-		dir_add(sdp->master_dir, "statfs", 6, &inum,
-			IF2DT(S_IFREG | 0600));
+		err = dir_add(sdp->master_dir, "statfs", 6, &inum,
+			      IF2DT(S_IFREG | 0600));
+		if (err) {
+			log_crit(_("Error %d adding statfs inode\n"), errno);
+			exit(FSCK_ERROR);
+		}
 	} else {
-		build_statfs(sdp);
+		err = build_statfs(sdp);
+		if (err) {
+			log_crit(_("Error %d building statfs inode\n"), err);
+			exit(FSCK_ERROR);
+		}
 		gfs2_lookupi(sdp->master_dir, "statfs", 6, &sdp->md.statfs);
 	}
 
 	if (fix_md.riinode) {
 		inum.no_formal_ino = sdp->md.next_inum++;
 		inum.no_addr = fix_md.riinode->i_di.di_num.no_addr;
-		dir_add(sdp->master_dir, "rindex", 6, &inum,
+		err = dir_add(sdp->master_dir, "rindex", 6, &inum,
 			IF2DT(S_IFREG | 0600));
+		if (err) {
+			log_crit(_("Error %d adding rindex inode\n"), errno);
+			exit(FSCK_ERROR);
+		}
 	} else {
-		build_rindex(sdp);
+		err = build_rindex(sdp);
+		if (err) {
+			log_crit(_("Error %d building rindex inode\n"), err);
+			exit(FSCK_ERROR);
+		}
 	}
 
 	if (fix_md.qinode) {
 		inum.no_formal_ino = sdp->md.next_inum++;
 		inum.no_addr = fix_md.qinode->i_di.di_num.no_addr;
-		dir_add(sdp->master_dir, "quota", 5, &inum,
+		err = dir_add(sdp->master_dir, "quota", 5, &inum,
 			IF2DT(S_IFREG | 0600));
+		if (err) {
+			log_crit(_("Error %d adding quota inode\n"), errno);
+			exit(FSCK_ERROR);
+		}
 	} else {
-		build_quota(sdp);
+		err = build_quota(sdp);
+		if (err) {
+			log_crit(_("Error %d building quota inode\n"), err);
+			exit(FSCK_ERROR);
+		}
 	}
 
 	log_err(_("Master directory rebuilt.\n"));
@@ -590,8 +641,13 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
 			}
 		}
 		/* Read inum entry into buffer */
-		gfs2_readi(sdp->md.inum, &inumbuf, 0,
-			   sdp->md.inum->i_di.di_size);
+		err = gfs2_readi(sdp->md.inum, &inumbuf, 0,
+				 sdp->md.inum->i_di.di_size);
+		if (err != sdp->md.inum->i_di.di_size) {
+			log_crit(_("Error %d reading system inum inode. "
+				   "Aborting.\n"), err);
+			goto fail;
+		}
 		/* call gfs2_inum_range_in() to retrieve range */
 		sdp->md.next_inum = be64_to_cpu(inumbuf);
 	}
@@ -624,8 +680,14 @@ static int init_system_inodes(struct gfs2_sbd *sdp)
 	if (sdp->md.statfs->i_di.di_size) {
 		buf = malloc(sdp->md.statfs->i_di.di_size);
 		if (buf) {
-			gfs2_readi(sdp->md.statfs, buf, 0,
-				   sdp->md.statfs->i_di.di_size);
+			err = gfs2_readi(sdp->md.statfs, buf, 0,
+					 sdp->md.statfs->i_di.di_size);
+			if (err != sdp->md.statfs->i_di.di_size) {
+				log_crit(_("Error %d reading statfs file. "
+					   "Aborting.\n"), err);
+				free(buf);
+				goto fail;
+			}
 			/* call gfs2_inum_range_in() to retrieve range */
 			gfs2_statfs_change_in(&sc, buf);
 			free(buf);
@@ -1251,14 +1313,17 @@ static int reconstruct_single_journal(struct gfs2_sbd *sdp, int jnum,
  */
 static int reconstruct_journals(struct gfs2_sbd *sdp)
 {
-	int i;
+	int i, count;
 	struct gfs_jindex ji;
 	char buf[sizeof(struct gfs_jindex)];
 
 	log_err("Clearing GFS journals (this may take a while)\n");
 	for (i = 0; i < sdp->md.journals; i++) {
-		gfs2_readi(sdp->md.jiinode, buf, i * sizeof(struct gfs_jindex),
-			   sizeof(struct gfs_jindex));
+		count = gfs2_readi(sdp->md.jiinode, buf,
+				   i * sizeof(struct gfs_jindex),
+				   sizeof(struct gfs_jindex));
+		if (count != sizeof(struct gfs_jindex))
+			return 0;
 		gfs_jindex_in(&ji, buf);
 		if ((i % 2) == 0)
 			log_err(".");
diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index 70a9181..6f09de1 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -19,6 +19,7 @@ static void add_dotdot(struct gfs2_inode *ip)
 {
 	struct dir_info *di;
 	struct gfs2_sbd *sdp = ip->i_sbd;
+	int err;
 
 	log_info( _("Adding .. entry to directory %llu (0x%llx) pointing back "
 		    "to lost+found\n"),
@@ -75,8 +76,13 @@ static void add_dotdot(struct gfs2_inode *ip)
 		log_warn( _("add_inode_to_lf:  Unable to remove "
 			    "\"..\" directory entry.\n"));
 
-	dir_add(ip, "..", 2, &(lf_dip->i_di.di_num),
-		(sdp->gfs1 ? GFS_FILE_DIR : DT_DIR));
+	err = dir_add(ip, "..", 2, &(lf_dip->i_di.di_num),
+		      (sdp->gfs1 ? GFS_FILE_DIR : DT_DIR));
+	if (err) {
+		log_crit(_("Error adding .. directory: %s\n"),
+			 strerror(errno));
+		exit(FSCK_ERROR);
+	}
 }
 
 static uint64_t find_free_blk(struct gfs2_sbd *sdp)
@@ -133,6 +139,7 @@ int add_inode_to_lf(struct gfs2_inode *ip){
 	uint64_t lf_blocks;
 	struct gfs2_sbd *sdp = ip->i_sbd;
 	struct dir_info *di;
+	int err = 0;
 	uint32_t mode;
 
 	if (!lf_dip) {
@@ -255,8 +262,13 @@ int add_inode_to_lf(struct gfs2_inode *ip){
 		break;
 	}
 
-	dir_add(lf_dip, tmp_name, strlen(tmp_name), &(ip->i_di.di_num),
+	err = dir_add(lf_dip, tmp_name, strlen(tmp_name), &(ip->i_di.di_num),
 		inode_type);
+	if (err) {
+		log_crit(_("Error adding directory %s: %s\n"),
+			 tmp_name, strerror(errno));
+		exit(FSCK_ERROR);
+	}
 	/* If the lf directory had new blocks added we have to mark them
 	   properly in the bitmap so they're not freed. */
 	if (lf_dip->i_di.di_blocks != lf_blocks)
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index b3ef7d4..52d4082 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -1326,7 +1326,7 @@ static int check_system_inode(struct gfs2_sbd *sdp,
 {
 	uint64_t iblock = 0;
 	struct dir_status ds = {0};
-	int error;
+	int error, err = 0;
 
 	log_info( _("Checking system inode '%s'\n"), filename);
 	if (*sysinode) {
@@ -1400,12 +1400,19 @@ static int check_system_inode(struct gfs2_sbd *sdp,
 		sysdir_fxns.private = &bc;
 		if ((*sysinode)->i_di.di_flags & GFS2_DIF_EXHASH)
 			check_metatree(*sysinode, &sysdir_fxns);
-		else
-			check_linear_dir(*sysinode, (*sysinode)->i_bh,
-					 &sysdir_fxns);
+		else {
+			err = check_linear_dir(*sysinode, (*sysinode)->i_bh,
+					       &sysdir_fxns);
+			/* If we encountered an error in our directory check
+			   we should still call handle_ip, but return the
+			   error later. */
+			if (err)
+				log_err(_("Error found in %s while checking "
+					  "directory entries.\n"), filename);
+		}
 	}
 	error = handle_ip(sdp, *sysinode);
-	return error;
+	return error ? error : err;
 }
 
 static int build_a_journal(struct gfs2_sbd *sdp)
@@ -1537,7 +1544,7 @@ int pass1(struct gfs2_sbd *sdp)
 {
 	struct osi_node *n, *next = NULL;
 	struct gfs2_buffer_head *bh;
-	uint64_t block;
+	uint64_t block = 0;
 	struct rgrp_tree *rgd;
 	int first;
 	uint64_t i;
diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
index be0e5fe..c772be3 100644
--- a/gfs2/fsck/pass2.c
+++ b/gfs2/fsck/pass2.c
@@ -667,10 +667,15 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
 			}
 			memcpy(filename, tmp_name, filename_len);
 			log_warn( _("Adding '.' entry\n"));
-			dir_add(sysinode, filename, filename_len,
-				&(sysinode->i_di.di_num),
-				(sysinode->i_sbd->gfs1 ?
-				 GFS_FILE_DIR : DT_DIR));
+			error = dir_add(sysinode, filename, filename_len,
+					&(sysinode->i_di.di_num),
+					(sysinode->i_sbd->gfs1 ?
+					 GFS_FILE_DIR : DT_DIR));
+			if (error) {
+				log_err(_("Error adding directory %s: %s\n"),
+				        filename, strerror(errno));
+				return -errno;
+			}
 			if (cur_blks != sysinode->i_di.di_blocks)
 				reprocess_inode(sysinode, dirname);
 			/* This system inode is linked to itself via '.' */
@@ -881,9 +886,15 @@ int pass2(struct gfs2_sbd *sdp)
 				memcpy(filename, tmp_name, filename_len);
 
 				cur_blks = ip->i_di.di_blocks;
-				dir_add(ip, filename, filename_len,
-					&(ip->i_di.di_num),
-					(sdp->gfs1 ? GFS_FILE_DIR : DT_DIR));
+				error = dir_add(ip, filename, filename_len,
+						&(ip->i_di.di_num),
+						(sdp->gfs1 ? GFS_FILE_DIR :
+						 DT_DIR));
+				if (error) {
+					log_err(_("Error adding directory %s: %s\n"),
+					        filename, strerror(errno));
+					return -errno;
+				}
 				if (cur_blks != ip->i_di.di_blocks) {
 					char dirname[80];
 
diff --git a/gfs2/fsck/pass3.c b/gfs2/fsck/pass3.c
index e1accc9..daa1809 100644
--- a/gfs2/fsck/pass3.c
+++ b/gfs2/fsck/pass3.c
@@ -18,7 +18,7 @@ static int attach_dotdot_to(struct gfs2_sbd *sdp, uint64_t newdotdot,
 			    uint64_t olddotdot, uint64_t block)
 {
 	char *filename;
-	int filename_len;
+	int filename_len, err;
 	struct gfs2_inode *ip, *pip;
 	uint64_t cur_blks;
 
@@ -52,8 +52,13 @@ static int attach_dotdot_to(struct gfs2_sbd *sdp, uint64_t newdotdot,
 	else
 		decr_link_count(olddotdot, block, _("old \"..\""));
 	cur_blks = ip->i_di.di_blocks;
-	dir_add(ip, filename, filename_len, &pip->i_di.di_num,
-		(sdp->gfs1 ? GFS_FILE_DIR : DT_DIR));
+	err = dir_add(ip, filename, filename_len, &pip->i_di.di_num,
+		      (sdp->gfs1 ? GFS_FILE_DIR : DT_DIR));
+	if (err) {
+		log_err(_("Error adding directory %s: %s\n"),
+		        filename, strerror(errno));
+		exit(FSCK_ERROR);
+	}
 	if (cur_blks != ip->i_di.di_blocks) {
 		char dirname[80];
 
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index ea033a0..2540b17 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -104,7 +104,8 @@ static int check_block_status(struct gfs2_sbd *sdp, char *buffer,
 {
 	unsigned char *byte, *end;
 	unsigned int bit;
-	unsigned char rg_status, block_status;
+	unsigned char rg_status;
+	int block_status;
 	uint8_t q;
 	uint64_t block;
 
@@ -119,6 +120,7 @@ static int check_block_status(struct gfs2_sbd *sdp, char *buffer,
 		warm_fuzzy_stuff(block);
 		if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
 			return 0;
+
 		q = block_type(block);
 
 		if (sdp->gfs1)
@@ -126,6 +128,12 @@ static int check_block_status(struct gfs2_sbd *sdp, char *buffer,
 		else
 			block_status = gfs2_convert_mark(q, count);
 
+		if (block_status < 0) {
+			log_err( _("Invalid status for block %llu (0x%llx).\n"),
+				 (unsigned long long)block,
+				 (unsigned long long)block);
+			return block_status;
+		}
 		/* If one node opens a file and another node deletes it, we
 		   may be left with a block that appears to be "unlinked" in
 		   the bitmap, but nothing links to it. This is a valid case
@@ -204,9 +212,10 @@ static void update_rgrp(struct gfs2_sbd *sdp, struct rgrp_tree *rgp,
 		bits = &rgp->bits[i];
 
 		/* update the bitmaps */
-		check_block_status(sdp, rgp->bh[i]->b_data + bits->bi_offset,
-				   bits->bi_len, &rg_block, rgp->ri.ri_data0,
-				   count);
+		if (check_block_status(sdp, rgp->bh[i]->b_data +
+				       bits->bi_offset, bits->bi_len,
+				       &rg_block, rgp->ri.ri_data0, count))
+			return;
 		if (skip_this_pass || fsck_abort) /* if asked to skip the rest */
 			return;
 	}
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index 5053c90..4f1774c 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -723,6 +723,11 @@ int gfs2_dirent_next(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
 	return 0;
 }
 
+/**
+ * Allocate a gfs2 dirent
+ * Returns 0 on success, with *dent_out pointing to the new dirent,
+ * or -1 on failure, with errno set
+ */
 static int dirent_alloc(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
 			int name_len, struct gfs2_dirent **dent_out)
 {
@@ -793,7 +798,8 @@ static int dirent_alloc(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
 		}
 	} while (gfs2_dirent_next(dip, bh, &dent) == 0);
 
-	return -ENOSPC;
+	errno = ENOSPC;
+	return -1;
 }
 
 void dirent2_del(struct gfs2_inode *dip, struct gfs2_buffer_head *bh,
@@ -1032,8 +1038,6 @@ int gfs2_get_leaf(struct gfs2_inode *dip, uint64_t leaf_no,
 	int error = 0;
 
 	*bhp = bread(dip->i_sbd, leaf_no);
-	if (error)
-		return error;
 	error = gfs2_check_meta(*bhp, GFS2_METATYPE_LF);
 	if(error)
 		brelse(*bhp);
@@ -1081,7 +1085,7 @@ static int get_next_leaf(struct gfs2_inode *dip,struct gfs2_buffer_head *bh_in,
 	return 0;
 }
 
-static void dir_e_add(struct gfs2_inode *dip, const char *filename, int len,
+static int dir_e_add(struct gfs2_inode *dip, const char *filename, int len,
 		      struct gfs2_inum *inum, unsigned int type)
 {
 	struct gfs2_buffer_head *bh, *nbh;
@@ -1090,6 +1094,7 @@ static void dir_e_add(struct gfs2_inode *dip, const char *filename, int len,
 	uint32_t lindex;
 	uint32_t hash;
 	uint64_t leaf_no, bn;
+	int err = 0;
 
 	hash = gfs2_disk_hash(filename, len);
 restart:
@@ -1138,8 +1143,9 @@ restart:
 				nleaf->lf_depth = leaf->lf_depth;
 				nleaf->lf_dirent_format = cpu_to_be32(GFS2_FORMAT_DE);
 
-				if (dirent_alloc(dip, nbh, len, &dent))
-					die("dir_split_leaf (3)\n");
+				err = dirent_alloc(dip, nbh, len, &dent);
+				if (err)
+					return err;
 				dip->i_di.di_blocks++;
 				bmodified(dip->i_bh);
 				bmodified(bh);
@@ -1159,7 +1165,7 @@ restart:
 
 		bmodified(bh);
 		brelse(bh);
-		return;
+		return err;
 	}
 }
 
@@ -1227,15 +1233,16 @@ static void dir_make_exhash(struct gfs2_inode *dip)
 	bwrite(dip->i_bh);
 }
 
-static void dir_l_add(struct gfs2_inode *dip, const char *filename, int len,
+static int dir_l_add(struct gfs2_inode *dip, const char *filename, int len,
 		      struct gfs2_inum *inum, unsigned int type)
 {
 	struct gfs2_dirent *dent;
+	int err = 0;
 
 	if (dirent_alloc(dip, dip->i_bh, len, &dent)) {
 		dir_make_exhash(dip);
-		dir_e_add(dip, filename, len, inum, type);
-		return;
+		err = dir_e_add(dip, filename, len, inum, type);
+		return err;
 	}
 
 	gfs2_inum_out(inum, (char *)&dent->de_inum);
@@ -1244,15 +1251,18 @@ static void dir_l_add(struct gfs2_inode *dip, const char *filename, int len,
 	dent->de_type = cpu_to_be16(type);
 	memcpy((char *)(dent + 1), filename, len);
 	bmodified(dip->i_bh);
+	return err;
 }
 
-void dir_add(struct gfs2_inode *dip, const char *filename, int len,
+int dir_add(struct gfs2_inode *dip, const char *filename, int len,
 	     struct gfs2_inum *inum, unsigned int type)
 {
+	int err = 0;
 	if (dip->i_di.di_flags & GFS2_DIF_EXHASH)
-		dir_e_add(dip, filename, len, inum, type);
+		err = dir_e_add(dip, filename, len, inum, type);
 	else
-		dir_l_add(dip, filename, len, inum, type);
+		err = dir_l_add(dip, filename, len, inum, type);
+	return err;
 }
 
 static struct gfs2_buffer_head *__init_dinode(struct gfs2_sbd *sdp,
@@ -1350,6 +1360,7 @@ static struct gfs2_inode *__createi(struct gfs2_inode *dip,
 	struct gfs2_inum inum;
 	struct gfs2_buffer_head *bh;
 	struct gfs2_inode *ip;
+	int err = 0;
 	int is_dir;
 
 	gfs2_lookupi(dip, filename, strlen(filename), &ip);
@@ -1362,7 +1373,9 @@ static struct gfs2_inode *__createi(struct gfs2_inode *dip,
 			inum.no_formal_ino = sdp->md.next_inum++;
 		inum.no_addr = bn;
 
-		dir_add(dip, filename, strlen(filename), &inum, IF2DT(mode));
+		err = dir_add(dip, filename, strlen(filename), &inum, IF2DT(mode));
+		if (err)
+			return NULL;
 
 		if (if_gfs1)
 			is_dir = (IF2DT(mode) == GFS_FILE_DIR);
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index bb47580..f60654c 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -385,7 +385,7 @@ extern int dir_search(struct gfs2_inode *dip, const char *filename, int len,
 		      unsigned int *type, struct gfs2_inum *inum);
 extern int gfs2_lookupi(struct gfs2_inode *dip, const char *filename, int len,
 			struct gfs2_inode **ipp);
-extern void dir_add(struct gfs2_inode *dip, const char *filename, int len,
+extern int dir_add(struct gfs2_inode *dip, const char *filename, int len,
 		    struct gfs2_inum *inum, unsigned int type);
 extern int gfs2_dirent_del(struct gfs2_inode *dip, const char *filename,
 			   int filename_len);
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

* [Cluster-devel] [PATCH 66/66] libgfs2: Fix null pointer dereference in linked_leaf_search
  2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
                   ` (64 preceding siblings ...)
  2012-01-20 15:10 ` [Cluster-devel] [PATCH 65/66] fsck.gfs2: Add return code checks and initializations rpeterso
@ 2012-01-20 15:10 ` rpeterso
  65 siblings, 0 replies; 67+ messages in thread
From: rpeterso @ 2012-01-20 15:10 UTC (permalink / raw)
  To: cluster-devel.redhat.com

From: Bob Peterson <rpeterso@redhat.com>

Fix a null pointer dereference by checking the value of the bh set by
get_first_leaf(). Looking down the call tree the bh is set to NULL when
__bread fails to allocate memory so we can use errno as the return value
here.

rhbz#675723
---
 gfs2/fsck/lost_n_found.c |    3 +--
 gfs2/libgfs2/fs_ops.c    |    2 ++
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/gfs2/fsck/lost_n_found.c b/gfs2/fsck/lost_n_found.c
index 6f09de1..d0e036a 100644
--- a/gfs2/fsck/lost_n_found.c
+++ b/gfs2/fsck/lost_n_found.c
@@ -160,8 +160,7 @@ int add_inode_to_lf(struct gfs2_inode *ip){
 			lf_dip = createi(sdp->md.rooti, "lost+found",
 					 S_IFDIR | 0700, 0);
 		if (lf_dip == NULL) {
-			log_crit(_("Error %d creating lost+found: %s\n"),
-				 errno);
+			log_crit(_("Error %d creating lost+found\n"), errno);
 			exit(FSCK_ERROR);
 		}
 
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index 4f1774c..330cedd 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -1514,6 +1514,8 @@ static int linked_leaf_search(struct gfs2_inode *dip, const char *filename,
 	error = get_first_leaf(dip, lindex, &bh_next);
 	if (error)
 		return error;
+	if (bh_next == NULL)
+		return errno;
 
 	/*  Find the entry  */
 	do{
-- 
1.7.7.5



^ permalink raw reply related	[flat|nested] 67+ messages in thread

end of thread, other threads:[~2012-01-20 15:10 UTC | newest]

Thread overview: 67+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-01-20 15:09 [Cluster-devel] [PATCH 00/66] fsck.gfs2: add ability to fix GFS (gfs1) file systems rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 01/66] fsck.gfs2: Make functions use sdp rather than sbp rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 02/66] fsck.gfs2: Change "if(" to "if (" rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 03/66] libgfs1: Add gfs1 variable to superblock structure rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 04/66] libgfs2: Make check_sb and read_sb operate on gfs1 rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 05/66] libgfs2: move gfs1 structures to libgfs2 rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 06/66] fsck.gfs2: Check for blocks wrongly inside resource groups rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 07/66] fsck.gfs2: Rename check_leaf to check_ealeaf_block rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 08/66] fsck.gfs2: fsck.gfs2: Delete vestigial buffer_head in check_leaf rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 09/66] fsck.gfs2: fsck.gfs2: Rename nlink functions to be intuitive rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 10/66] fsck.gfs2: fsck.gfs2: Sync di_nlink adding links for lost+found rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 11/66] fsck.gfs2: fsck.gfs2: Make dir entry count 32 bits rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 12/66] fsck.gfs2: get rid of triple negative logic rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 13/66] dirent_repair needs to mark the buffer as modified rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 14/66] fsck.gfs2: fsck.gfs2: Ask to reclaim unlinked meta per-rgrp only rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 15/66] fsck.gfs2: fsck.gfs2: Refactor add_dotdot function in lost+found rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 16/66] libgfs2: libgfs2: Use __FUNCTION__ rather than __FILE__ rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 17/66] fsck.gfs2: fsck.gfs2: Don't stop invalidating blocks on invalid rpeterso
2012-01-20 15:09 ` [Cluster-devel] [PATCH 18/66] fsck.gfs2: fsck.gfs2: Find and clear duplicate leaf blocks refs rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 19/66] fsck.gfs2: fsck.gfs2: Move check_num_ptrs from metawalk to pass1 rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 20/66] fsck.gfs2: fsck.gfs2: Duplicate ref processing for leaf blocks rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 21/66] fsck.gfs2: fsck.gfs2: split check_leaf_blks to be more readable rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 22/66] fsck.gfs2: Shorten output rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 23/66] fsck.gfs2: Make output messages more sensible rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 24/66] fsck.gfs pass2: Refactor function set_dotdot_dir rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 25/66] fsck.gfs2 pass2: Delete extended attributes with inode rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 26/66] fsck.gfs2 pass2: Don't delete invalid inode metadata rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 27/66] fsck.gfs2 pass3: Refactor mark_and_return_parent rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 28/66] fsck.gfs2: misc cosmetic changes rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 29/66] fsck.gfs2: Don't use old_leaf if it was a duplicate rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 30/66] fsck.gfs2: Add find_remove_dup, free_block_if_notdup rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 31/66] fsck.gfs2: don't free prev rgrp list repairing rgrps rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 32/66] libgfs2: eliminate gfs1_readi in favor of gfs2_readi rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 33/66] libgfs2: Mark buffer modified adding a new GFS1 block rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 34/66] libgfs2: Use dinode buffer to map gfs1 dinode blocks rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 35/66] libgfs2: move block_map functions to fsck.gfs2 rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 36/66] libgfs2: eliminate gfs1_rindex_read rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 37/66] libgfs2: combine ri_update and gfs1_ri_update rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 38/66] libgfs2: combine gfs_inode_read and gfs_inode_get rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 39/66] libgfs2: move gfs1 functions from edit to libgfs2 rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 40/66] gfs2_edit savemeta: save_inode_data backward for gfs1 rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 41/66] libgfs2: expand capabilities to operate on gfs1 rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 42/66] fsck.gfs2: Combine block and char device inode types rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 43/66] fsck.gfs2: four-step duplicate elimination process rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 44/66] fsck.gfs2: Add ability to check gfs1 file systems rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 45/66] fsck.gfs2: Remove bad inodes from duplicate tree rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 46/66] fsck.gfs2: Handle duplicate reference to dinode blocks rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 47/66] fsck.gfs2: Bad extended attributes not deleted properly rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 48/66] libgfs2: Make rebuild functions not re-read ip rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 49/66] fsck.gfs2: Shorten debug output rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 50/66] fsck.gfs2: Increment link count reporting wrong dinode rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 51/66] fsck.gfs2: system dinodes take priority over user dinodes rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 52/66] fsck.gfs2: Recognize partially gfs2-converted dinodes rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 53/66] fsck.gfs2: Print step 2 duplicate debug msg first rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 54/66] fsck.gfs2: pass1c counts percentage backward rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 55/66] fsck.gfs2: Speed up rangecheck functions rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 56/66] libgfs2: Make in-core rgrps use rbtree rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 57/66] fsck.gfs2: Fix memory leaks rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 58/66] Change man pages and gfs2_convert messages to include GFS rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 59/66] gfs2_edit: Fix memory leaks rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 60/66] fsck.gfs2: Journals not properly checked rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 61/66] fsck.gfs2: Rearrange block types to group all inode types rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 62/66] fsck.gfs2: Fix initialization error return codes rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 63/66] fsck.gfs2: Don't use strerror for libgfs2 errors rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 64/66] fsck.gfs2: Fix memory leak in initialize.c rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 65/66] fsck.gfs2: Add return code checks and initializations rpeterso
2012-01-20 15:10 ` [Cluster-devel] [PATCH 66/66] libgfs2: Fix null pointer dereference in linked_leaf_search rpeterso

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).