A new user interface for you! Read more...

File gfs2_mkfs_segfaults_with_18.55T_and_b512.patch of Package cluster

commit d3af317da0bccfe12814c06c0723c0dd1657df17
Author: Bob Peterson <rpeterso@redhat.com>
Date:   Wed Jan 19 12:45:20 2011 -0600

    GFS2: mkfs.gfs2 segfaults with 18.55TB and -b512
    
    The problem was that mkfs.gfs2 attempted to keep the number of resource
    groups as low as possible, but in so doing, it chose a rgrp size that
    required an enormous number of bitmap blocks per rgrp.  In fact, it
    tried to use more than it could possibly address, given the small
    block size.  Therefore, an error was flagged and mkfs.gfs2 aborted.
    This patch ensures that mkfs.gfs2 chooses a rgrp size that takes into
    account the maximum number of bitmap blocks.  If it hits the max
    number of bitmap blocks, it backs off on its rgrp size and uses a
    smaller size.  The smaller size rgrp ensures that a valid number of
    bitmap blocks will be needed to represent all the blocks in each rgrp.
    
    rhbz#624535

diff --git a/gfs2/libgfs2/fs_geometry.c b/gfs2/libgfs2/fs_geometry.c
index a06e8a2..a15c31f 100644
--- a/gfs2/libgfs2/fs_geometry.c
+++ b/gfs2/libgfs2/fs_geometry.c
@@ -25,21 +25,42 @@
 static uint64_t how_many_rgrps(struct gfs2_sbd *sdp, struct device *dev, int rgsize_specified)
 {
 	uint64_t nrgrp;
+	uint32_t rgblocks1, rgblocksn, bitblocks1, bitblocksn;
+	int bitmap_overflow = 0;
 
 	while (TRUE) {
 		nrgrp = DIV_RU(dev->length, (sdp->rgsize << 20) / sdp->bsize);
 
-		if (rgsize_specified || /* If user specified an rg size or */
-			nrgrp <= GFS2_EXCESSIVE_RGS || /* not an excessive # of rgs or  */
-			sdp->rgsize >= 2048)     /* we've reached the max rg size */
+		/* check to see if the rg length overflows max # bitblks */
+		rgblocksn = dev->length / nrgrp;
+		rgblocks2bitblocks(sdp->bsize, &rgblocksn, &bitblocksn);
+		/* calculate size of the first rgrp */
+		rgblocks1 = dev->length - (nrgrp - 1) * (dev->length / nrgrp);
+		rgblocks2bitblocks(sdp->bsize, &rgblocks1, &bitblocks1);
+		if (bitblocks1 > 2149 || bitblocksn > 2149) {
+			bitmap_overflow = 1;
+			if (sdp->rgsize <= GFS2_DEFAULT_RGSIZE) {
+				fprintf(stderr, "error: It is not possible "
+					"to use the entire device with "
+					"block size %u bytes.\n",
+					sdp->bsize);
+				exit(-1);
+			}
+			sdp->rgsize -= GFS2_DEFAULT_RGSIZE; /* smaller rgs */
+			continue;
+		}
+		if (bitmap_overflow ||
+		    rgsize_specified || /* If user specified an rg size or */
+		    nrgrp <= GFS2_EXCESSIVE_RGS || /* not an excessive # or  */
+		    sdp->rgsize >= 2048)   /* we reached the max rg size */
 			break;
 
-		sdp->rgsize += GFS2_DEFAULT_RGSIZE; /* Try again w/bigger rgs */
+		sdp->rgsize += GFS2_DEFAULT_RGSIZE; /* bigger rgs */
 	}
 
 	if (sdp->debug)
-		printf("  rg sz = %"PRIu32"\n  nrgrp = %"PRIu64"\n", sdp->rgsize,
-			   nrgrp);
+		printf("  rg sz = %"PRIu32"\n  nrgrp = %"PRIu64"\n",
+		       sdp->rgsize, nrgrp);
 
 	return nrgrp;
 }
@@ -210,7 +231,11 @@ void build_rgrps(struct gfs2_sbd *sdp, int do_write)
 		rl->rg.rg_header.mh_format = GFS2_FORMAT_RG;
 		rl->rg.rg_free = rgblocks;
 
-		gfs2_compute_bitstructs(sdp, rl);
+		if (gfs2_compute_bitstructs(sdp, rl)) {
+			fprintf(stderr, "%s: Unable to build resource groups "
+				"with these characteristics.\n", __FUNCTION__);
+			exit(-1);
+		}
 
 		if (do_write) {
 			for (x = 0; x < bitblocks; x++) {