[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