Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 9383e745e23602bc45f9c92184feea59 > files > 23

gfs2-utils-0.1.62-28.el5.src.rpm

commit 4fbd5fa224b6dbcf0998c4cb352a92c4b49f6cdc
Author: Bob Peterson <bob@ganesha.peterson>
Date:   Wed Nov 25 14:31:51 2009 -0600

    Remove nvbuf_list and use fewer buffers
    
    This preliminary patch is a starting point for disentangling the
    issues fsck has with libgfs2/buf.c.  Rather than read in all the
    rgrp bitmaps into memory, all in a non-volatile linked list, this
    patch keeps the same linked list of rgrps, but only reads in the
    bitmaps on an as-needed basis, and only for short-term.  This is
    also an attempt to eliminate the fairly new non-volatile linked
    buffer list and change all the code in gfs2-utils so that they
    should not depend on the list being non-volatile.  The whole
    non-volatile thing was a stop-gap temporary solution so that we
    could minimize the possibility of regression.  In addition to
    getting rid of the non-volatile linked list, it also reduces the
    remaining linked list of buffers from 128MB to 1MB so that much
    fewer buffers will be kept in memory.  That could drive a lot of
    bugs out of their hiding places.
    
    rhbz#455300

diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 48b4087..028913b 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -167,34 +167,29 @@ void print_it(const char *label, const char *fmt, const char *fmt2, ...)
 /*                   valid in gfs1 but invalid in gfs2).                     */
 /* ------------------------------------------------------------------------- */
 static void convert_bitmaps(struct gfs2_sbd *sdp, struct rgrp_list *rgd2,
-					 int read_disk)
+			    struct gfs2_buffer_head **rgbh)
 {
 	uint32_t blk;
 	int x, y;
 	struct gfs2_rindex *ri;
 	unsigned char state;
-	struct gfs2_buffer_head *bh;
 
 	ri = &rgd2->ri;
-	if (gfs2_compute_bitstructs(sdp, rgd2)) { /* mallocs bh as array */
+	if (gfs2_compute_bitstructs(sdp, rgd2)) {
 		log_crit("gfs2_convert: Error converting bitmaps.\n");
 		exit(-1);
 	}
 	for (blk = 0; blk < ri->ri_length; blk++) {
-		bh = bget_generic(&sdp->nvbuf_list, ri->ri_addr + blk,
-				  read_disk, read_disk);
-		if (!rgd2->bh[blk])
-			rgd2->bh[blk] = bh;
-		x = (blk) ? sizeof(struct gfs2_meta_header) : sizeof(struct gfs2_rgrp);
+		x = (blk) ? sizeof(struct gfs2_meta_header) :
+			sizeof(struct gfs2_rgrp);
 
 		for (; x < sdp->bsize; x++)
 			for (y = 0; y < GFS2_NBBY; y++) {
-				state = (rgd2->bh[blk]->b_data[x] >>
-						 (GFS2_BIT_SIZE * y)) & 0x03;
+				state = (rgbh[blk]->b_data[x] >>
+					 (GFS2_BIT_SIZE * y)) & 0x03;
 				if (state == 0x02) /* unallocated metadata state invalid */
-					rgd2->bh[blk]->b_data[x] &= ~(0x02 << (GFS2_BIT_SIZE * y));
+					rgbh[blk]->b_data[x] &= ~(0x02 << (GFS2_BIT_SIZE * y));
 			}
-		brelse(bh, updated);
 	}
 }/* convert_bitmaps */
 
@@ -205,38 +200,49 @@ static void convert_bitmaps(struct gfs2_sbd *sdp, struct rgrp_list *rgd2,
 static int convert_rgs(struct gfs2_sbd *sbp)
 {
 	struct rgrp_list *rgd;
+	struct gfs2_rgrp rg;
 	osi_list_t *tmp;
-	struct gfs2_buffer_head *bh;
 	struct gfs1_rgrp *rgd1;
 	int rgs = 0;
+	struct gfs2_buffer_head **rgbh;
 
 	/* --------------------------------- */
 	/* Now convert its rgs into gfs2 rgs */
 	/* --------------------------------- */
 	osi_list_foreach(tmp, &sbp->rglist) {
 		rgd = osi_list_entry(tmp, struct rgrp_list, list);
-		rgd1 = (struct gfs1_rgrp *)&rgd->rg; /* recast as gfs1 structure */
+		if(!(rgbh = (struct gfs2_buffer_head **)
+		     malloc(rgd->ri.ri_length *
+			    sizeof(struct gfs2_buffer_head *))))
+			return -1;
+		if(!memset(rgbh, 0, rgd->ri.ri_length *
+			   sizeof(struct gfs2_buffer_head *))) {
+			free(rgbh);
+			return -1;
+		}
+
+		gfs2_rgrp_read(sbp, rgd, rgbh, &rg);
+		rgd1 = (struct gfs1_rgrp *)&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. */
-		rgd->rg.rg_free = rgd1->rg_free + be32_to_cpu(rgd1->rg_freemeta);
+		rg.rg_free = rgd1->rg_free + be32_to_cpu(rgd1->rg_freemeta);
+		rgd->rg_free = rg.rg_free;
 		/* Zero it out so we don't add it again in case something breaks */
 		/* later on in the process and we have to re-run convert */
 		rgd1->rg_freemeta = 0;
 
 		sbp->blks_total += rgd->ri.ri_data;
-		sbp->blks_alloced += (rgd->ri.ri_data - rgd->rg.rg_free);
+		sbp->blks_alloced += (rgd->ri.ri_data - rg.rg_free);
 		sbp->dinodes_alloced += rgd1->rg_useddi;
-		convert_bitmaps(sbp, rgd, TRUE);
+		convert_bitmaps(sbp, rgd, rgbh);
 		/* Write the updated rgrp to the gfs2 buffer */
-		bh = bget(&sbp->nvbuf_list,
-			  rgd->ri.ri_addr); /* get a gfs2 buffer for the rg */
-		gfs2_rgrp_out(&rgd->rg, rgd->bh[0]->b_data);
-		brelse(bh, updated); /* release the buffer */
+		gfs2_rgrp_out(&rg, rgbh[0]->b_data);
 		rgs++;
 		if (rgs % 100 == 0) {
 			printf(".");
 			fflush(stdout);
 		}
+		free(rgbh);
 	}
 	return 0;
 }/* superblock_cvt */
@@ -983,6 +989,8 @@ static int inode_renumber(struct gfs2_sbd *sbp, uint64_t root_inode_addr)
 	int first;
 	int error = 0;
 	int rgs_processed = 0;
+	struct gfs2_buffer_head **rgbh;
+	struct gfs2_rgrp rg;
 
 	log_notice("Converting inodes.\n");
 	sbp->md.next_inum = 1; /* starting inode numbering */
@@ -996,8 +1004,18 @@ static int inode_renumber(struct gfs2_sbd *sbp, uint64_t root_inode_addr)
 		rgs_processed++;
 		rgd = osi_list_entry(tmp, struct rgrp_list, list);
 		first = 1;
-		if (gfs2_rgrp_read(sbp, rgd)) {
+                if(!(rgbh = (struct gfs2_buffer_head **)
+                     malloc(rgd->ri.ri_length *
+                            sizeof(struct gfs2_buffer_head *))))
+                        return -1;
+                if(!memset(rgbh, 0, rgd->ri.ri_length *
+                           sizeof(struct gfs2_buffer_head *))) {
+			free(rgbh);
+                        return -1;
+		}
+		if (gfs2_rgrp_read(sbp, rgd, rgbh, &rg)) {
 			log_crit("Unable to read rgrp.\n");
+			free(rgbh);
 			return -1;
 		}
 		while (1) {    /* for all inodes in the resource group */
@@ -1042,9 +1060,9 @@ static int inode_renumber(struct gfs2_sbd *sbp, uint64_t root_inode_addr)
 						sizeof(struct gfs2_rgrp);
 					/* if it's on this page */
 					if (buf_offset + bitmap_byte < sbp->bsize) {
-						rgd->bh[blk]->b_data[buf_offset + bitmap_byte] &=
+						rgbh[blk]->b_data[buf_offset + bitmap_byte] &=
 							~(0x03 << (GFS2_BIT_SIZE * byte_bit));
-						rgd->bh[blk]->b_data[buf_offset + bitmap_byte] |=
+						rgbh[blk]->b_data[buf_offset + bitmap_byte] |=
 							(0x01 << (GFS2_BIT_SIZE * byte_bit));
 						break;
 					}
@@ -1054,7 +1072,8 @@ static int inode_renumber(struct gfs2_sbd *sbp, uint64_t root_inode_addr)
 			brelse(bh, updated);
 			first = 0;
 		} /* while 1 */
-		gfs2_rgrp_relse(rgd, updated);
+		gfs2_rgrp_relse(rgd, updated, rgbh);
+		free(rgbh);
 	} /* for all rgs */
 	log_notice("\r%" PRIu64" inodes from %d rgs converted.",
 		   sbp->md.next_inum, rgs_processed);
@@ -1379,8 +1398,7 @@ static int init(struct gfs2_sbd *sbp)
 	sbp->sd_sb.sb_bsize = GFS2_DEFAULT_BSIZE;
 	sbp->bsize = sbp->sd_sb.sb_bsize;
 	osi_list_init(&sbp->rglist);
-	init_buf_list(sbp, &sbp->buf_list, 128 << 20);
-	init_buf_list(sbp, &sbp->nvbuf_list, 0xffffffff);
+	init_buf_list(sbp, &sbp->buf_list, 1 << 20); /* only use 1MB of bufs */
 	compute_constants(sbp);
 
 	bh = bread(&sbp->buf_list, GFS2_SB_ADDR >> sbp->sd_fsb2bb_shift);
@@ -1596,6 +1614,8 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp)
 	struct rgrp_list *rgd, *rgdhigh;
 	osi_list_t *tmp;
 	struct gfs2_meta_header mh;
+	struct gfs2_rgrp rg;
+	struct gfs2_buffer_head **rgbh;
 
 	mh.mh_magic = GFS2_MAGIC;
 	mh.mh_type = GFS2_METATYPE_RB;
@@ -1606,12 +1626,12 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp)
 		uint64_t size;
 
 		jndx = &sd_jindex[j];
-		/* go through all rg index entries, keeping track of the highest */
-		/* that's still in the first subdevice.                          */
-		/* Note: we really should go through all of the rgindex because  */
-		/* we might have had rg's added by gfs_grow, and journals added  */
-		/* by jadd.  gfs_grow adds rgs out of order, so we can't count   */
-		/* on them being in ascending order.                             */
+		/* go through all rg index entries, keeping track of the
+		   highest that's still in the first subdevice.
+		   Note: we really should go through all of the rgindex because
+		   we might have had rg's added by gfs_grow, and journals added
+		   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);
@@ -1635,11 +1655,11 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp)
 		}
 		memset(rgd, 0, sizeof(struct rgrp_list));
 		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;
-		rgd->rg.rg_flags = 0;
-		rgd->rg.rg_dinodes = 0;
+		rg.rg_header.mh_magic = GFS2_MAGIC;
+		rg.rg_header.mh_type = GFS2_METATYPE_RG;
+		rg.rg_header.mh_format = GFS2_FORMAT_RG;
+		rg.rg_flags = 0;
+		rg.rg_dinodes = 0;
 
 		rgd->ri.ri_addr = jndx->ji_addr; /* new rg addr becomes ji addr */
 		rgd->ri.ri_length = rgrp_length(size, sdp); /* aka bitblocks */
@@ -1650,19 +1670,31 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp)
 		while (rgd->ri.ri_data & 0x03)
 			rgd->ri.ri_data--;
 		sdp->blks_total += rgd->ri.ri_data; /* For statfs file update */
-		rgd->rg.rg_free = rgd->ri.ri_data;
+		rg.rg_free = rgd->ri.ri_data;
 		rgd->ri.ri_bitbytes = rgd->ri.ri_data / GFS2_NBBY;
-		convert_bitmaps(sdp, rgd, FALSE); /* allocates rgd->bh */
+
+		if(!(rgbh = (struct gfs2_buffer_head **)
+		     malloc(rgd->ri.ri_length *
+			    sizeof(struct gfs2_buffer_head *))))
+			return -1;
+		if(!memset(rgbh, 0, rgd->ri.ri_length *
+			   sizeof(struct gfs2_buffer_head *))) {
+			free(rgbh);
+			return -1;
+		}
+
+		convert_bitmaps(sdp, rgd, rgbh);
 		for (x = 0; x < rgd->ri.ri_length; x++) {
-			rgd->bh[x]->b_count++;
+			rgbh[x]->b_count++;
 			if (x)
-				gfs2_meta_header_out(&mh, rgd->bh[x]->b_data);
+				gfs2_meta_header_out(&mh, rgbh[x]->b_data);
 			else
-				gfs2_rgrp_out(&rgd->rg, rgd->bh[x]->b_data);
+				gfs2_rgrp_out(&rg, rgbh[x]->b_data);
 		}
 		/* 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);
+		free(rgbh);
 	} /* for each journal */
 	return error;
 }/* journ_space_to_rg */
@@ -1803,7 +1835,7 @@ int main(int argc, char **argv)
 		if (error)
 			log_crit("%s: Unable to convert resource groups.\n",
 					device);
-		bcommit(&sb2.nvbuf_list); /* write the buffers to disk */
+		bcommit(&sb2.buf_list); /* write the buffers to disk */
 	}
 	/* ---------------------------------------------- */
 	/* Renumber the inodes consecutively.             */
@@ -1870,10 +1902,9 @@ int main(int argc, char **argv)
 		inode_put(sb2.md.statfs, updated);
 
 		bcommit(&sb2.buf_list); /* write the buffers to disk */
-		bcommit(&sb2.nvbuf_list); /* write the buffers to disk */
 
 		/* Now free all the in memory */
-		gfs2_rgrp_free(&sb2.rglist, updated);
+		gfs2_rgrp_free(&sb2.rglist);
 		log_notice("Committing changes to disk.\n");
 		fflush(stdout);
 		/* Set filesystem type in superblock to gfs2.  We do this at the */
@@ -1887,7 +1918,6 @@ int main(int argc, char **argv)
 		brelse(bh, updated);
 
 		bsync(&sb2.buf_list); /* write the buffers to disk */
-		bsync(&sb2.nvbuf_list); /* write the buffers to disk */
 		error = fsync(sb2.device_fd);
 		if (error)
 			perror(device);
diff --git a/gfs2/edit/hexedit.c b/gfs2/edit/hexedit.c
index 99b42bf..d6fb7fe 100644
--- a/gfs2/edit/hexedit.c
+++ b/gfs2/edit/hexedit.c
@@ -580,10 +580,9 @@ int display_block_type(const char *lpBuffer, int from_restore)
 		struct rgrp_list *rgd;
 
 		rgd = gfs2_blk2rgrpd(&sbd, block);
-		if (rgd) {
+		if (rgd)
 			type = gfs2_get_bitmap(&sbd, block, rgd);
-			gfs2_rgrp_relse(rgd, not_updated);
-		} else
+		else
 			type = 4;
 		screen_chunk_size = ((termlines - 4) * 16) >> 8 << 8;
 		if (!screen_chunk_size)
@@ -801,7 +800,7 @@ static void rgcount(void)
 	printf("%lld RGs in this file system.\n",
 	       (unsigned long long)sbd.md.riinode->i_di.di_size / risize());
 	inode_put(sbd.md.riinode, not_updated);
-	gfs2_rgrp_free(&sbd.rglist, not_updated);
+	gfs2_rgrp_free(&sbd.rglist);
 	exit(EXIT_SUCCESS);
 }
 
@@ -1004,7 +1003,7 @@ static int parse_rindex(struct gfs2_inode *dip, int print_rindex)
 			else {
 				struct gfs2_buffer_head *tmp_bh;
 
-				tmp_bh = bread(&sbd.nvbuf_list, ri.ri_addr);
+				tmp_bh = bread(&sbd.buf_list, ri.ri_addr);
 				if (gfs1) {
 					struct gfs_rgrp rg1;
 					gfs_rgrp_in(&rg1, tmp_bh->b_data);
@@ -1707,7 +1706,7 @@ static int display_extended(void)
 /* ------------------------------------------------------------------------ */
 static void read_superblock(int fd)
 {
-	int count;
+	int count, bitmap_blocks = 0;
 
 	sbd1 = (struct gfs_sb *)&sbd.sd_sb;
 	ioctl(fd, BLKFLSBUF, 0);
@@ -1726,8 +1725,7 @@ static void read_superblock(int fd)
 	sbd.qcsize = GFS2_DEFAULT_QCSIZE;
 	sbd.time = time(NULL);
 	osi_list_init(&sbd.rglist);
-	init_buf_list(&sbd, &sbd.buf_list, 128 << 20);
-	init_buf_list(&sbd, &sbd.nvbuf_list, 0xffffffff);
+	init_buf_list(&sbd, &sbd.buf_list, 1 << 20);
 	gfs2_sb_in(&sbd.sd_sb, buf); /* parse it out into the sb structure */
 	/* Check to see if this is really gfs1 */
 	if (sbd1->sb_fs_format == GFS_FORMAT_FS &&
@@ -1760,7 +1758,8 @@ static void read_superblock(int fd)
 		sbd.md.riinode = gfs2_load_inode(&sbd,
 						 sbd1->sb_rindex_di.no_addr);
 		sbd.fssize = sbd.device.length;
-		gfs1_ri_update(&sbd, 0, &count, 1);
+		gfs1_rindex_read(&sbd, fd, &count, &bitmap_blocks);
+		/*gfs1_ri_update(&sbd, 0, &count, 1);*/
 	} else {
 		sbd.sd_inptrs = (sbd.bsize - sizeof(struct gfs2_meta_header)) /
 			sizeof(uint64_t);
@@ -1770,7 +1769,8 @@ static void read_superblock(int fd)
 					    sbd.sd_sb.sb_master_dir.no_addr);
 		gfs2_lookupi(sbd.master_dir, "rindex", 6, &sbd.md.riinode);
 		sbd.fssize = sbd.device.length;
-		ri_update(&sbd, 0, &count);
+		rindex_read(&sbd, fd, &count, &bitmap_blocks);
+		/*ri_update(&sbd, 0, &count);*/
 	}
 
 }
@@ -2040,7 +2040,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, not_updated);
+	gfs2_rgrp_free(&sbd.rglist);
 	if (print)
 		exit(0);
 	return blk;
@@ -2079,7 +2079,7 @@ 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, not_updated);
+		gfs2_rgrp_free(&sbd.rglist);
 		if (print)
 			exit(-1);
 	}
@@ -2105,7 +2105,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, not_updated);
+	gfs2_rgrp_free(&sbd.rglist);
 	if (print)
 		exit(0);
 	return blk;
@@ -2139,7 +2139,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, not_updated);
+		gfs2_rgrp_free(&sbd.rglist);
 		exit(-1);
 	}
 	return blk;
@@ -2448,7 +2448,7 @@ static void find_print_block_type(void)
 	type = get_block_type(bh->b_data);
 	print_block_type(tblock, type, "");
 	brelse(bh, NOT_UPDATED);
-	gfs2_rgrp_free(&sbd.rglist, not_updated);
+	gfs2_rgrp_free(&sbd.rglist);
 	exit(0);
 }
 
@@ -2491,7 +2491,7 @@ static void find_print_block_rg(int bitmap)
 			printf("-1 (block invalid or part of an rgrp).\n");
 		}
 	}
-	gfs2_rgrp_free(&sbd.rglist, not_updated);
+	gfs2_rgrp_free(&sbd.rglist);
 	exit(0);
 }
 
@@ -2512,7 +2512,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[gfs1][i]);
-		gfs2_rgrp_free(&sbd.rglist, not_updated);
+		gfs2_rgrp_free(&sbd.rglist);
 		exit(-1);
 	}
 	ablock = blockstack[blockhist % BLOCK_STACK_SIZE].block;
@@ -2529,17 +2529,16 @@ static void find_change_block_alloc(int *newval)
 			if (rgd) {
 				type = gfs2_get_bitmap(&sbd, ablock, rgd);
 				printf("%d (%s)\n", type, allocdesc[gfs1][type]);
-				gfs2_rgrp_relse(rgd, not_updated);
 			} else {
-				gfs2_rgrp_free(&sbd.rglist, not_updated);
+				gfs2_rgrp_free(&sbd.rglist);
 				printf("-1 (block invalid or part of an rgrp).\n");
 				exit(-1);
 			}
 		}
 	}
-	gfs2_rgrp_free(&sbd.rglist, (newval) ? updated : not_updated);
+	gfs2_rgrp_free(&sbd.rglist);
 	if (newval)
-		bcommit(&sbd.nvbuf_list);
+		bcommit(&sbd.buf_list);
 	exit(0);
 }
 
@@ -3343,7 +3342,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, not_updated);
+				gfs2_rgrp_free(&sbd.rglist);
 				exit(EXIT_FAILURE);
 			}
 			if (isdigit(argv[i + 1][0])) {
@@ -3353,11 +3352,11 @@ static void process_parameters(int argc, char *argv[], int pass)
 				else
 					newval = (uint64_t)atoll(argv[i + 1]);
 				process_field(argv[i], &newval, 1);
-				gfs2_rgrp_free(&sbd.rglist, not_updated);
+				gfs2_rgrp_free(&sbd.rglist);
 				exit(0);
 			} else {
 				process_field(argv[i], NULL, 1);
-				gfs2_rgrp_free(&sbd.rglist, not_updated);
+				gfs2_rgrp_free(&sbd.rglist);
 				exit(0);
 			}
 		} else if (!strcmp(argv[i], "blocktype")) {
@@ -3389,7 +3388,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, not_updated);
+				gfs2_rgrp_free(&sbd.rglist);
 				exit(EXIT_FAILURE);
 			}
 			if (argv[i][0]=='0' && argv[i][1]=='x')
@@ -3406,7 +3405,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, not_updated);
+			gfs2_rgrp_free(&sbd.rglist);
 			exit(EXIT_SUCCESS);
 		} else if (!strcmp(argv[i], "rg")) {
 			int rg;
@@ -3415,7 +3414,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, not_updated);
+				gfs2_rgrp_free(&sbd.rglist);
 				exit(EXIT_FAILURE);
 			}
 			rg = atoi(argv[i]);
@@ -3424,7 +3423,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, not_updated);
+				gfs2_rgrp_free(&sbd.rglist);
 				exit(EXIT_SUCCESS);
 			}
 		}
@@ -3536,6 +3535,6 @@ int main(int argc, char *argv[])
 		free(buf);
 	if (indirect)
 		free(indirect);
-	gfs2_rgrp_free(&sbd.rglist, not_updated);
+	gfs2_rgrp_free(&sbd.rglist);
  	exit(EXIT_SUCCESS);
 }
diff --git a/gfs2/edit/savemeta.c b/gfs2/edit/savemeta.c
index 1983ba3..8959442 100644
--- a/gfs2/edit/savemeta.c
+++ b/gfs2/edit/savemeta.c
@@ -449,12 +449,14 @@ static void get_journal_inode_blocks(void)
 	}
 }
 
-static int next_rg_freemeta(struct rgrp_list *rgd, uint64_t *nrfblock, int first)
+static int next_rg_freemeta(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
+			    uint64_t *nrfblock, int first)
 {
 	struct gfs2_bitmap *bits = NULL;
 	uint32_t length = rgd->ri.ri_length;
 	uint32_t blk = (first)? 0: (uint32_t)((*nrfblock+1)-rgd->ri.ri_data0);
 	int i;
+	struct gfs2_buffer_head *bh;
 
 	if(!first && (*nrfblock < rgd->ri.ri_data0)) {
 		log_err("next_rg_freemeta:  Start block is outside rgrp "
@@ -469,9 +471,11 @@ static int next_rg_freemeta(struct rgrp_list *rgd, uint64_t *nrfblock, int first
 	}
 	for(; i < length; i++){
 		bits = &rgd->bits[i];
-		blk = gfs2_bitfit((unsigned char *)rgd->bh[i]->b_data +
+		bh = bread(&sdp->buf_list, rgd->ri.ri_addr + i);
+		blk = gfs2_bitfit((unsigned char *)bh->b_data +
 				  bits->bi_offset, bits->bi_len, blk,
 				  GFS2_BLKST_UNLINKED);
+		brelse(bh, not_updated);
 		if(blk != BFITNOENT){
 			*nrfblock = blk + (bits->bi_start * GFS2_NBBY) +
 				rgd->ri.ri_data0;
@@ -493,6 +497,8 @@ void savemeta(char *out_fn, int saveoption)
 	int rgcount;
 	uint64_t jindex_block;
 	struct gfs2_buffer_head *bh;
+	struct gfs2_rgrp rg;
+	struct gfs2_buffer_head **rgbh;
 
 	slow = (saveoption == 1);
 	sbd.md.journals = 1;
@@ -522,8 +528,7 @@ void savemeta(char *out_fn, int saveoption)
 		device_geometry(&sbd);
 		fix_device_geometry(&sbd);
 		osi_list_init(&sbd.rglist);
-		init_buf_list(&sbd, &sbd.buf_list, 128 << 20);
-		init_buf_list(&sbd, &sbd.nvbuf_list, 0xffffffff);
+		init_buf_list(&sbd, &sbd.buf_list, 1 << 20);
 		if (!gfs1)
 			sbd.sd_sb.sb_bsize = GFS2_DEFAULT_BSIZE;
 		compute_constants(&sbd);
@@ -617,7 +622,16 @@ void savemeta(char *out_fn, int saveoption)
 			int i, first;
 
 			rgd = osi_list_entry(tmp, struct rgrp_list, list);
-			slow = gfs2_rgrp_read(&sbd, rgd);
+			if(!(rgbh = (struct gfs2_buffer_head **)
+			     malloc(rgd->ri.ri_length *
+				    sizeof(struct gfs2_buffer_head *))))
+				break;
+			if(!memset(rgbh, 0, rgd->ri.ri_length *
+				   sizeof(struct gfs2_buffer_head *))) {
+				free(rgbh);
+				break;
+			}
+			slow = gfs2_rgrp_read(&sbd, rgd, rgbh, &rg);
 			if (slow)
 				continue;
 			log_debug("RG at %"PRIu64" is %u long\n",
@@ -639,7 +653,8 @@ void savemeta(char *out_fn, int saveoption)
 			if (saveoption != 2) {
 				int blktype;
 
-				while (!gfs2_next_rg_meta(rgd, &block, first)) {
+				while (!gfs2_next_rg_meta(&sbd, rgd, &block,
+							  first)) {
 					warm_fuzzy_stuff(block, FALSE, TRUE);
 					blktype = save_block(sbd.device_fd,
 							     out_fd, block);
@@ -650,13 +665,15 @@ void savemeta(char *out_fn, int saveoption)
 				/* Save off the free/unlinked meta blocks too.
 				   If we don't, we may run into metadata
 				   allocation issues. */
-				while (!next_rg_freemeta(rgd, &block, first)) {
+				while (!next_rg_freemeta(&sbd, rgd, &block,
+							 first)) {
 					blktype = save_block(sbd.device_fd,
 							     out_fd, block);
 					first = 0;
 				}
 			}
-			gfs2_rgrp_relse(rgd, not_updated);
+			gfs2_rgrp_relse(rgd, not_updated, rgbh);
+			free(rgbh);
 		}
 	}
 	if (slow) {
diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c
index a225eb1..3225c26 100644
--- a/gfs2/fsck/fs_recovery.c
+++ b/gfs2/fsck/fs_recovery.c
@@ -589,6 +589,5 @@ int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check,
 	inode_put(sdp->md.jiinode, not_updated);
 	/* Sync the buffers to disk so we get a fresh start. */
 	bsync(&sdp->buf_list);
-	bsync(&sdp->nvbuf_list);
 	return error;
 }
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index a12deed..67fa1fb 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -303,9 +303,8 @@ static int fill_super_block(struct gfs2_sbd *sdp)
 	 ********************************************************************/
 	log_info( _("Initializing lists...\n"));
 	osi_list_init(&sdp->rglist);
-	init_buf_list(sdp, &sdp->buf_list, 128 << 20);
-	init_buf_list(sdp, &sdp->nvbuf_list, 0xffffffff);
-	for(i = 0; i < BUF_HASH_SIZE; i++) {
+	init_buf_list(sdp, &sdp->buf_list, 1 << 20);
+	for(i = 0; i < FSCK_HASH_SIZE; i++) {
 		osi_list_init(&dir_hash[i]);
 		osi_list_init(&inode_hash[i]);
 	}
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index 718aa8f..56ac943 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -276,10 +276,12 @@ void check_statfs(struct gfs2_sbd *sdp)
 {
 	osi_list_t *tmp;
 	struct rgrp_list *rgd;
+	struct gfs2_rgrp rg;
 	struct gfs2_rindex *ri;
 	struct gfs2_statfs_change sc;
 	char buf[sizeof(struct gfs2_statfs_change)];
 	int count;
+	struct gfs2_buffer_head **rgbh;
 
 	/* Read the current statfs values */
 	count = gfs2_readi(sdp->md.statfs, buf, 0,
@@ -295,9 +297,24 @@ void check_statfs(struct gfs2_sbd *sdp)
 	for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
 		rgd = osi_list_entry(tmp, struct rgrp_list, list);
 		ri = &rgd->ri;
+		if(!(rgbh = (struct gfs2_buffer_head **)
+		     malloc(rgd->ri.ri_length *
+			    sizeof(struct gfs2_buffer_head *)))) {
+			log_err( _("Error: can't allocate memory to check statfs.\n"));
+			return;
+		}
+		if(!memset(rgbh, 0, rgd->ri.ri_length *
+			   sizeof(struct gfs2_buffer_head *))) {
+			free(rgbh);
+			log_err( _("Error: can't allocate memory to check statfs.\n"));
+			return;
+		}
+		gfs2_rgrp_read(sdp, rgd, rgbh, &rg);
 		sdp->blks_total += ri->ri_data;
-		sdp->blks_alloced += (ri->ri_data - rgd->rg.rg_free);
-		sdp->dinodes_alloced += rgd->rg.rg_dinodes;
+		sdp->blks_alloced += (ri->ri_data - rg.rg_free);
+		sdp->dinodes_alloced += rg.rg_dinodes;
+		gfs2_rgrp_relse(rgd, not_updated, rgbh);
+		free(rgbh);
 	}
 
 	/* See if they match */
@@ -482,7 +499,6 @@ int main(int argc, char **argv)
 		log_notice( _("Writing changes to disk\n"));
 
 	bsync(&sbp->buf_list);
-	bsync(&sbp->nvbuf_list);
 	destroy(sbp);
 	log_notice( _("gfs2_fsck complete    \n"));
 
diff --git a/gfs2/fsck/pass1.c b/gfs2/fsck/pass1.c
index a23da46..f011c64 100644
--- a/gfs2/fsck/pass1.c
+++ b/gfs2/fsck/pass1.c
@@ -995,6 +995,8 @@ int pass1(struct gfs2_sbd *sbp)
 	uint64_t blk_count;
 	uint64_t offset;
 	uint64_t rg_count = 0;
+	struct gfs2_rgrp rg;
+	struct gfs2_buffer_head **rgbh;
 
 	/* FIXME: In the gfs fsck, we had to mark things like the
 	 * journals and indices and such as 'other_meta' - in gfs2,
@@ -1017,8 +1019,18 @@ int pass1(struct gfs2_sbd *sbp)
 		log_info( _("Checking metadata in Resource Group #%" PRIu64 "\n"),
 				 rg_count);
 		rgd = osi_list_entry(tmp, struct rgrp_list, list);
-		if(gfs2_rgrp_read(sbp, rgd)){
+		if(!(rgbh = (struct gfs2_buffer_head **)
+		     malloc(rgd->ri.ri_length *
+			    sizeof(struct gfs2_buffer_head *))))
+			return FSCK_ERROR;
+		if(!memset(rgbh, 0, rgd->ri.ri_length *
+			   sizeof(struct gfs2_buffer_head *))) {
+			free(rgbh);
+			return FSCK_ERROR;
+		}
+		if(gfs2_rgrp_read(sbp, rgd, rgbh, &rg)){
 			stack;
+			free(rgbh);
 			return FSCK_ERROR;
 		}
 		log_debug( _("RG at %llu (0x%llx) is %u long\n"),
@@ -1029,6 +1041,7 @@ int pass1(struct gfs2_sbd *sbp)
 			if(gfs2_block_set(sbp, bl, rgd->ri.ri_addr + i,
 					  gfs2_meta_other)){
 				stack;
+				free(rgbh);
 				return FSCK_ERROR;
 			}
 		}
@@ -1039,11 +1052,12 @@ int pass1(struct gfs2_sbd *sbp)
 
 		while (1) {
 			/* "block" is relative to the entire file system */
-			if (gfs2_next_rg_meta(rgd, &block, first))
+			if (gfs2_next_rg_meta(sbp, rgd, &block, first))
 				break;
 			warm_fuzzy_stuff(block);
 			if (fsck_abort) { /* if asked to abort */
-				gfs2_rgrp_relse(rgd, not_updated);
+				gfs2_rgrp_relse(rgd, not_updated, rgbh);
+				free(rgbh);
 				return FSCK_OK;
 			}
 			if (skip_this_pass) {
@@ -1056,13 +1070,15 @@ int pass1(struct gfs2_sbd *sbp)
 			if (scan_meta(sbp, bh, block)) {
 				stack;
 				brelse(bh, not_updated);
-				gfs2_rgrp_relse(rgd, not_updated);
+				gfs2_rgrp_relse(rgd, not_updated, rgbh);
+				free(rgbh);
 				return FSCK_ERROR;
 			}
 			brelse(bh, not_updated);
 			first = 0;
 		}
-		gfs2_rgrp_relse(rgd, not_updated);
+		gfs2_rgrp_relse(rgd, not_updated, rgbh);
+		free(rgbh);
 	}
 	return FSCK_OK;
 }
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index a533536..98cdeef 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -166,7 +166,8 @@ static int check_block_status(struct gfs2_sbd *sbp, char *buffer, unsigned int b
 }
 
 static enum update_flags update_rgrp(struct gfs2_sbd *sbp, struct rgrp_list *rgp,
-							  uint32_t *count)
+			      uint32_t *count, struct gfs2_buffer_head **rgbh,
+			      struct gfs2_rgrp *rg)
 {
 	uint32_t i;
 	struct gfs2_bitmap *bits;
@@ -177,26 +178,26 @@ static enum update_flags 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(sbp, rgbh[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 0;
 	}
 
 	/* actually adjust counters and write out to disk */
-	if(rgp->rg.rg_free != count[0]) {
+	if(rgp->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,
 			(unsigned long long)rgp->ri.ri_addr,
-			rgp->rg.rg_free, count[0]);
-		rgp->rg.rg_free = count[0];
+			rgp->rg_free, count[0]);
+		rgp->rg_free = count[0];
 		update = 1;
 	}
-	if(rgp->rg.rg_dinodes != count[1]) {
+	if(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];
+				rg->rg_dinodes, count[1]);
+		rg->rg_dinodes = count[1];
 		update = 1;
 	}
 	if((rgp->ri.ri_data - count[0] - count[1]) != count[2]) {
@@ -212,7 +213,7 @@ static enum update_flags update_rgrp(struct gfs2_sbd *sbp, struct rgrp_list *rgp
 			errors_corrected++;
 			log_warn( _("Resource group counts updated\n"));
 			/* write out the rgrp */
-			gfs2_rgrp_out(&rgp->rg, rgp->bh[0]->b_data);
+			gfs2_rgrp_out(rg, rgbh[0]->b_data);
 			return updated;
 		} else
 			log_err( _("Resource group counts left inconsistent\n"));
@@ -229,9 +230,11 @@ static enum update_flags update_rgrp(struct gfs2_sbd *sbp, struct rgrp_list *rgp
 int pass5(struct gfs2_sbd *sbp)
 {
 	osi_list_t *tmp;
-	struct rgrp_list *rgp = NULL;
+	struct rgrp_list *rgd = NULL;
 	uint32_t count[3];
 	uint64_t rg_count = 0;
+	struct gfs2_rgrp rg;
+	struct gfs2_buffer_head **rgbh;
 
 	/* Reconcile RG bitmaps with fsck bitmap */
 	for(tmp = sbp->rglist.next; tmp != &sbp->rglist; tmp = tmp->next){
@@ -241,16 +244,27 @@ int pass5(struct gfs2_sbd *sbp)
 			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);
+		rgd = osi_list_entry(tmp, struct rgrp_list, list);
 
-		if(gfs2_rgrp_read(sbp, rgp)){
+		if(!(rgbh = (struct gfs2_buffer_head **)
+		     malloc(rgd->ri.ri_length *
+			    sizeof(struct gfs2_buffer_head *))))
+			return FSCK_ERROR;
+		if(!memset(rgbh, 0, rgd->ri.ri_length *
+			   sizeof(struct gfs2_buffer_head *))) {
+			free(rgbh);
+			return FSCK_ERROR;
+		}
+		if(gfs2_rgrp_read(sbp, rgd, rgbh, &rg)){
 			stack;
+			free(rgbh);
 			return FSCK_ERROR;
 		}
 		rg_count++;
 		/* Compare the bitmaps and report the differences */
-		f = update_rgrp(sbp, rgp, count);
-		gfs2_rgrp_relse(rgp, f);
+		f = update_rgrp(sbp, rgd, count, rgbh, &rg);
+		gfs2_rgrp_relse(rgd, f, rgbh);
+		free(rgbh);
 	}
 	/* Fix up superblock info based on this - don't think there's
 	 * anything to do here... */
diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c
index 9d28b1a..cc5b2ca 100644
--- a/gfs2/fsck/rgrepair.c
+++ b/gfs2/fsck/rgrepair.c
@@ -142,7 +142,7 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list,
 	for (blk = sdp->sb_addr + 1;
 	     blk < sdp->device.length && number_of_rgs < 6;
 	     blk++) {
-		bh = bread(&sdp->nvbuf_list, blk);
+		bh = bread(&sdp->buf_list, blk);
 		if (((blk == sdp->sb_addr + 1) ||
 		    (!gfs2_check_meta(bh, GFS2_METATYPE_RG))) &&
 		    !is_false_rg(blk)) {
@@ -220,7 +220,7 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list,
 	for (blk = sdp->sb_addr + 1; blk <= sdp->device.length;
 	     blk += block_bump) {
 		log_debug( _("Block 0x%" PRIx64 "\n"), blk);
-		bh = bread(&sdp->nvbuf_list, blk);
+		bh = bread(&sdp->buf_list, blk);
 		rg_was_fnd = (!gfs2_check_meta(bh, GFS2_METATYPE_RG));
 		brelse(bh, not_updated);
 		/* Allocate a new RG and index. */
@@ -254,7 +254,7 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list,
 		for (fwd_block = blk + 1;
 		     fwd_block < sdp->device.length; 
 		     fwd_block++) {
-			bh = bread(&sdp->nvbuf_list, fwd_block);
+			bh = bread(&sdp->buf_list, fwd_block);
 			bitmap_was_fnd =
 				(!gfs2_check_meta(bh, GFS2_METATYPE_RB));
 			brelse(bh, not_updated);
@@ -265,13 +265,6 @@ static int gfs2_rindex_rebuild(struct gfs2_sbd *sdp, osi_list_t *ret_list,
 		} /* for subsequent bitmaps */
 		
 		gfs2_compute_bitstructs(sdp, calc_rgd);
-		log_debug( _("Memory allocated for rg at 0x%llx, bh: %p\n"),
-			  (unsigned long long)calc_rgd->ri.ri_addr,
-			  calc_rgd->bh);
-		if (!calc_rgd->bh) {
-			log_crit( _("Can't allocate memory for bitmap repair.\n"));
-			return -1;
-		}
 		calc_rgd->ri.ri_data0 = calc_rgd->ri.ri_addr +
 			calc_rgd->ri.ri_length;
 		if (prev_rgd) {
@@ -386,37 +379,38 @@ 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_list *rgd,
+		     uint64_t errblock, struct gfs2_buffer_head **rgbh,
+		     struct gfs2_rgrp *rg)
 {
-	int x = errblock - rg->ri.ri_addr;
+	int x = errblock - rgd->ri.ri_addr;
 
 	log_err( _("Block #%"PRIu64" (0x%" PRIx64") (%d of %d) is neither"
 		" GFS2_METATYPE_RB nor GFS2_METATYPE_RG.\n"),
-		rg->bh[x]->b_blocknr, rg->bh[x]->b_blocknr,
-		(int)x+1, (int)rg->ri.ri_length);
+		rgbh[x]->b_blocknr, rgbh[x]->b_blocknr,
+		(int)x+1, (int)rgd->ri.ri_length);
 	errors_found++;
 	if (query(&opts, "Fix the RG? (y/n)")) {
 
 		errors_corrected++;
 		log_err( _("Attempting to repair the RG.\n"));
-		rg->bh[x] = bread(&sdp->nvbuf_list, rg->ri.ri_addr + x);
+		rgbh[x] = bread(&sdp->buf_list, rgd->ri.ri_addr + x);
 		if (x) {
 			struct gfs2_meta_header mh;
 
 			mh.mh_magic = GFS2_MAGIC;
 			mh.mh_type = GFS2_METATYPE_RB;
 			mh.mh_format = GFS2_FORMAT_RB;
-			gfs2_meta_header_out(&mh, rg->bh[x]->b_data);
+			gfs2_meta_header_out(&mh, rgbh[x]->b_data);
 		} 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]->b_data);
+			memset(rg, 0, sizeof(struct gfs2_rgrp));
+			rg->rg_header.mh_magic = GFS2_MAGIC;
+			rg->rg_header.mh_type = GFS2_METATYPE_RG;
+			rg->rg_header.mh_format = GFS2_FORMAT_RG;
+			rg->rg_free = rgd->ri.ri_data;
+			gfs2_rgrp_out(rg, rgbh[x]->b_data);
 		}
-		brelse(rg->bh[x], updated);
+		brelse(rgbh[x], updated);
 		return 0;
 	}
 	return 1;
@@ -437,6 +431,7 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count)
 	int calc_rg_count = 0, rgcount_from_index, rg;
 	osi_list_t *exp, *act; /* expected, actual */
 	struct gfs2_rindex buf;
+	int bitmap_blocks;
 
 	if (trust_lvl == blind_faith)
 		return 0;
@@ -445,7 +440,7 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count)
 		error = gfs2_rindex_calculate(sdp, &expected_rglist,
 					       &calc_rg_count);
 		if (error) { /* If calculated RGs don't match the fs */
-			gfs2_rgrp_free(&expected_rglist, not_updated);
+			gfs2_rgrp_free(&expected_rglist);
 			return -1;
 		}
 	}
@@ -454,18 +449,18 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count)
 					     &calc_rg_count);
 		if (error) {
 			log_crit( _("Error rebuilding rg list.\n"));
-			gfs2_rgrp_free(&expected_rglist, not_updated);
+			gfs2_rgrp_free(&expected_rglist);
 			return -1;
 		}
 		sdp->rgrps = calc_rg_count;
 	}
 	/* Read in the rindex */
 	osi_list_init(&sdp->rglist); /* Just to be safe */
-	rindex_read(sdp, 0, &rgcount_from_index);
+	rindex_read(sdp, 0, &rgcount_from_index, &bitmap_blocks);
 	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, not_updated);
-		gfs2_rgrp_free(&sdp->rglist, not_updated);
+		gfs2_rgrp_free(&expected_rglist);
+		gfs2_rgrp_free(&sdp->rglist);
 		return -1;
 	}
 	log_warn( _("L%d: number of rgs expected     = %lld.\n"), trust_lvl + 1,
@@ -473,8 +468,8 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count)
 	if (calc_rg_count != sdp->rgrps) {
 		log_warn( _("L%d: They don't match; either (1) the fs was extended, (2) an odd\n"), trust_lvl + 1);
 		log_warn( _("L%d: rg size was used, or (3) we have a corrupt rg index.\n"), trust_lvl + 1);
-		gfs2_rgrp_free(&expected_rglist, not_updated);
-		gfs2_rgrp_free(&sdp->rglist, not_updated);
+		gfs2_rgrp_free(&expected_rglist);
+		gfs2_rgrp_free(&sdp->rglist);
 		return -1;
 	}
 	/* ------------------------------------------------------------- */
@@ -505,8 +500,8 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count)
 			 trust_lvl + 1);
 		log_warn( _("%d out of %d RGs did not match what was expected.\n"),
 			 descrepencies, rg);
-		gfs2_rgrp_free(&expected_rglist, not_updated);
-		gfs2_rgrp_free(&sdp->rglist, not_updated);
+		gfs2_rgrp_free(&expected_rglist);
+		gfs2_rgrp_free(&sdp->rglist);
 		return -1;
 	}
 	/* ------------------------------------------------------------- */
@@ -546,8 +541,6 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count)
 				/* Therefore, gfs2_compute_bitstructs might  */
 				/* have malloced the wrong length for bitmap */
 				/* buffers.  So we have to redo it.          */
-				if (actual->bh)
-					free(actual->bh);
 				if (actual->bits)
 					free(actual->bits);
 			}
@@ -567,28 +560,46 @@ int rg_repair(struct gfs2_sbd *sdp, int trust_lvl, int *rg_count)
 		struct rgrp_list *rgd;
 		uint64_t prev_err = 0, errblock;
 		int i;
+		struct gfs2_rgrp rgrp;
+		struct gfs2_buffer_head **rgbh;
 
 		/* 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);
-			errblock = gfs2_rgrp_read(sdp, rgd);
+
+			if(!(rgbh = (struct gfs2_buffer_head **)
+			     malloc(rgd->ri.ri_length *
+				    sizeof(struct gfs2_buffer_head *))))
+				return -1;
+			if(!memset(rgbh, 0, bitmap_blocks *
+				   sizeof(struct gfs2_buffer_head *))) {
+				free(rgbh);
+				return -1;
+			}
+
+			errblock = gfs2_rgrp_read(sdp, rgd, rgbh, &rgrp);
 			if (errblock) {
-				if (errblock == prev_err)
+				if (errblock == prev_err) {
+					free(rgbh);
 					break;
+				}
 				prev_err = errblock;
-				rewrite_rg_block(sdp, rgd, errblock);
+				rewrite_rg_block(sdp, rgd, errblock, rgbh,
+						 &rgrp);
 			}
 			else {
-				gfs2_rgrp_relse(rgd, not_updated);
+				gfs2_rgrp_relse(rgd, not_updated, rgbh);
+				free(rgbh);
 				break;
 			}
+			free(rgbh);
 			i++;
 		} while (i < rgd->ri.ri_length);
 	}
 	*rg_count = rg;
-	gfs2_rgrp_free(&expected_rglist, not_updated);
-	gfs2_rgrp_free(&sdp->rglist, not_updated);
+	gfs2_rgrp_free(&expected_rglist);
+	gfs2_rgrp_free(&sdp->rglist);
 	return 0;
 }
diff --git a/gfs2/libgfs2/block_list.c b/gfs2/libgfs2/block_list.c
index b0d7000..5d1851b 100644
--- a/gfs2/libgfs2/block_list.c
+++ b/gfs2/libgfs2/block_list.c
@@ -40,8 +40,8 @@ struct gfs2_block_list *gfs2_block_list_create(struct gfs2_sbd *sdp,
 	if (!il || !memset(il, 0, sizeof(*il)))
 		return NULL;
 
-	if(gfs2_bitmap_create(&il->list.gbmap.group_map, size, 4)) {
-		*addl_mem_needed = il->list.gbmap.group_map.mapsize;
+	if(gfs2_bitmap_create(&il->list.gbmap, size, 4)) {
+		*addl_mem_needed = il->list.gbmap.mapsize;
 		free(il);
 		il = NULL;
 	}
@@ -169,7 +169,7 @@ int gfs2_block_mark(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
 	else if(mark == gfs2_eattr_block)
 		gfs2_special_set(&sdp->eattr_blocks, block);
 	else
-		err = gfs2_bitmap_set(&il->list.gbmap.group_map, block,
+		err = gfs2_bitmap_set(&il->list.gbmap, block,
 				      mark_to_gbmap[mark]);
 	return err;
 }
@@ -192,7 +192,7 @@ int gfs2_block_unmark(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
 		break;
 	default:
 		/* FIXME: check types */
-		err = gfs2_bitmap_clear(&il->list.gbmap.group_map, block);
+		err = gfs2_bitmap_clear(&il->list.gbmap, block);
 		break;
 	}
 	return err;
@@ -207,7 +207,7 @@ int gfs2_block_clear(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
 	gfs2_dup_clear(&sdp->dup_blocks, block);
 	gfs2_special_clear(&sdp->bad_blocks, block);
 	gfs2_special_clear(&sdp->eattr_blocks, block);
-	err = gfs2_bitmap_clear(&il->list.gbmap.group_map, block);
+	err = gfs2_bitmap_clear(&il->list.gbmap, block);
 	return err;
 }
 
@@ -236,8 +236,7 @@ int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
 		val->dup_block = 1;
 	if (blockfind(&sdp->eattr_blocks, block))
 		val->eattr_block = 1;
-	if((err = gfs2_bitmap_get(&il->list.gbmap.group_map, block,
-				  &val->block_type)))
+	if((err = gfs2_bitmap_get(&il->list.gbmap, block, &val->block_type)))
 		return err;
 	return 0;
 }
@@ -245,7 +244,7 @@ int gfs2_block_check(struct gfs2_sbd *sdp, struct gfs2_block_list *il,
 void *gfs2_block_list_destroy(struct gfs2_sbd *sdp, struct gfs2_block_list *il)
 {
 	if(il) {
-		gfs2_bitmap_destroy(&il->list.gbmap.group_map);
+		gfs2_bitmap_destroy(&il->list.gbmap);
 		free(il);
 		il = NULL;
 	}
diff --git a/gfs2/libgfs2/buf.c b/gfs2/libgfs2/buf.c
index 6c7e181..48b1f5c 100644
--- a/gfs2/libgfs2/buf.c
+++ b/gfs2/libgfs2/buf.c
@@ -44,6 +44,10 @@ static void write_buffer(struct buf_list *bl, struct gfs2_buffer_head *bh)
 		do_write(sdp->device_fd, bh->b_data, sdp->bsize);
 		sdp->writes++;
 	}
+	bh->b_blocknr = -1;
+	bh->b_data = NULL;
+	bh->b_count = -1;
+	bh->b_changed = -1;
 	free(bh);
 }
 
diff --git a/gfs2/libgfs2/fs_bits.c b/gfs2/libgfs2/fs_bits.c
index b295261..2183aa5 100644
--- a/gfs2/libgfs2/fs_bits.c
+++ b/gfs2/libgfs2/fs_bits.c
@@ -13,6 +13,7 @@
 
 #include <inttypes.h>
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 
 #include "libgfs2.h"
@@ -171,6 +172,8 @@ int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int state)
 	struct rgrp_list *rgd;
 	unsigned char *byte, cur_state;
 	unsigned int bit;
+	struct gfs2_rgrp rg;
+	struct gfs2_buffer_head **rgbh;
 
 	/* FIXME: should GFS2_BLKST_INVALID be allowed */
 	if ((state < GFS2_BLKST_FREE) || (state > GFS2_BLKST_DINODE))
@@ -181,8 +184,20 @@ int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int state)
 	if(!rgd)
 		return -1;
 
-	if(gfs2_rgrp_read(sdp, rgd))
+	if(!(rgbh = (struct gfs2_buffer_head **)
+	     malloc(rgd->ri.ri_length *
+		    sizeof(struct gfs2_buffer_head *))))
 		return -1;
+	if(!memset(rgbh, 0, rgd->ri.ri_length *
+		   sizeof(struct gfs2_buffer_head *))) {
+		free(rgbh);
+		return -1;
+	}
+
+	if(gfs2_rgrp_read(sdp, rgd, rgbh, &rg)) {
+		free(rgbh);
+		return -1;
+	}
 	rgrp_block = (uint32_t)(blkno - rgd->ri.ri_data0);
 	for(buf= 0; buf < rgd->ri.ri_length; buf++){
 		bits = &(rgd->bits[buf]);
@@ -190,7 +205,7 @@ int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int state)
 			break;
 	}
 
-	byte = (unsigned char *)(rgd->bh[buf]->b_data + bits->bi_offset) +
+	byte = (unsigned char *)(rgbh[buf]->b_data + bits->bi_offset) +
 		(rgrp_block/GFS2_NBBY - bits->bi_start);
 	bit = (rgrp_block % GFS2_NBBY) * GFS2_BIT_SIZE;
 
@@ -198,12 +213,13 @@ int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int state)
 	*byte ^= cur_state << bit;
 	*byte |= state << bit;
 
-	gfs2_rgrp_relse(rgd, updated);
+	gfs2_rgrp_relse(rgd, updated, rgbh);
+	free(rgbh);
 	return 0;
 }
 
 /*
- * fs_get_bitmap - get value of FS bitmap
+ * gfs2_get_bitmap - get value of FS bitmap
  * @sdp: super block
  * @blkno: block number relative to file system
  *
@@ -220,12 +236,15 @@ int gfs2_set_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, int state)
 int gfs2_get_bitmap(struct gfs2_sbd *sdp, uint64_t blkno,
 		    struct rgrp_list *rgd)
 {
-	int           buf, val;
+	int           i, val;
 	uint32_t        rgrp_block;
 	struct gfs2_bitmap	*bits = NULL;
 	unsigned int  bit;
 	unsigned char *byte;
 	int local_rgd = 0;
+	struct gfs2_rgrp rg;
+	struct gfs2_buffer_head **rgbh;
+	int bitmap_blocks = rgd->length;
 
 	if(gfs2_check_range(sdp, blkno))
 		return -1;
@@ -235,30 +254,39 @@ int gfs2_get_bitmap(struct gfs2_sbd *sdp, uint64_t blkno,
 	}
 	if(rgd == NULL)
 		return -1;
-	if(gfs2_rgrp_read(sdp, rgd))
+	if(!(rgbh = (struct gfs2_buffer_head **)
+	     malloc(bitmap_blocks * sizeof(struct gfs2_buffer_head *))))
+		return -1;
+	if(!memset(rgbh, 0, bitmap_blocks *
+		   sizeof(struct gfs2_buffer_head *))) {
+		free(rgbh);
+		return -1;
+	}
+
+	if(gfs2_rgrp_read(sdp, rgd, rgbh, &rg))
 		return -1;
 
 	rgrp_block = (uint32_t)(blkno - rgd->ri.ri_data0);
 
-	for(buf= 0; buf < rgd->ri.ri_length; buf++){
-		bits = &(rgd->bits[buf]);
+	for(i= 0; i < rgd->ri.ri_length; i++){
+		bits = &(rgd->bits[i]);
 		if(rgrp_block < ((bits->bi_start + bits->bi_len)*GFS2_NBBY)){
 			break;
 		}
 	}
 
-	if(buf >= rgd->ri.ri_length){
-		gfs2_rgrp_relse(rgd, not_updated);
+	if(i >= rgd->ri.ri_length){
+		gfs2_rgrp_relse(rgd, not_updated, rgbh);
 		return -1;
 	}
 
-	byte = (unsigned char *)(rgd->bh[buf]->b_data + bits->bi_offset) +
+	byte = (unsigned char *)(rgbh[i]->b_data + bits->bi_offset) +
 		(rgrp_block/GFS2_NBBY - bits->bi_start);
 	bit = (rgrp_block % GFS2_NBBY) * GFS2_BIT_SIZE;
 
 	val = ((*byte >> bit) & GFS2_BIT_MASK);
 	if(local_rgd)
-		gfs2_rgrp_relse(rgd, not_updated);
+		gfs2_rgrp_relse(rgd, not_updated, rgbh);
 
 	return val;
 }
diff --git a/gfs2/libgfs2/fs_geometry.c b/gfs2/libgfs2/fs_geometry.c
index 0ad7df4..86e50f9 100644
--- a/gfs2/libgfs2/fs_geometry.c
+++ b/gfs2/libgfs2/fs_geometry.c
@@ -120,7 +120,6 @@ void compute_rgrp_layout(struct gfs2_sbd *sdp, int rgsize_specified)
 			rl->length = dev->length -
 				(nrgrp - 1) * (dev->length / nrgrp);
 		}
-		rl->rgf_flags = dev->rgf_flags;
 
 		log_info("%d: start: %" PRIu64 " (0x%"
 			 PRIx64 "), length = %"PRIu64" (0x%"
@@ -191,7 +190,7 @@ void build_rgrps(struct gfs2_sbd *sdp, int do_write)
 	struct rgrp_list *rl;
 	uint32_t rgblocks, bitblocks;
 	struct gfs2_rindex *ri;
-	struct gfs2_rgrp *rg;
+	struct gfs2_rgrp rg;
 	struct gfs2_meta_header mh;
 	unsigned int x;
 	struct gfs2_buffer_head *bh;
@@ -205,7 +204,6 @@ void build_rgrps(struct gfs2_sbd *sdp, int do_write)
 	     tmp = tmp->next) {
 		rl = osi_list_entry(tmp, struct rgrp_list, list);
 		ri = &rl->ri;
-		rg = &rl->rg;
 
 		rgblocks = rl->length;
 		rgblocks2bitblocks(sdp->bsize, &rgblocks, &bitblocks);
@@ -216,19 +214,20 @@ void build_rgrps(struct gfs2_sbd *sdp, int do_write)
 		ri->ri_data = rgblocks;
 		ri->ri_bitbytes = rgblocks / GFS2_NBBY;
 
-		rg->rg_header.mh_magic = GFS2_MAGIC;
-		rg->rg_header.mh_type = GFS2_METATYPE_RG;
-		rg->rg_header.mh_format = GFS2_FORMAT_RG;
-		rg->rg_flags = rl->rgf_flags;
-		rg->rg_free = rgblocks;
+		memset(&rg, 0, sizeof(rg));
+		rg.rg_header.mh_magic = GFS2_MAGIC;
+		rg.rg_header.mh_type = GFS2_METATYPE_RG;
+		rg.rg_header.mh_format = GFS2_FORMAT_RG;
+		rg.rg_free = rgblocks;
+		rl->rg_free = rgblocks;
 
 		if (do_write) {
 			for (x = 0; x < bitblocks; x++) {
-				bh = bget(&sdp->nvbuf_list, rl->start + x);
+				bh = bget(&sdp->buf_list, rl->start + x);
 				if (x)
 					gfs2_meta_header_out(&mh, bh->b_data);
 				else
-					gfs2_rgrp_out(rg, bh->b_data);
+					gfs2_rgrp_out(&rg, bh->b_data);
 				brelse(bh, updated);
 			}
 		}
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index 7dacd43..4b13d5c 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -55,16 +55,17 @@ static uint64_t blk_alloc_i(struct gfs2_sbd *sdp, unsigned int type)
 	osi_list_t *tmp, *head;
 	struct rgrp_list *rl = NULL;
 	struct gfs2_rindex *ri;
-	struct gfs2_rgrp *rg;
+	struct gfs2_rgrp rg;
+	struct gfs2_buffer_head **rgbh;
 	unsigned int block, bn = 0, x = 0, y = 0;
-	struct gfs2_buffer_head *bh;
 	unsigned int state;
 
+	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)
+		if (rl->rg_free)
 			break;
 	}
 
@@ -72,31 +73,43 @@ static uint64_t blk_alloc_i(struct gfs2_sbd *sdp, unsigned int type)
 		die("out of space\n");
 
 	ri = &rl->ri;
-	rg = &rl->rg;
+
+	if(!(rgbh = (struct gfs2_buffer_head **)
+	     malloc(rl->ri.ri_length *
+		    sizeof(struct gfs2_buffer_head *))))
+		return -1;
+	if(!memset(rgbh, 0, rl->ri.ri_length *
+		   sizeof(struct gfs2_buffer_head *))) {
+		free(rgbh);
+		return -1;
+	}
 
 	for (block = 0; block < ri->ri_length; block++) {
-		bh = bread(&sdp->nvbuf_list, ri->ri_addr + block);
+		rgbh[block] = bread(&sdp->buf_list, ri->ri_addr + block);
 		x = (block) ? sizeof(struct gfs2_meta_header) : sizeof(struct gfs2_rgrp);
 
+		if (!block)
+			gfs2_rgrp_in(&rg, rgbh[0]->b_data);
 		for (; x < sdp->bsize; x++)
 			for (y = 0; y < GFS2_NBBY; y++) {
-				state = (bh->b_data[x] >> (GFS2_BIT_SIZE * y)) & 0x03;
+				state = (rgbh[block]->b_data[x] >>
+					 (GFS2_BIT_SIZE * y)) & 0x03;
 				if (state == GFS2_BLKST_FREE)
 					goto found;
 				bn++;
 			}
 
-		brelse(bh, FALSE);
+		brelse(rgbh[block], FALSE);
 	}
 
 	die("allocation is broken (1): %"PRIu64" %u\n",
-	    (uint64_t)rl->ri.ri_addr, rl->rg.rg_free);
+	    (uint64_t)rl->ri.ri_addr, rl->rg_free);
 
  found:
 	if (bn >= ri->ri_bitbytes * GFS2_NBBY)
 		die("allocation is broken (2): %u %u %"PRIu64" %u\n",
 		    bn, ri->ri_bitbytes * GFS2_NBBY,
-		    (uint64_t)rl->ri.ri_addr, rl->rg.rg_free);
+		    (uint64_t)rl->ri.ri_addr, rl->rg_free);
 
 	switch (type) {
 	case DATA:
@@ -105,24 +118,25 @@ static uint64_t blk_alloc_i(struct gfs2_sbd *sdp, unsigned int type)
 		break;
 	case DINODE:
 		state = GFS2_BLKST_DINODE;
-		rg->rg_dinodes++;
+		rg.rg_dinodes++;
 		break;
 	default:
 		die("bad state\n");
 	}
 
-	bh->b_data[x] &= ~(0x03 << (GFS2_BIT_SIZE * y));
-	bh->b_data[x] |= state << (GFS2_BIT_SIZE * y);
-	rg->rg_free--;
+	rgbh[block]->b_data[x] &= ~(0x03 << (GFS2_BIT_SIZE * y));
+	rgbh[block]->b_data[x] |= state << (GFS2_BIT_SIZE * y);
+	rg.rg_free--;
+	rl->rg_free--;
 
-	brelse(bh, updated);
+	brelse(rgbh[block], updated);
 
-	bh = bread(&sdp->nvbuf_list, ri->ri_addr);
-	gfs2_rgrp_out(rg, bh->b_data);
-	brelse(bh, updated);
+	rgbh[0] = bread(&sdp->buf_list, ri->ri_addr);
+	gfs2_rgrp_out(&rg, rgbh[0]->b_data);
+	brelse(rgbh[0], updated);
 
 	sdp->blks_alloced++;
-
+	free(rgbh);
 	return ri->ri_data0 + bn;
 }
 
@@ -927,7 +941,7 @@ static int get_first_leaf(struct gfs2_inode *dip, uint32_t lindex,
  */
 
 static int get_next_leaf(struct gfs2_inode *dip,struct gfs2_buffer_head *bh_in,
-			 struct gfs2_buffer_head **bh_out)
+						 struct gfs2_buffer_head **bh_out)
 {
 	struct gfs2_leaf *leaf;
 
@@ -1563,13 +1577,16 @@ void gfs2_free_block(struct gfs2_sbd *sdp, uint64_t block)
 {
 	struct gfs2_buffer_head *bh;
 	struct rgrp_list *rgd;
+	struct gfs2_rgrp rg;
 
 	gfs2_set_bitmap(sdp, block, GFS2_BLKST_FREE);
 	/* Adjust the free space count for the freed block */
 	rgd = gfs2_blk2rgrpd(sdp, block); /* find the rg for indir block */
-	bh = bget(&sdp->nvbuf_list, rgd->ri.ri_addr); /* get the rg buffer */
-	rgd->rg.rg_free++; /* adjust the free count */
-	gfs2_rgrp_out(&rgd->rg, bh->b_data); /* back to the buffer */
+	bh = bget(&sdp->buf_list, rgd->ri.ri_addr); /* get the rg buffer */
+	gfs2_rgrp_in(&rg, bh->b_data); /* back to the buffer */
+	rg.rg_free++; /* adjust the free count */
+	rgd->rg_free++;
+	gfs2_rgrp_out(&rg, bh->b_data); /* back to the buffer */
 	brelse(bh, updated); /* release the buffer */
 	sdp->blks_alloced--;
 }
@@ -1588,6 +1605,7 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock)
 	uint32_t height;
 	osi_list_t metalist[GFS2_MAX_META_HEIGHT];
 	osi_list_t *cur_list, *next_list, *tmp;
+	struct gfs2_rgrp rg;
 
 	for (h = 0; h < GFS2_MAX_META_HEIGHT; h++)
 		osi_list_init(&metalist[h]);
@@ -1616,11 +1634,8 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock)
 				gfs2_free_block(sdp, block);
 				if (h == height - 1) /* if not metadata */
 					continue; /* don't queue it up */
-				/* Read the next metadata block in the chain.
-				   First see if it's on the nvbuf_list. */
-				nbh = bfind(&sdp->nvbuf_list, block);
-				if (!nbh)
-					nbh = bread(&sdp->buf_list, block);
+				/* Read the next metadata block in the chain */
+				nbh = bread(&sdp->buf_list, block);
 				osi_list_add(&nbh->b_altlist, next_list);
 				brelse(nbh, not_updated);
 			}
@@ -1634,13 +1649,12 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock)
 	sdp->blks_alloced--;
 	/* Now we have to adjust the rg freespace count and inode count: */
 	rgd = gfs2_blk2rgrpd(sdp, diblock);
-	/* The rg itself is in memory as rgd->rg, but there's most likely a  */
-	/* buffer in memory for the rg on disk because we used it to fix the */
-	/* bitmaps, some of which are on the same block on disk.             */
-	bh = bread(&sdp->nvbuf_list, rgd->ri.ri_addr); /* get the buffer */
-	rgd->rg.rg_free++;
-	rgd->rg.rg_dinodes--; /* one less inode in use */
-	gfs2_rgrp_out(&rgd->rg, bh->b_data);
+	bh = bread(&sdp->buf_list, rgd->ri.ri_addr); /* get the buffer */
+	gfs2_rgrp_in(&rg, bh->b_data);
+	rg.rg_free++;
+	rgd->rg_free++;
+	rg.rg_dinodes--; /* one less inode in use */
+	gfs2_rgrp_out(&rg, bh->b_data);
 	brelse(bh, updated); /* release the buffer */
 	sdp->dinodes_alloced--;
 	return 0;
diff --git a/gfs2/libgfs2/gfs1.c b/gfs2/libgfs2/gfs1.c
index f9e5a6e..e783fdd 100644
--- a/gfs2/libgfs2/gfs1.c
+++ b/gfs2/libgfs2/gfs1.c
@@ -232,7 +232,8 @@ int gfs1_readi(struct gfs2_inode *ip, void *bufin,
  *
  * Returns: 0 on success, -1 on failure
  */
-int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1)
+int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1,
+		     int *bitmap_blocks)
 {
 	unsigned int rg;
 	int error;
@@ -242,6 +243,7 @@ int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1)
 
 	*count1 = 0;
 	prev_rgd = NULL;
+	*bitmap_blocks = 0;
 	for (rg = 0; ; rg++) {
 		if (fd > 0)
 			error = read(fd, &buf, sizeof(struct gfs2_rindex));
@@ -264,6 +266,8 @@ int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1)
 
 		gfs2_rindex_in(&rgd->ri, (char *)&buf);
 
+		if (rgd->ri.ri_length > *bitmap_blocks)
+			*bitmap_blocks = rgd->ri.ri_length;
 		rgd->start = rgd->ri.ri_addr;
 		if (prev_rgd) {
 			prev_length = rgd->start - prev_rgd->start;
@@ -297,14 +301,28 @@ int gfs1_ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int quiet)
 	osi_list_t *tmp;
 	int count1 = 0, count2 = 0;
 	uint64_t errblock = 0;
+	struct gfs2_rgrp rg;
+	struct gfs2_buffer_head **rgbh = NULL;
+	int bitmap_blocks;
 
-	if (gfs1_rindex_read(sdp, fd, &count1))
+	if (gfs1_rindex_read(sdp, fd, &count1, &bitmap_blocks))
 	    goto fail;
+
+	if(!(rgbh = (struct gfs2_buffer_head **)
+	     malloc(bitmap_blocks * sizeof(struct gfs2_buffer_head *))))
+		return -1;
+	if(!memset(rgbh, 0, bitmap_blocks *
+		   sizeof(struct gfs2_buffer_head *))) {
+		free(rgbh);
+		return -1;
+	}
 	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)
+		errblock = gfs2_rgrp_read(sdp, rgd, rgbh, &rg);
+		if (errblock) {
+			free(rgbh);
 			return errblock;
+		}
 		count2++;
 		if (!quiet && count2 % 100 == 0) {
 			printf(".");
@@ -316,10 +334,12 @@ int gfs1_ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int quiet)
 	if (count1 != count2)
 		goto fail;
 
+	free(rgbh);
 	return 0;
 
  fail:
-	gfs2_rgrp_free(&sdp->rglist, not_updated);
+	gfs2_rgrp_free(&sdp->rglist);
+	free(rgbh);
 	return -1;
 }
 
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index ffd673c..70cf6cf 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -103,12 +103,10 @@ struct rgrp_list {
 	osi_list_t list;
 	uint64_t start;	   /* The offset of the beginning of this resource group */
 	uint64_t length;	/* The length of this resource group */
-	uint32_t rgf_flags;
+	uint32_t rg_free;       /* Free blocks */
 
 	struct gfs2_rindex ri;
-	struct gfs2_rgrp rg;
-	gfs2_bitmap_t *bits;
-	struct gfs2_buffer_head **bh;
+	struct gfs2_bitmap *bits;
 };
 
 struct gfs2_buffer_head {
@@ -250,7 +248,6 @@ struct gfs2_sbd {
 	unsigned int orig_journals;
 
 	struct buf_list buf_list;   /* transient buffer list */
-	struct buf_list nvbuf_list; /* non-volatile buffer list */
 
 	struct gfs2_inode *master_dir;
 	struct master_dir md;
@@ -360,15 +357,8 @@ struct gfs2_block_query {
         uint8_t eattr_block;
 };
 
-struct gfs2_gbmap {
-        struct gfs2_bmap group_map;
-        struct gfs2_bmap bad_map;
-        struct gfs2_bmap dup_map;
-        struct gfs2_bmap eattr_map;
-};
-
 union gfs2_block_lists {
-        struct gfs2_gbmap gbmap;
+        struct gfs2_bmap gbmap;
 };
 
 /* bitmap implementation */
@@ -571,20 +561,19 @@ struct gfs_dinode {
 	char di_reserved[56];
 };
 
-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);
-void gfs1_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new,
-		    uint64_t *dblock, uint32_t *extlen, int prealloc);
-int gfs1_readi(struct gfs2_inode *ip, void *buf, uint64_t offset,
-	       unsigned int size);
-int gfs1_rindex_read(struct gfs2_sbd *sdp, int fd, int *count1);
-int gfs1_ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount, int quiet);
-struct gfs2_inode *gfs_inode_get(struct gfs2_sbd *sdp,
-				 struct gfs2_buffer_head *bh);
-
-/* locking.c */
-void test_locking(char *lockproto, char *locktable);
+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_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,
+			    int *bitmap_blocks);
+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);
 
 /* gfs2_log.c */
 struct gfs2_options {
@@ -696,38 +685,40 @@ int gfs2_find_jhead(struct gfs2_inode *ip, struct gfs2_log_header *head);
 int clean_journal(struct gfs2_inode *ip, struct gfs2_log_header *head);
 
 /* rgrp.c */
-int gfs2_compute_bitstructs(struct gfs2_sbd *sdp, struct rgrp_list *rgd);
-struct rgrp_list *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, uint64_t blk);
-uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_list *rgd);
-void gfs2_rgrp_relse(struct rgrp_list *rgd, enum update_flags updated);
-void gfs2_rgrp_free(osi_list_t *rglist, enum update_flags updated);
+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,
+			       struct gfs2_buffer_head **bh,
+			       struct gfs2_rgrp *rg);
+extern void gfs2_rgrp_relse(struct rgrp_list *rgd, enum update_flags updated,
+		     struct gfs2_buffer_head **bh);
+extern void gfs2_rgrp_free(osi_list_t *rglist);
 
 /* structures.c */
-void build_master(struct gfs2_sbd *sdp);
-void build_sb(struct gfs2_sbd *sdp, const unsigned char *uuid);
-void build_jindex(struct gfs2_sbd *sdp);
-void build_per_node(struct gfs2_sbd *sdp);
-void build_inum(struct gfs2_sbd *sdp);
-void build_statfs(struct gfs2_sbd *sdp);
-void build_rindex(struct gfs2_sbd *sdp);
-void build_quota(struct gfs2_sbd *sdp);
-void build_root(struct gfs2_sbd *sdp);
-void do_init_inum(struct gfs2_sbd *sdp);
-void do_init_statfs(struct gfs2_sbd *sdp);
-int gfs2_check_meta(struct gfs2_buffer_head *bh, int type);
-int gfs2_set_meta(struct gfs2_buffer_head *bh, int type, int format);
-int gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block, int first);
-int gfs2_next_rg_meta_free(struct rgrp_list *rgd, uint64_t *block, int first,
-						   int *mfree);
-int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
-						  uint64_t *block, uint32_t type, int first);
+extern void build_master(struct gfs2_sbd *sdp);
+extern void build_sb(struct gfs2_sbd *sdp, const unsigned char *uuid);
+extern void build_jindex(struct gfs2_sbd *sdp);
+extern void build_per_node(struct gfs2_sbd *sdp);
+extern void build_inum(struct gfs2_sbd *sdp);
+extern void build_statfs(struct gfs2_sbd *sdp);
+extern void build_rindex(struct gfs2_sbd *sdp);
+extern void build_quota(struct gfs2_sbd *sdp);
+extern void build_root(struct gfs2_sbd *sdp);
+extern void do_init_inum(struct gfs2_sbd *sdp);
+extern void 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 gfs2_sbd *sdp, 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);
 /* super.c */
-int check_sb(struct gfs2_sb *sb);
-int read_sb(struct gfs2_sbd *sdp);
-int ji_update(struct gfs2_sbd *sdp);
-int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1);
-int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount);
-int write_sb(struct gfs2_sbd *sdp);
+extern int check_sb(struct gfs2_sb *sb);
+extern int read_sb(struct gfs2_sbd *sdp);
+extern int ji_update(struct gfs2_sbd *sdp);
+extern int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1,
+		       int *bitmap_blocks);
+extern int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount);
+extern int write_sb(struct gfs2_sbd *sdp);
 
 /* ondisk.c */
 uint32_t gfs2_disk_hash(const char *data, int len);
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index 7bebb3f..9027909 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -85,14 +85,6 @@ int gfs2_compute_bitstructs(struct gfs2_sbd *sdp, struct rgrp_list *rgd)
 	    rgd->bits[length - 1].bi_len) * GFS2_NBBY != rgd->ri.ri_data)
 		return -1;
 
-	if (rgd->bh)      /* If we already have a bh allocated */
-		return 0; /* don't want to allocate another */
-	if(!(rgd->bh = (struct gfs2_buffer_head **)
-		 malloc(length * sizeof(struct gfs2_buffer_head *))))
-		return -1;
-	if(!memset(rgd->bh, 0, length * sizeof(struct gfs2_buffer_head *)))
-		return -1;
-
 	return 0;
 }
 
@@ -127,51 +119,47 @@ 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_list *rgd,
+			struct gfs2_buffer_head **bh, struct gfs2_rgrp *rg)
 {
 	int x, length = rgd->ri.ri_length;
 
 	for (x = 0; x < length; x++){
-		rgd->bh[x] = bread(&sdp->nvbuf_list, rgd->ri.ri_addr + x);
-		if(gfs2_check_meta(rgd->bh[x],
+		bh[x] = bread(&sdp->buf_list, rgd->ri.ri_addr + x);
+		if(gfs2_check_meta(bh[x],
 				   (x) ? GFS2_METATYPE_RB : GFS2_METATYPE_RG))
 		{
 			uint64_t error;
 
 			error = rgd->ri.ri_addr + x;
 			for (; x >= 0; x--)
-				brelse(rgd->bh[x], not_updated);
+				brelse(bh[x], not_updated);
 			return error;
 		}
 	}
 
-	gfs2_rgrp_in(&rgd->rg, rgd->bh[0]->b_data);
+	gfs2_rgrp_in(rg, bh[0]->b_data);
+	rgd->rg_free = rg->rg_free;
 	return 0;
 }
 
-void gfs2_rgrp_relse(struct rgrp_list *rgd, enum update_flags is_updated)
+void gfs2_rgrp_relse(struct rgrp_list *rgd, enum update_flags is_updated,
+		     struct gfs2_buffer_head **bh)
 {
 	int x, length = rgd->ri.ri_length;
 
 	for (x = 0; x < length; x++)
-		brelse(rgd->bh[x], is_updated);
+		brelse(bh[x], is_updated);
 }
 
-void gfs2_rgrp_free(osi_list_t *rglist, enum update_flags is_updated)
+void gfs2_rgrp_free(osi_list_t *rglist)
 {
 	struct rgrp_list *rgd;
 
 	while(!osi_list_empty(rglist->next)){
 		rgd = osi_list_entry(rglist->next, struct rgrp_list, list);
-		if (rgd->bh && rgd->bh[0] && /* if a buffer exists and       */
-			rgd->bh[0]->b_count) /* the 1st buffer is allocated */
-			gfs2_rgrp_relse(rgd, is_updated); /* free them all. */
 		if(rgd->bits)
 			free(rgd->bits);
-		if(rgd->bh) {
-			free(rgd->bh);
-			rgd->bh = NULL;
-		}
 		osi_list_del(&rgd->list);
 		free(rgd);
 	}
diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c
index 43a7e0f..2b63ad2 100644
--- a/gfs2/libgfs2/structures.c
+++ b/gfs2/libgfs2/structures.c
@@ -475,12 +475,14 @@ int gfs2_set_meta(struct gfs2_buffer_head *bh, int type, int format)
  *
  * Returns: 0 on success, -1 when finished
  */
-int gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block, int first)
+int gfs2_next_rg_meta(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
+		      uint64_t *block, int first)
 {
 	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);
 	int i;
+	struct gfs2_buffer_head *bh;
 
 	if(!first && (*block < rgd->ri.ri_data0)) {
 		log_err("next_rg_meta:  Start block is outside rgrp bounds.\n");
@@ -494,14 +496,17 @@ int gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block, int first)
 	}
 	for(; i < length; i++){
 		bits = &rgd->bits[i];
-		blk = gfs2_bitfit((unsigned char *)rgd->bh[i]->b_data +
+		bh = bread(&sdp->buf_list, rgd->ri.ri_addr + i);
+		blk = gfs2_bitfit((unsigned char *)bh->b_data +
 				  bits->bi_offset, bits->bi_len, blk,
 				  GFS2_BLKST_DINODE);
 		if(blk != BFITNOENT){
 			*block = blk + (bits->bi_start * GFS2_NBBY) + rgd->ri.ri_data0;
+			brelse(bh, not_updated);
 			break;
 		}
 		blk=0;
+		brelse(bh, not_updated);
 	}
 	if(i == length)
 		return -1;
@@ -509,71 +514,6 @@ int gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block, int first)
 }
 
 /**
- * gfs2_next_rg_meta_free - finds free or used metadata
- * @rgd:
- * @block:
- * @first: if set, start at zero and ignore block
- *
- * The position to start looking from is *block.  When a block
- * is found, it is returned in block.
- *
- * Returns: 0 on success, -1 when finished
- */
-int gfs2_next_rg_meta_free(struct rgrp_list *rgd, uint64_t *block, int first,
-						   int *mfree)
-{
-	gfs2_bitmap_t *bits = NULL;
-	uint32_t length = rgd->ri.ri_length;
-	uint32_t blk = (first)? 0: (uint32_t)((*block+1)-rgd->ri.ri_data0);
-	uint32_t iblk, ublk, fblk;
-	int i;
-	
-	if(!first && (*block < rgd->ri.ri_data0)) {
-		log_err("next_rg_meta_free:  Start block is outside rgrp bounds.\n");
-		exit(1);
-	}
-	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++){
-		bits = &rgd->bits[i];
-
-		iblk = gfs2_bitfit((unsigned char *)rgd->bh[i]->b_data +
-						   bits->bi_offset, bits->bi_len, blk,
-						   GFS2_BLKST_DINODE);
-		ublk = gfs2_bitfit((unsigned char *)rgd->bh[i]->b_data +
-						   bits->bi_offset, bits->bi_len, blk,
-						   GFS2_BLKST_USED);
-		fblk = gfs2_bitfit((unsigned char *)rgd->bh[i]->b_data +
-						   bits->bi_offset, bits->bi_len, blk,
-						   GFS2_BLKST_FREE);
-		if(ublk < fblk) {
-            blk = ublk;
-            *mfree = 0;
-		}
-		else if(iblk < fblk) {
-            blk = iblk;
-            *mfree = 0;
-		} else {
-            blk = fblk;
-            *mfree = 1;
-		}
-		if(blk != BFITNOENT){
-            *block = blk + (bits->bi_start * GFS2_NBBY) + rgd->ri.ri_data0;
-            break;
-		}
-		blk=0;
-	}
-
-	if(i == length)
-		return -1;
-	return 0;
-}
-
-/**
  * next_rg_metatype
  * @rgd:
  * @block:
@@ -590,7 +530,7 @@ int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
 	do{
 		if (bh)
 			brelse(bh, not_updated);
-		if (gfs2_next_rg_meta(rgd, block, first))
+		if (gfs2_next_rg_meta(sdp, rgd, block, first))
 			return -1;
 		bh = bread(&sdp->buf_list, *block);
 		first = 0;
diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c
index 9a42021..e31268e 100644
--- a/gfs2/libgfs2/super.c
+++ b/gfs2/libgfs2/super.c
@@ -175,7 +175,7 @@ int ji_update(struct gfs2_sbd *sdp)
  *
  * Returns: 0 on success, -1 on failure
  */
-int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1)
+int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1, int *bitmap_blocks)
 {
 	unsigned int rg;
 	int error;
@@ -185,6 +185,7 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1)
 
 	*count1 = 0;
 	prev_rgd = NULL;
+	*bitmap_blocks = 0;
 	for (rg = 0; ; rg++) {
 		if (fd > 0)
 			error = read(fd, &buf, sizeof(struct gfs2_rindex));
@@ -207,6 +208,8 @@ int rindex_read(struct gfs2_sbd *sdp, int fd, int *count1)
 
 		gfs2_rindex_in(&rgd->ri, (char *)&buf);
 
+		if (rgd->ri.ri_length > *bitmap_blocks)
+			*bitmap_blocks = rgd->ri.ri_length;
 		rgd->start = rgd->ri.ri_addr;
 		if (prev_rgd) {
 			prev_length = rgd->start - prev_rgd->start;
@@ -241,19 +244,33 @@ int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount)
 	osi_list_t *tmp;
 	int count1 = 0, count2 = 0;
 	uint64_t errblock = 0;
+	struct gfs2_rgrp rg;
+	struct gfs2_buffer_head **rgbh = NULL;
+	int bitmap_blocks;
 
-	if (rindex_read(sdp, fd, &count1))
+	if (rindex_read(sdp, fd, &count1, &bitmap_blocks))
 	    goto fail;
+
+	if(!(rgbh = (struct gfs2_buffer_head **)
+	     malloc(bitmap_blocks * sizeof(struct gfs2_buffer_head *))))
+		return -1;
+	if(!memset(rgbh, 0, bitmap_blocks *
+		   sizeof(struct gfs2_buffer_head *))) {
+		free(rgbh);
+		return -1;
+	}
+
 	for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
 		enum update_flags f;
 
 		f = not_updated;
 		rgd = osi_list_entry(tmp, struct rgrp_list, list);
-		errblock = gfs2_rgrp_read(sdp, rgd);
-		if (errblock)
+		errblock = gfs2_rgrp_read(sdp, rgd, rgbh, &rg);
+		if (errblock) {
+			free(rgbh);
 			return errblock;
-		else
-			gfs2_rgrp_relse(rgd, f);
+		} else
+			gfs2_rgrp_relse(rgd, f, rgbh);
 		count2++;
 	}
 
@@ -261,10 +278,12 @@ int ri_update(struct gfs2_sbd *sdp, int fd, int *rgcount)
 	if (count1 != count2)
 		goto fail;
 
+	free(rgbh);
 	return 0;
 
  fail:
-	gfs2_rgrp_free(&sdp->rglist, not_updated);
+	gfs2_rgrp_free(&sdp->rglist);
+	free(rgbh);
 	return -1;
 }
 
@@ -276,7 +295,6 @@ int write_sb(struct gfs2_sbd *sbp)
 	gfs2_sb_out(&sbp->sd_sb, bh->b_data);
 	brelse(bh, updated);
 	bcommit(&sbp->buf_list); /* make sure the change gets to disk ASAP */
-	bcommit(&sbp->nvbuf_list); /* make sure the change gets to disk ASAP */
 	return 0;
 }
 
diff --git a/gfs2/mkfs/main_grow.c b/gfs2/mkfs/main_grow.c
index 879f399..60082a9 100644
--- a/gfs2/mkfs/main_grow.c
+++ b/gfs2/mkfs/main_grow.c
@@ -187,7 +187,6 @@ static void initialize_new_portion(struct gfs2_sbd *sdp, int *old_rg_count)
 
 	/* We're done with the libgfs portion, so commit it to disk.      */
 	bsync(&sdp->buf_list);
-	bsync(&sdp->nvbuf_list);
 }
 
 /**
@@ -286,8 +285,7 @@ main_grow(int argc, char *argv[])
 		device_geometry(sdp);
 		log_info( _("Initializing lists...\n"));
 		osi_list_init(&sdp->rglist);
-		init_buf_list(sdp, &sdp->buf_list, 128 << 20);
-		init_buf_list(sdp, &sdp->nvbuf_list, 0xffffffff);
+		init_buf_list(sdp, &sdp->buf_list, 1 << 20);
 
 		sdp->sd_sb.sb_bsize = GFS2_DEFAULT_BSIZE;
 		sdp->bsize = sdp->sd_sb.sb_bsize;
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index 9eb4761..67b552b 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -437,8 +437,7 @@ main_mkfs(int argc, char *argv[])
 	strcpy(sdp->lockproto, GFS2_DEFAULT_LOCKPROTO);
 	sdp->time = time(NULL);
 	osi_list_init(&sdp->rglist);
-	init_buf_list(sdp, &sdp->buf_list, 128 << 20);
-	init_buf_list(sdp, &sdp->nvbuf_list, 0xffffffff);
+	init_buf_list(sdp, &sdp->buf_list, 1 << 20);
 
 	decode_arguments(argc, argv, sdp);
 	if (sdp->rgsize == -1)                 /* if rg size not specified */
@@ -509,7 +508,6 @@ main_mkfs(int argc, char *argv[])
 	inode_put(sdp->md.inum, updated);
 	inode_put(sdp->md.statfs, updated);
 	bsync(&sdp->buf_list);
-	bsync(&sdp->nvbuf_list);
 
 	error = fsync(sdp->device_fd);
 	if (error)
diff --git a/gfs2/tool/df.c b/gfs2/tool/df.c
index 3dbfd46..025fc85 100644
--- a/gfs2/tool/df.c
+++ b/gfs2/tool/df.c
@@ -113,7 +113,6 @@ do_df_one(char *path)
 	sbd.qcsize = GFS2_DEFAULT_QCSIZE;
 	osi_list_init(&sbd.rglist);
 	init_buf_list(&sbd, &sbd.buf_list, 128 << 20);
-	init_buf_list(&sbd, &sbd.nvbuf_list, 0xffffffff);
 
 	do_lseek(sbd.device_fd, 0x10 * sbd.bsize);
 	do_read(sbd.device_fd, buf, sbd.bsize); /* read in the superblock */