[Cluster-devel] cluster/gfs2 fsck/initialize.c libgfs2/bitmap. ...

rpeterso at sourceware.org rpeterso at sourceware.org
Wed Sep 20 15:23:35 UTC 2006


CVSROOT:	/cvs/cluster
Module name:	cluster
Changes by:	rpeterso at sourceware.org	2006-09-20 15:23:34

Modified files:
	gfs2/fsck      : initialize.c 
	gfs2/libgfs2   : bitmap.c block_list.c libgfs2.h 

Log message:
	This is a crosswrite from gfs1 for bugzilla bz 200883: gfs_fsck
	segfaults on very large file systems.  The same problem existed
	and is now fixed in gfs2_fsck and libgfs2.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/fsck/initialize.c.diff?cvsroot=cluster&r1=1.4&r2=1.5
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/libgfs2/bitmap.c.diff?cvsroot=cluster&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/libgfs2/block_list.c.diff?cvsroot=cluster&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/libgfs2/libgfs2.h.diff?cvsroot=cluster&r1=1.6&r2=1.7

--- cluster/gfs2/fsck/initialize.c	2006/06/15 18:48:45	1.4
+++ cluster/gfs2/fsck/initialize.c	2006/09/20 15:23:34	1.5
@@ -196,6 +196,7 @@
 	uint64_t inumbuf;
 	struct gfs2_statfs_change sc;
 	int rgcount;
+	uint64_t addl_mem_needed;
 
 	sync();
 
@@ -290,8 +291,13 @@
 		goto fail;
 	}
 
-	bl = gfs2_block_list_create(last_fs_block+1);
-
+	bl = gfs2_block_list_create(last_fs_block+1, &addl_mem_needed);
+	if (!bl) {
+		log_crit("This system doesn't have enough memory + swap space to fsck this file system.\n");
+		log_crit("Additional memory needed is approximately: %ldMB\n", addl_mem_needed / 1048576);
+		log_crit("Please increase your swap space by that amount and run gfs_fsck again.\n");
+		goto fail;
+	}
 	return 0;
 
  fail:
--- cluster/gfs2/libgfs2/bitmap.c	2006/06/08 20:50:24	1.1
+++ cluster/gfs2/libgfs2/bitmap.c	2006/09/20 15:23:34	1.2
@@ -48,11 +48,11 @@
 	bmap->mapsize = BITMAP_SIZE(size, bmap->chunks_per_byte)+1;
 
 	if(!(bmap->map = malloc(sizeof(char) * bmap->mapsize)))
-		return ENOMEM;
+		return -ENOMEM;
 	if(!memset(bmap->map, 0, sizeof(char) * bmap->mapsize)) {
 		free(bmap->map);
 		bmap->map = NULL;
-		return ENOMEM;
+		return -ENOMEM;
 	}
 	return 0;
 }
--- cluster/gfs2/libgfs2/block_list.c	2006/06/08 20:50:54	1.1
+++ cluster/gfs2/libgfs2/block_list.c	2006/09/20 15:23:34	1.2
@@ -46,27 +46,45 @@
 	INVALID_META, INVALID_META
 };
 
-struct gfs2_block_list *gfs2_block_list_create(uint64_t size)
+struct gfs2_block_list *gfs2_block_list_create(uint64_t size,
+											   uint64_t *addl_mem_needed)
 {
 	struct gfs2_block_list *il;
 
+	*addl_mem_needed = 0L;
 	if ((il = malloc(sizeof(*il)))) {
 		if(!memset(il, 0, sizeof(*il)))
 			return NULL;
 
 		if(gfs2_bitmap_create(&il->list.gbmap.group_map, size, 4)) {
+			/* Note on addl_mem_needed: We've tried to allocate ram   */
+			/* for our bitmaps, but we failed.  The fs is too big.    */
+			/* We should tell them how much to allocate.  This first  */
+			/* bitmap is the biggest, but we need three more smaller  */
+			/* for the code that immediately follows.  I'm rounding   */
+			/* up to twice the memory for this bitmap, even though    */
+			/* it's actually 1 + 3/4.  That will allow for future     */
+			/* mallocs that happen after this point in the code.      */
+			/* For the bad_map, we have two more to go (total of 3)   */
+			/* but again I'm rounding it up to 4 smaller ones.        */
+			/* For the dup_map, I'm rounding from 2 to 3, and for     */
+			/* eattr_map, I'm rounding up from 1 to 2.                */
+			*addl_mem_needed = il->list.gbmap.group_map.mapsize * 2;
 			free(il);
 			il = NULL;
 		}
-		if(gfs2_bitmap_create(&il->list.gbmap.bad_map, size, 1)) {
+		else if(gfs2_bitmap_create(&il->list.gbmap.bad_map, size, 1)) {
+			*addl_mem_needed = il->list.gbmap.group_map.mapsize * 4;
 			free(il);
 			il = NULL;
 		}
-		if(gfs2_bitmap_create(&il->list.gbmap.dup_map, size, 1)) {
+		else if(gfs2_bitmap_create(&il->list.gbmap.dup_map, size, 1)) {
+			*addl_mem_needed = il->list.gbmap.group_map.mapsize * 3;
 			free(il);
 			il = NULL;
 		}
-		if(gfs2_bitmap_create(&il->list.gbmap.eattr_map, size, 1)) {
+		else if(gfs2_bitmap_create(&il->list.gbmap.eattr_map, size, 1)) {
+			*addl_mem_needed = il->list.gbmap.group_map.mapsize * 2;
 			free(il);
 			il = NULL;
 		}
--- cluster/gfs2/libgfs2/libgfs2.h	2006/06/19 20:45:15	1.6
+++ cluster/gfs2/libgfs2/libgfs2.h	2006/09/20 15:23:34	1.7
@@ -318,7 +318,8 @@
         union gfs2_block_lists list;
 };
 
-struct gfs2_block_list *gfs2_block_list_create(uint64_t size);
+struct gfs2_block_list *gfs2_block_list_create(uint64_t size,
+											   uint64_t *addl_mem_needed);
 int gfs2_block_mark(struct gfs2_block_list *il, uint64_t block,
 					enum gfs2_mark_block mark);
 int gfs2_block_set(struct gfs2_block_list *il, uint64_t block,




More information about the Cluster-devel mailing list