gfs2-utils: RHEL7 - libgfs2: Move bitmap buffers inside struct gfs2_bitmap

Andrew Price andyp at fedoraproject.org
Mon Sep 8 17:34:11 UTC 2014


Gitweb:        http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=e42a9392ecd663ea82903e9a3a86952ad9fc0af0
Commit:        e42a9392ecd663ea82903e9a3a86952ad9fc0af0
Parent:        8e3a9dfa499956d55ee96ffd618aceb6dd7a7434
Author:        Andrew Price <anprice at redhat.com>
AuthorDate:    Thu Jun 12 03:54:15 2014 +0100
Committer:     Andrew Price <anprice at redhat.com>
CommitterDate: Fri Sep 5 14:57:46 2014 +0100

libgfs2: Move bitmap buffers inside struct gfs2_bitmap

Keeping an array of buffers alongside the array of bitmaps meant some
extra management and bookkeeping for arrays of buffer pointers. Move the
buffer pointers into the bitmap structures.

The only downside to this is that reading resource groups gets a little
more complicated and an intermediate array of buffer pointers is created
in gfs2_rgrp_read to make sure we can still use vector i/o. Fortunately
this doesn't cause any noticeable slowdown.

Signed-off-by: Andrew Price <anprice at redhat.com>
---
 gfs2/convert/gfs2_convert.c |   42 +++++++++++---------------
 gfs2/edit/journal.c         |    6 ++--
 gfs2/fsck/fs_recovery.c     |    2 +-
 gfs2/fsck/initialize.c      |   15 ++++-----
 gfs2/fsck/metawalk.c        |   10 ++----
 gfs2/fsck/pass5.c           |    9 ++---
 gfs2/fsck/rgrepair.c        |   14 ++++-----
 gfs2/fsck/util.c            |    2 +-
 gfs2/libgfs2/fs_bits.c      |   10 ++++--
 gfs2/libgfs2/fs_geometry.c  |    6 ++--
 gfs2/libgfs2/fs_ops.c       |   16 +++++-----
 gfs2/libgfs2/libgfs2.h      |    2 +-
 gfs2/libgfs2/rgrp.c         |   70 +++++++++++++++++++++---------------------
 gfs2/libgfs2/structures.c   |    2 +-
 14 files changed, 98 insertions(+), 108 deletions(-)

diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index 87bec8c..61ed320 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -142,16 +142,18 @@ static void convert_bitmaps(struct gfs2_sbd *sdp, struct rgrp_tree *rg)
 
 	ri = &rg->ri;
 	for (blk = 0; blk < ri->ri_length; blk++) {
+		struct gfs2_bitmap *bi;
 		x = (blk) ? sizeof(struct gfs2_meta_header) :
 			sizeof(struct gfs2_rgrp);
 
+		bi = &rg->bits[blk];
 		for (; x < sdp->bsize; x++)
 			for (y = 0; y < GFS2_NBBY; y++) {
-				state = (rg->bh[blk]->b_data[x] >>
+				state = (bi->bi_bh->b_data[x] >>
 					 (GFS2_BIT_SIZE * y)) & 0x03;
 				if (state == 0x02) {/* unallocated metadata state invalid */
-					rg->bh[blk]->b_data[x] &= ~(0x02 << (GFS2_BIT_SIZE * y));
-					bmodified(rg->bh[blk]);
+					bi->bi_bh->b_data[x] &= ~(0x02 << (GFS2_BIT_SIZE * y));
+					bmodified(bi->bi_bh);
 				}
 			}
 	}
@@ -188,7 +190,7 @@ static int convert_rgs(struct gfs2_sbd *sbp)
 		sbp->dinodes_alloced += rgd1->rg_useddi;
 		convert_bitmaps(sbp, rgd);
 		/* Write the updated rgrp to the gfs2 buffer */
-		gfs2_rgrp_out_bh(&rgd->rg, rgd->bh[0]);
+		gfs2_rgrp_out_bh(&rgd->rg, rgd->bits[0].bi_bh);
 		rgs++;
 		if (rgs % 100 == 0) {
 			printf(".");
@@ -969,8 +971,8 @@ static int next_rg_meta(struct rgrp_tree *rgd, uint64_t *block, int first)
 	}
 	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);
+		blk = gfs2_bitfit((uint8_t *)bits->bi_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;
@@ -1073,16 +1075,17 @@ static int inode_renumber(struct gfs2_sbd *sbp, uint64_t root_inode_addr, osi_li
 				byte_bit = (block - rgd->ri.ri_data0) % GFS2_NBBY;
 				/* Now figure out which bitmap block the byte is on */
 				for (blk = 0; blk < rgd->ri.ri_length; blk++) {
+					struct gfs2_bitmap *bi = &rgd->bits[blk];
 					/* figure out offset of first bitmap byte for this map: */
 					buf_offset = (blk) ? sizeof(struct gfs2_meta_header) :
 						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] &=
+						bi->bi_bh->b_data[buf_offset + bitmap_byte] &=
 							~(0x03 << (GFS2_BIT_SIZE * byte_bit));
-						rgd->bh[blk]->b_data[buf_offset + bitmap_byte] |=
+						bi->bi_bh->b_data[buf_offset + bitmap_byte] |=
 							(0x01 << (GFS2_BIT_SIZE * byte_bit));
-						bmodified(rgd->bh[blk]);
+						bmodified(bi->bi_bh);
 						break;
 					}
 					bitmap_byte -= (sbp->bsize - buf_offset);
@@ -1854,29 +1857,20 @@ static int journ_space_to_rg(struct gfs2_sbd *sdp)
 		rgd->rg.rg_free = rgd->ri.ri_data;
 		rgd->ri.ri_bitbytes = rgd->ri.ri_data / GFS2_NBBY;
 
-		if(!(rgd->bh = (struct gfs2_buffer_head **)
-		     malloc(rgd->ri.ri_length *
-			    sizeof(struct gfs2_buffer_head *))))
-			return -1;
-		if(!memset(rgd->bh, 0, rgd->ri.ri_length *
-			   sizeof(struct gfs2_buffer_head *))) {
-			free(rgd->bh);
-			return -1;
-		}
-		for (x = 0; x < rgd->ri.ri_length; x++) {
-			rgd->bh[x] = bget(sdp, rgd->ri.ri_addr + x);
-			memset(rgd->bh[x]->b_data, 0, sdp->bsize);
-		}
 		if (gfs2_compute_bitstructs(sdp->sd_sb.sb_bsize, rgd)) {
 			log_crit(_("gfs2_convert: Error converting bitmaps.\n"));
 			exit(-1);
 		}
+
+		for (x = 0; x < rgd->ri.ri_length; x++)
+			rgd->bits[x].bi_bh = bget(sdp, rgd->ri.ri_addr + x);
+
 		convert_bitmaps(sdp, rgd);
 		for (x = 0; x < rgd->ri.ri_length; x++) {
 			if (x)
-				gfs2_meta_header_out_bh(&mh, rgd->bh[x]);
+				gfs2_meta_header_out_bh(&mh, rgd->bits[x].bi_bh);
 			else
-				gfs2_rgrp_out_bh(&rgd->rg, rgd->bh[x]);
+				gfs2_rgrp_out_bh(&rgd->rg, rgd->bits[x].bi_bh);
 		}
 	} /* for each journal */
 	return error;
diff --git a/gfs2/edit/journal.c b/gfs2/edit/journal.c
index a72a044..5b824a4 100644
--- a/gfs2/edit/journal.c
+++ b/gfs2/edit/journal.c
@@ -259,14 +259,14 @@ static int print_ld_blks(const uint64_t *b, const char *end, int start_line,
 						      sizeof(struct gfs2_meta_header))
 							* GFS2_NBBY;
 					bmap = o / sbd.sd_blocks_per_bitmap;
-					save_bh = rgd->bh[bmap];
+					save_bh = rgd->bits[bmap].bi_bh;
 					j_bmap_bh = bread(&sbd, abs_block +
 							  bcount);
-					rgd->bh[bmap] = j_bmap_bh;
+					rgd->bits[bmap].bi_bh = j_bmap_bh;
 					type = lgfs2_get_bitmap(&sbd, tblk,
 								rgd);
 					brelse(j_bmap_bh);
-					rgd->bh[bmap] = save_bh;
+					rgd->bits[bmap].bi_bh = save_bh;
 					print_gfs2("bit for blk 0x%llx is %d "
 						   "(%s)",
 						   (unsigned long long)tblk,
diff --git a/gfs2/fsck/fs_recovery.c b/gfs2/fsck/fs_recovery.c
index a052487..bc4210d 100644
--- a/gfs2/fsck/fs_recovery.c
+++ b/gfs2/fsck/fs_recovery.c
@@ -652,7 +652,7 @@ int replay_journals(struct gfs2_sbd *sdp, int preen, int force_check,
 			 * don't segfault. */
 			rgd.start = sdp->sb_addr + 1;
 			rgd.length = 1;
-			rgd.bh = NULL;
+			bits.bi_bh = NULL;
 			bits.bi_start = 0;
 			bits.bi_len = sdp->fssize / GFS2_NBBY;
 			rgd.bits = &bits;
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
index f7ea45f..02ecd3f 100644
--- a/gfs2/fsck/initialize.c
+++ b/gfs2/fsck/initialize.c
@@ -222,7 +222,7 @@ static void check_rgrp_integrity(struct gfs2_sbd *sdp, struct rgrp_tree *rgd,
 		for (x = 0; x < bytes_to_check; x++) {
 			unsigned char *byte;
 
-			byte = (unsigned char *)&rgd->bh[rgb]->b_data[off + x];
+			byte = (unsigned char *)&rgd->bits[rgb].bi_bh->b_data[off + x];
 			if (*byte == 0x55) {
 				diblock += GFS2_NBBY;
 				continue;
@@ -277,7 +277,7 @@ static void check_rgrp_integrity(struct gfs2_sbd *sdp, struct rgrp_tree *rgd,
 				}
 				*byte &= ~(GFS2_BIT_MASK <<
 					   (GFS2_BIT_SIZE * y));
-				bmodified(rgd->bh[rgb]);
+				bmodified(rgd->bits[rgb].bi_bh);
 				rg_reclaimed++;
 				rg_free++;
 				rgd->rg.rg_free++;
@@ -314,9 +314,9 @@ static void check_rgrp_integrity(struct gfs2_sbd *sdp, struct rgrp_tree *rgd,
 	   will be reported. */
 	if (rg_reclaimed && *fixit) {
 		if (sdp->gfs1)
-			gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bh[0]);
+			gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bits[0].bi_bh);
 		else
-			gfs2_rgrp_out_bh(&rgd->rg, rgd->bh[0]);
+			gfs2_rgrp_out_bh(&rgd->rg, rgd->bits[0].bi_bh);
 		*this_rg_cleaned = 1;
 		log_info( _("The rgrp at %lld (0x%llx) was cleaned of %d "
 			    "free metadata blocks.\n"),
@@ -335,10 +335,9 @@ static void check_rgrp_integrity(struct gfs2_sbd *sdp, struct rgrp_tree *rgd,
 		if (query( _("Fix the rgrp free blocks count? (y/n)"))) {
 			rgd->rg.rg_free = rg_free;
 			if (sdp->gfs1)
-				gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg,
-					     rgd->bh[0]);
+				gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bits[0].bi_bh);
 			else
-				gfs2_rgrp_out_bh(&rgd->rg, rgd->bh[0]);
+				gfs2_rgrp_out_bh(&rgd->rg, rgd->bits[0].bi_bh);
 			*this_rg_fixed = 1;
 			log_err( _("The rgrp was fixed.\n"));
 		} else
@@ -354,7 +353,7 @@ static void check_rgrp_integrity(struct gfs2_sbd *sdp, struct rgrp_tree *rgd,
 			 gfs1rg->rg_freemeta, rg_unlinked);
 		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]);
+			gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bits[0].bi_bh);
 			*this_rg_fixed = 1;
 			log_err( _("The rgrp was fixed.\n"));
 		} else
diff --git a/gfs2/fsck/metawalk.c b/gfs2/fsck/metawalk.c
index 8da17c6..329fc3b 100644
--- a/gfs2/fsck/metawalk.c
+++ b/gfs2/fsck/metawalk.c
@@ -91,17 +91,15 @@ int check_n_fix_bitmap(struct gfs2_sbd *sdp, uint64_t blk, int error_on_dinode,
 				}
 				rgd->rg.rg_free++;
 				if (sdp->gfs1)
-					gfs_rgrp_out((struct gfs_rgrp *)
-						     &rgd->rg, rgd->bh[0]);
+					gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bits[0].bi_bh);
 				else
-					gfs2_rgrp_out_bh(&rgd->rg, rgd->bh[0]);
+					gfs2_rgrp_out_bh(&rgd->rg, rgd->bits[0].bi_bh);
 			} else if (old_bitmap_state == GFS2_BLKST_FREE) {
 				rgd->rg.rg_free--;
 				if (sdp->gfs1)
-					gfs_rgrp_out((struct gfs_rgrp *)
-						     &rgd->rg, rgd->bh[0]);
+					gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bits[0].bi_bh);
 				else
-					gfs2_rgrp_out_bh(&rgd->rg, rgd->bh[0]);
+					gfs2_rgrp_out_bh(&rgd->rg, rgd->bits[0].bi_bh);
 			}
 			log_err( _("The bitmap was fixed.\n"));
 		} else {
diff --git a/gfs2/fsck/pass5.c b/gfs2/fsck/pass5.c
index 68b1373..b2e8adf 100644
--- a/gfs2/fsck/pass5.c
+++ b/gfs2/fsck/pass5.c
@@ -218,9 +218,8 @@ static void update_rgrp(struct gfs2_sbd *sdp, struct rgrp_tree *rgp,
 		bits = &rgp->bits[i];
 
 		/* update the bitmaps */
-		if (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, bits->bi_bh->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;
@@ -275,9 +274,9 @@ static void update_rgrp(struct gfs2_sbd *sdp, struct rgrp_tree *rgp,
 			log_warn( _("Resource group counts updated\n"));
 			/* write out the rgrp */
 			if (sdp->gfs1)
-				gfs_rgrp_out(gfs1rg, rgp->bh[0]);
+				gfs_rgrp_out(gfs1rg, rgp->bits[0].bi_bh);
 			else
-				gfs2_rgrp_out_bh(&rgp->rg, rgp->bh[0]);
+				gfs2_rgrp_out_bh(&rgp->rg, rgp->bits[0].bi_bh);
 		} else
 			log_err( _("Resource group counts left inconsistent\n"));
 	}
diff --git a/gfs2/fsck/rgrepair.c b/gfs2/fsck/rgrepair.c
index 0466dd8..dd197d6 100644
--- a/gfs2/fsck/rgrepair.c
+++ b/gfs2/fsck/rgrepair.c
@@ -658,14 +658,14 @@ static int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_tree *rg,
 		 (int)x+1, (int)rg->ri.ri_length, typedesc);
 	if (query( _("Fix the Resource Group? (y/n)"))) {
 		log_err( _("Attempting to repair the rgrp.\n"));
-		rg->bh[x] = bread(sdp, rg->ri.ri_addr + x);
+		rg->bits[x].bi_bh = bread(sdp, rg->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_bh(&mh, rg->bh[x]);
+			gfs2_meta_header_out_bh(&mh, rg->bits[x].bi_bh);
 		} else {
 			if (sdp->gfs1)
 				memset(&rg->rg, 0, sizeof(struct gfs_rgrp));
@@ -676,13 +676,12 @@ static int rewrite_rg_block(struct gfs2_sbd *sdp, struct rgrp_tree *rg,
 			rg->rg.rg_header.mh_format = GFS2_FORMAT_RG;
 			rg->rg.rg_free = rg->ri.ri_data;
 			if (sdp->gfs1)
-				gfs_rgrp_out((struct gfs_rgrp *)&rg->rg,
-					     rg->bh[x]);
+				gfs_rgrp_out((struct gfs_rgrp *)&rg->rg, rg->bits[x].bi_bh);
 			else
-				gfs2_rgrp_out_bh(&rg->rg, rg->bh[x]);
+				gfs2_rgrp_out_bh(&rg->rg, rg->bits[x].bi_bh);
 		}
-		brelse(rg->bh[x]);
-		rg->bh[x] = NULL;
+		brelse(rg->bits[x].bi_bh);
+		rg->bits[x].bi_bh = NULL;
 		return 0;
 	}
 	return 1;
@@ -712,7 +711,6 @@ static int expect_rindex_sanity(struct gfs2_sbd *sdp, int *num_rgs)
 		memcpy(&exp->ri, &rgd->ri, sizeof(exp->ri));
 		memcpy(&exp->rg, &rgd->rg, sizeof(exp->rg));
 		exp->bits = NULL;
-		exp->bh = NULL;
 		gfs2_compute_bitstructs(sdp->sd_sb.sb_bsize, exp);
 	}
 	sdp->rgrps = *num_rgs;
diff --git a/gfs2/fsck/util.c b/gfs2/fsck/util.c
index 8b439a9..a0f6009 100644
--- a/gfs2/fsck/util.c
+++ b/gfs2/fsck/util.c
@@ -680,7 +680,7 @@ uint64_t find_free_blk(struct gfs2_sbd *sdp)
 	rg = &rl->rg;
 
 	for (block = 0; block < ri->ri_length; block++) {
-		bh = rl->bh[block];
+		bh = rl->bits[block].bi_bh;
 		x = (block) ? sizeof(struct gfs2_meta_header) : sizeof(struct gfs2_rgrp);
 
 		for (; x < sdp->bsize; x++)
diff --git a/gfs2/libgfs2/fs_bits.c b/gfs2/libgfs2/fs_bits.c
index 7194949..93ddc13 100644
--- a/gfs2/libgfs2/fs_bits.c
+++ b/gfs2/libgfs2/fs_bits.c
@@ -148,7 +148,7 @@ int gfs2_set_bitmap(lgfs2_rgrp_t rgd, uint64_t blkno, int state)
 
 	if (bits == NULL)
 		return -1;
-	byte = (unsigned char *)(rgd->bh[buf]->b_data + bits->bi_offset) +
+	byte = (unsigned char *)(bits->bi_bh->b_data + bits->bi_offset) +
 		(rgrp_block/GFS2_NBBY - bits->bi_start);
 	bit = (rgrp_block % GFS2_NBBY) * GFS2_BIT_SIZE;
 
@@ -156,7 +156,7 @@ int gfs2_set_bitmap(lgfs2_rgrp_t rgd, uint64_t blkno, int state)
 	*byte ^= cur_state << bit;
 	*byte |= state << bit;
 
-	bmodified(rgd->bh[buf]);
+	bmodified(bits->bi_bh);
 	return 0;
 }
 
@@ -181,6 +181,7 @@ int lgfs2_get_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, struct rgrp_tree *rgd
 	uint32_t i = 0;
 	char *byte;
 	unsigned int bit;
+	struct gfs2_bitmap *bi;
 
 	if (rgd == NULL) {
 		rgd = gfs2_blk2rgrpd(sdp, blkno);
@@ -205,10 +206,11 @@ int lgfs2_get_bitmap(struct gfs2_sbd *sdp, uint64_t blkno, struct rgrp_tree *rgd
 		offset -= i * sdp->sd_blocks_per_bitmap;
 	}
 
-	if (!rgd->bh || !rgd->bh[i])
+	bi = &rgd->bits[i];
+	if (!bi->bi_bh)
 		return GFS2_BLKST_FREE;
 
-	byte = (rgd->bh[i]->b_data + rgd->bits[i].bi_offset) + (offset/GFS2_NBBY);
+	byte = (bi->bi_bh->b_data + bi->bi_offset) + (offset/GFS2_NBBY);
 	bit = (offset % GFS2_NBBY) * GFS2_BIT_SIZE;
 
 	return (*byte >> bit) & GFS2_BIT_MASK;
diff --git a/gfs2/libgfs2/fs_geometry.c b/gfs2/libgfs2/fs_geometry.c
index 587ceb8..c378dba 100644
--- a/gfs2/libgfs2/fs_geometry.c
+++ b/gfs2/libgfs2/fs_geometry.c
@@ -213,11 +213,11 @@ int build_rgrps(struct gfs2_sbd *sdp, int do_write)
 
 		if (do_write) {
 			for (x = 0; x < bitblocks; x++) {
-				rl->bh[x] = bget(sdp, rl->start + x);
+				rl->bits[x].bi_bh = bget(sdp, rl->start + x);
 				if (x)
-					gfs2_meta_header_out_bh(&mh, rl->bh[x]);
+					gfs2_meta_header_out_bh(&mh, rl->bits[x].bi_bh);
 				else
-					gfs2_rgrp_out_bh(&rl->rg, rl->bh[x]);
+					gfs2_rgrp_out_bh(&rl->rg, rl->bits[x].bi_bh);
 			}
 		}
 
diff --git a/gfs2/libgfs2/fs_ops.c b/gfs2/libgfs2/fs_ops.c
index 015b974..aa95aa8 100644
--- a/gfs2/libgfs2/fs_ops.c
+++ b/gfs2/libgfs2/fs_ops.c
@@ -126,7 +126,7 @@ static uint64_t find_free_block(struct rgrp_tree *rgd)
 		unsigned long blk = 0;
 		struct gfs2_bitmap *bits = &rgd->bits[bm];
 
-		blk = gfs2_bitfit((unsigned char *)rgd->bh[bm]->b_data + bits->bi_offset,
+		blk = gfs2_bitfit((uint8_t *)bits->bi_bh->b_data + bits->bi_offset,
 		                  bits->bi_len, blk, GFS2_BLKST_FREE);
 		if (blk != BFITNOENT) {
 			blkno = blk + (bits->bi_start * GFS2_NBBY) + rgd->ri.ri_data0;
@@ -149,9 +149,9 @@ static int blk_alloc_in_rg(struct gfs2_sbd *sdp, unsigned state, struct rgrp_tre
 
 	rgd->rg.rg_free--;
 	if (sdp->gfs1)
-		gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bh[0]);
+		gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bits[0].bi_bh);
 	else
-		gfs2_rgrp_out_bh(&rgd->rg, rgd->bh[0]);
+		gfs2_rgrp_out_bh(&rgd->rg, rgd->bits[0].bi_bh);
 
 	sdp->blks_alloced++;
 	return 0;
@@ -178,7 +178,7 @@ static int block_alloc(struct gfs2_sbd *sdp, const uint64_t blksreq, int state,
 	if (rgt == NULL)
 		return -1;
 
-	if (rgt->bh[0] == NULL) {
+	if (rgt->bits[0].bi_bh == NULL) {
 		if (gfs2_rgrp_read(sdp, rgt))
 			return -1;
 		release = 1;
@@ -1767,9 +1767,9 @@ void gfs2_free_block(struct gfs2_sbd *sdp, uint64_t block)
 		gfs2_set_bitmap(rgd, block, GFS2_BLKST_FREE);
 		rgd->rg.rg_free++; /* adjust the free count */
 		if (sdp->gfs1)
-			gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bh[0]);
+			gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bits[0].bi_bh);
 		else
-			gfs2_rgrp_out_bh(&rgd->rg, rgd->bh[0]);
+			gfs2_rgrp_out_bh(&rgd->rg, rgd->bits[0].bi_bh);
 		sdp->blks_alloced--;
 	}
 }
@@ -1836,9 +1836,9 @@ int gfs2_freedi(struct gfs2_sbd *sdp, uint64_t diblock)
 	rgd->rg.rg_free++;
 	rgd->rg.rg_dinodes--;
 	if (sdp->gfs1)
-		gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bh[0]);
+		gfs_rgrp_out((struct gfs_rgrp *)&rgd->rg, rgd->bits[0].bi_bh);
 	else
-		gfs2_rgrp_out_bh(&rgd->rg, rgd->bh[0]);
+		gfs2_rgrp_out_bh(&rgd->rg, rgd->bits[0].bi_bh);
 	sdp->dinodes_alloced--;
 	return 0;
 }
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 2ba97d6..71da81e 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -170,6 +170,7 @@ struct device {
 
 struct gfs2_bitmap
 {
+	struct gfs2_buffer_head *bi_bh;
 	uint32_t   bi_offset;  /* The offset in the buffer of the first byte */
 	uint32_t   bi_start;   /* The position of the first byte in this block */
 	uint32_t   bi_len;     /* The number of bytes in this block */
@@ -185,7 +186,6 @@ struct rgrp_tree {
 	struct gfs2_rindex ri;
 	struct gfs2_rgrp rg;
 	struct gfs2_bitmap *bits;
-	struct gfs2_buffer_head **bh;
 };
 
 typedef struct rgrp_tree *lgfs2_rgrp_t;
diff --git a/gfs2/libgfs2/rgrp.c b/gfs2/libgfs2/rgrp.c
index c529594..e929846 100644
--- a/gfs2/libgfs2/rgrp.c
+++ b/gfs2/libgfs2/rgrp.c
@@ -67,11 +67,6 @@ int gfs2_compute_bitstructs(const uint32_t bsize, struct rgrp_tree *rgd)
 	    rgd->bits[length - 1].bi_len) * GFS2_NBBY != rgd->ri.ri_data)
 		goto errbits;
 
-	if (rgd->bh == NULL) {
-		rgd->bh = calloc(length, sizeof(struct gfs2_buffer_head *));
-		if (rgd->bh == NULL)
-			goto errbits;
-	}
 	return 0;
 errbits:
 	if (ownbits)
@@ -108,8 +103,9 @@ struct rgrp_tree *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, uint64_t blk)
  */
 uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_tree *rgd)
 {
-	int x, length = rgd->ri.ri_length;
+	unsigned x, length = rgd->ri.ri_length;
 	uint64_t max_rgrp_bitbytes, max_rgrp_len;
+	struct gfs2_buffer_head **bhs;
 
 	/* Max size of an rgrp is 2GB.  Figure out how many blocks that is: */
 	max_rgrp_bitbytes = ((2147483648 / sdp->bsize) / GFS2_NBBY);
@@ -118,27 +114,38 @@ uint64_t gfs2_rgrp_read(struct gfs2_sbd *sdp, struct rgrp_tree *rgd)
 		return -1;
 	if (gfs2_check_range(sdp, rgd->ri.ri_addr))
 		return -1;
-	if (breadm(sdp, rgd->bh, length, rgd->ri.ri_addr))
+
+	bhs = calloc(length, sizeof(struct gfs2_buffer_head *));
+	if (bhs == NULL)
+		return -1;
+
+	if (breadm(sdp, bhs, length, rgd->ri.ri_addr)) {
+		free(bhs);
 		return -1;
-	for (x = 0; x < length; x++){
-		if(gfs2_check_meta(rgd->bh[x], (x) ? GFS2_METATYPE_RB : GFS2_METATYPE_RG))
-		{
-			uint64_t error;
+	}
+
+	for (x = 0; x < length; x++) {
+		struct gfs2_bitmap *bi = &rgd->bits[x];
+		int mtype = (x ? GFS2_METATYPE_RB : GFS2_METATYPE_RG);
 
-			error = rgd->ri.ri_addr + x;
+		bi->bi_bh = bhs[x];
+		if (gfs2_check_meta(bi->bi_bh, mtype)) {
+			unsigned err = x;
 			for (; x >= 0; x--) {
-				brelse(rgd->bh[x]);
-				rgd->bh[x] = NULL;
+				brelse(rgd->bits[x].bi_bh);
+				rgd->bits[x].bi_bh = NULL;
 			}
-			return error;
+			free(bhs);
+			return rgd->ri.ri_addr + err;
 		}
 	}
-	if (rgd->bh && rgd->bh[0]) {
+	if (x > 0) {
 		if (sdp->gfs1)
-			gfs_rgrp_in((struct gfs_rgrp *)&rgd->rg, rgd->bh[0]);
+			gfs_rgrp_in((struct gfs_rgrp *)&rgd->rg, rgd->bits[0].bi_bh);
 		else
-			gfs2_rgrp_in(&rgd->rg, rgd->bh[0]);
+			gfs2_rgrp_in(&rgd->rg, rgd->bits[0].bi_bh);
 	}
+	free(bhs);
 	return 0;
 }
 
@@ -147,10 +154,9 @@ void gfs2_rgrp_relse(struct rgrp_tree *rgd)
 	int x, length = rgd->ri.ri_length;
 
 	for (x = 0; x < length; x++) {
-		if (rgd->bh) {
-			if (rgd->bh[x])
-				brelse(rgd->bh[x]);
-			rgd->bh[x] = NULL;
+		if (rgd->bits[x].bi_bh) {
+			brelse(rgd->bits[x].bi_bh);
+			rgd->bits[x].bi_bh = NULL;
 		}
 	}
 }
@@ -193,11 +199,12 @@ void gfs2_rgrp_free(struct osi_root *rgrp_tree)
 
 	while ((n = osi_first(rgrp_tree))) {
 		rgd = (struct rgrp_tree *)n;
-		if (rgd->bh && rgd->bh[0]) { /* if a buffer exists        */
+
+		if (rgd->bits[0].bi_bh) { /* if a buffer exists */
 			rgs_since_sync++;
 			if (rgs_since_sync >= RG_SYNC_TOLERANCE) {
 				if (!sdp)
-					sdp = rgd->bh[0]->sdp;
+					sdp = rgd->bits[0].bi_bh->sdp;
 				fsync(sdp->device_fd);
 				rgs_since_sync = 0;
 			}
@@ -205,10 +212,6 @@ void gfs2_rgrp_free(struct osi_root *rgrp_tree)
 		}
 		if(rgd->bits)
 			free(rgd->bits);
-		if(rgd->bh) {
-			free(rgd->bh);
-			rgd->bh = NULL;
-		}
 		osi_erase(&rgd->node, rgrp_tree);
 		free(rgd);
 	}
@@ -407,9 +410,9 @@ void lgfs2_rgrps_free(lgfs2_rgrps_t *rgs)
 	while ((rg = (struct rgrp_tree *)osi_first(tree))) {
 		int i;
 		for (i = 0; i < rg->ri.ri_length; i++) {
-			if (rg->bh[i] != NULL) {
-				free(rg->bh[i]);
-				rg->bh[i] = NULL;
+			if (rg->bits[i].bi_bh != NULL) {
+				free(rg->bits[i].bi_bh);
+				rg->bits[i].bi_bh = NULL;
 			}
 		}
 		osi_erase(&rg->node, tree);
@@ -521,14 +524,11 @@ lgfs2_rgrp_t lgfs2_rgrps_append(lgfs2_rgrps_t rgs, struct gfs2_rindex *entry)
 		link = &lastrg->node.osi_right;
 	}
 
-	rg = calloc(1, sizeof(*rg) +
-	              (entry->ri_length * sizeof(struct gfs2_bitmap)) +
-	              (entry->ri_length * sizeof(struct gfs2_buffer_head *)));
+	rg = calloc(1, sizeof(*rg) + (entry->ri_length * sizeof(struct gfs2_bitmap)));
 	if (rg == NULL)
 		return NULL;
 
 	rg->bits = (struct gfs2_bitmap *)(rg + 1);
-	rg->bh = (struct gfs2_buffer_head **)(rg->bits + entry->ri_length);
 
 	osi_link_node(&rg->node, parent, link);
 	osi_insert_color(&rg->node, &rgs->root);
diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c
index ee49dce..9d90657 100644
--- a/gfs2/libgfs2/structures.c
+++ b/gfs2/libgfs2/structures.c
@@ -560,7 +560,7 @@ unsigned lgfs2_bm_scan(struct rgrp_tree *rgd, unsigned idx, uint64_t *buf, uint8
 	uint32_t blk = 0;
 
 	while(blk < (bi->bi_len * GFS2_NBBY)) {
-		blk = gfs2_bitfit((const unsigned char *)rgd->bh[idx]->b_data + bi->bi_offset,
+		blk = gfs2_bitfit((uint8_t *)bi->bi_bh->b_data + bi->bi_offset,
 				  bi->bi_len, blk, state);
 		if (blk == BFITNOENT)
 			break;


More information about the cluster-commits mailing list