[RFC][E2FSPROGS][PATCH 8/8]

Alexandre Ratchov <[email protected]>
Newsgroups gmane.comp.file-systems.ext2.devel
Message-ID <[email protected]>
Introduce management of larger block groups. The patch allows
bitmaps of each block group to be spread over several blocks and
also allows groups to be larger than (8 * blocksize) blocks.



Index: e2fsprogs/lib/e2p/feature.c
===================================================================
--- e2fsprogs.orig/lib/e2p/feature.c	2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/lib/e2p/feature.c	2006-05-24 15:26:05.000000000 +0200
@@ -41,6 +41,8 @@
 			"sparse_super" },
 	{	E2P_FEATURE_RO_INCOMPAT, EXT2_FEATURE_RO_COMPAT_LARGE_FILE,
 			"large_file" },
+	{	E2P_FEATURE_RO_INCOMPAT, EXT2_FEATURE_RO_COMPAT_BIG_BG,
+			"big_bg" },
 	{	E2P_FEATURE_RO_INCOMPAT, EXT2_FEATURE_RO_COMPAT_64BIT,
 			"64bit" },
 	{	E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_COMPRESSION,
Index: e2fsprogs/e2fsck/pass5.c
===================================================================
--- e2fsprogs.orig/e2fsck/pass5.c	2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/e2fsck/pass5.c	2006-05-24 15:26:05.000000000 +0200
@@ -278,15 +278,20 @@
 		ext2fs_unmark_valid(fs);
 
 	for (i = 0; i < fs->group_desc_count; i++) {
-		if (free_array[i] != fs->group_desc[i].bg_free_blocks_count) {
+		__u32 free_blocks;
+
+		free_blocks = fs->group_desc[i].bg_free_blocks_count;
+		free_blocks += (__u32)fs->group_desc[i].bg_free_blocks_count_hi << 16;
+
+		if (free_array[i] != free_blocks) {
 			pctx.group = i;
-			pctx.blk = fs->group_desc[i].bg_free_blocks_count;
+			pctx.blk = free_blocks;
 			pctx.blk2 = free_array[i];
 
 			if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP,
 					&pctx)) {
-				fs->group_desc[i].bg_free_blocks_count =
-					free_array[i];
+				fs->group_desc[i].bg_free_blocks_count = free_blocks;
+				fs->group_desc[i].bg_free_blocks_count_hi = free_blocks >> 16;
 				ext2fs_mark_super_dirty(fs);
 			} else
 				ext2fs_unmark_valid(fs);
@@ -468,27 +473,36 @@
 		ext2fs_unmark_valid(fs);
 	
 	for (i = 0; i < fs->group_desc_count; i++) {
-		if (free_array[i] != fs->group_desc[i].bg_free_inodes_count) {
+		__u32 free_inodes, used_dirs;
+		free_inodes = fs->group_desc[i].bg_free_inodes_count;
+		used_dirs = fs->group_desc[i].bg_used_dirs_count;
+		free_inodes += (__u32)fs->group_desc[i].bg_free_inodes_count_hi << 16;
+		used_dirs += (__u32)fs->group_desc[i].bg_used_dirs_count_hi << 16;
+		if (free_array[i] != free_inodes) {
 			pctx.group = i;
-			pctx.ino = fs->group_desc[i].bg_free_inodes_count;
+			pctx.ino = free_inodes;
 			pctx.ino2 = free_array[i];
 			if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP,
 					&pctx)) {
 				fs->group_desc[i].bg_free_inodes_count =
 					free_array[i];
+				fs->group_desc[i].bg_free_inodes_count_hi =
+					free_array[i] >> 16;
 				ext2fs_mark_super_dirty(fs);
 			} else
 				ext2fs_unmark_valid(fs);
 		}
-		if (dir_array[i] != fs->group_desc[i].bg_used_dirs_count) {
+		if (dir_array[i] != used_dirs) {
 			pctx.group = i;
-			pctx.ino = fs->group_desc[i].bg_used_dirs_count;
+			pctx.ino = used_dirs;
 			pctx.ino2 = dir_array[i];
 
 			if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP,
 					&pctx)) {
 				fs->group_desc[i].bg_used_dirs_count =
 					dir_array[i];
+				fs->group_desc[i].bg_used_dirs_count_hi =
+					dir_array[i] >> 16;
 				ext2fs_mark_super_dirty(fs);
 			} else
 				ext2fs_unmark_valid(fs);
Index: e2fsprogs/lib/ext2fs/alloc_stats.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/alloc_stats.c	2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/lib/ext2fs/alloc_stats.c	2006-05-24 15:26:05.000000000 +0200
@@ -19,14 +19,24 @@
 			       int inuse, int isdir)
 {
 	int	group = ext2fs_group_of_ino(fs, ino);
+	__u32	free_inodes, used_dirs;
 
 	if (inuse > 0)
 		ext2fs_mark_inode_bitmap(fs->inode_map, ino);
 	else
 		ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
-	fs->group_desc[group].bg_free_inodes_count -= inuse;
-	if (isdir)
-		fs->group_desc[group].bg_used_dirs_count += inuse;
+	free_inodes = fs->group_desc[group].bg_free_inodes_count;
+	free_inodes += (__u32)fs->group_desc[group].bg_free_inodes_count_hi << 16;
+	free_inodes -= inuse;
+	fs->group_desc[group].bg_free_inodes_count = free_inodes;
+	fs->group_desc[group].bg_free_inodes_count_hi = free_inodes >> 16;
+	if (isdir) {
+		used_dirs = fs->group_desc[group].bg_used_dirs_count;
+		used_dirs += (__u32)fs->group_desc[group].bg_used_dirs_count_hi << 16;
+		used_dirs += inuse;
+		fs->group_desc[group].bg_used_dirs_count = used_dirs;
+		fs->group_desc[group].bg_used_dirs_count_hi = used_dirs >> 16;
+	}
 	fs->super->s_free_inodes_count -= inuse;
 	ext2fs_mark_super_dirty(fs);
 	ext2fs_mark_ib_dirty(fs);
@@ -39,13 +49,21 @@
 
 void ext2fs_block_alloc_stats(ext2_filsys fs, blk_t blk, int inuse)
 {
+	__u32 free_blocks;
+
 	int	group = ext2fs_group_of_blk(fs, blk);
 
 	if (inuse > 0)
 		ext2fs_mark_block_bitmap(fs->block_map, blk);
 	else
 		ext2fs_unmark_block_bitmap(fs->block_map, blk);
-	fs->group_desc[group].bg_free_blocks_count -= inuse;
+	free_blocks = fs->group_desc[group].bg_free_blocks_count;
+	free_blocks += (__u32)fs->group_desc[group].bg_free_blocks_count_hi << 16;
+
+	free_blocks -= inuse;
+	fs->group_desc[group].bg_free_blocks_count = free_blocks;
+	fs->group_desc[group].bg_free_blocks_count_hi = free_blocks >> 16;
+
 	EXT2_FREE_BLOCKS_COUNT_SET(fs->super, EXT2_FREE_BLOCKS_COUNT(fs->super) - inuse);
 	ext2fs_mark_super_dirty(fs);
 	ext2fs_mark_bb_dirty(fs);
Index: e2fsprogs/lib/ext2fs/ext2fs.h
===================================================================
--- e2fsprogs.orig/lib/ext2fs/ext2fs.h	2006-05-24 15:25:39.000000000 +0200
+++ e2fsprogs/lib/ext2fs/ext2fs.h	2006-05-24 15:26:05.000000000 +0200
@@ -467,6 +467,7 @@
 #endif
 #define EXT2_LIB_FEATURE_RO_COMPAT_SUPP	(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
 					 EXT2_FEATURE_RO_COMPAT_LARGE_FILE|\
+					 EXT2_FEATURE_RO_COMPAT_BIG_BG|\
 					 EXT2_FEATURE_RO_COMPAT_64BIT)
 /*
  * function prototypes
Index: e2fsprogs/lib/ext2fs/swapfs.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/swapfs.c	2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/lib/ext2fs/swapfs.c	2006-05-24 15:26:05.000000000 +0200
@@ -79,7 +79,9 @@
 	gdp->bg_inode_bitmap = ext2fs_swab32(gdp->bg_inode_bitmap);
 	gdp->bg_inode_table = ext2fs_swab32(gdp->bg_inode_table);
 	gdp->bg_free_blocks_count = ext2fs_swab16(gdp->bg_free_blocks_count);
+	gdp->bg_free_blocks_count_hi = ext2fs_swab16(gdp->bg_free_blocks_count_hi);
 	gdp->bg_free_inodes_count = ext2fs_swab16(gdp->bg_free_inodes_count);
+	gdp->bg_free_inodes_count_hi = ext2fs_swab16(gdp->bg_free_inodes_count_hi);
 	gdp->bg_used_dirs_count = ext2fs_swab16(gdp->bg_used_dirs_count);
 	gdp->bg_flags = ext2fs_swab16(gdp->bg_flags);
 }
Index: e2fsprogs/debugfs/debugfs.c
===================================================================
--- e2fsprogs.orig/debugfs/debugfs.c	2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/debugfs/debugfs.c	2006-05-24 15:26:05.000000000 +0200
@@ -286,6 +286,7 @@
 	struct ext2_group_desc *gdp;
 	int	c, header_only = 0;
 	int	numdirs = 0, first;
+	__u32 free_blocks, free_inodes, used_dirs;
 
 	reset_getopt();
 	while ((c = getopt (argc, argv, "h")) != EOF) {
@@ -305,8 +306,12 @@
 	out = open_pager();
 
 	list_super2(current_fs->super, out);
-	for (i=0; i < current_fs->group_desc_count; i++)
-		numdirs += current_fs->group_desc[i].bg_used_dirs_count;
+	for (i=0; i < current_fs->group_desc_count; i++) {
+		used_dirs = current_fs->group_desc[i].bg_used_dirs_count;
+		if (current_fs->super->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_BIG_BG)
+			used_dirs += (__u32)current_fs->group_desc[i].bg_used_dirs_count_hi << 16;
+		numdirs += used_dirs;
+	}
 	fprintf(out, "Directories:              %d\n", numdirs);
 	
 	if (header_only) {
@@ -317,6 +322,17 @@
 	gdp = &current_fs->group_desc[0];
 	for (i = 0; i < current_fs->group_desc_count; i++, gdp++) {
 		blk_t group_base = EXT2_GROUP_BASE(current_fs->super, i);
+		free_blocks = gdp->bg_free_blocks_count;
+		free_inodes = gdp->bg_free_inodes_count;
+		used_dirs = gdp->bg_used_dirs_count;
+
+		if (current_fs->super->s_feature_ro_compat &
+				EXT2_FEATURE_RO_COMPAT_BIG_BG) {
+			free_blocks += (__u32)gdp->bg_free_blocks_count_hi << 16;
+			free_inodes += (__u32)gdp->bg_free_inodes_count_hi << 16;
+			used_dirs += (__u32)gdp->bg_used_dirs_count_hi << 16;
+		}
+
 		fprintf(out, " Group %2d: block bitmap at %llu, "
 		        "inode bitmap at %llu, "
 		        "inode table at %llu\n"
@@ -326,13 +342,9 @@
 		        i, EXT2_BLOCK_BITMAP(gdp, group_base),
 			EXT2_INODE_BITMAP(gdp, group_base),
 			EXT2_INODE_TABLE(gdp, group_base),
-		        gdp->bg_free_blocks_count,
-		        gdp->bg_free_blocks_count != 1 ? "blocks" : "block",
-		        gdp->bg_free_inodes_count,
-		        gdp->bg_free_inodes_count != 1 ? "inodes" : "inode",
-		        gdp->bg_used_dirs_count,
-		        gdp->bg_used_dirs_count != 1 ? "directories"
-				: "directory");
+		        free_blocks, free_blocks != 1 ?  "blocks" : "block",
+		        free_inodes, free_inodes != 1 ? "inodes" : "inode",
+		        used_dirs, used_dirs != 1 ? "directories" : "directory");
 		first = 1;
 		print_bg_opts(gdp, EXT2_BG_INODE_UNINIT, "Inode not init",
 			      &first, out);
Index: e2fsprogs/misc/dumpe2fs.c
===================================================================
--- e2fsprogs.orig/misc/dumpe2fs.c	2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/misc/dumpe2fs.c	2006-05-24 15:26:05.000000000 +0200
@@ -135,6 +135,7 @@
 	char *block_bitmap=NULL, *inode_bitmap=NULL;
 	int inode_blocks_per_group, old_desc_blocks, reserved_gdt;
 	int has_super;
+	int free_blocks, free_inodes, used_dirs;
 
 	if (fs->block_map)
 		block_bitmap = fs->block_map->bitmap;
@@ -203,11 +204,15 @@
 		diff = EXT2_INODE_TABLE(&fs->group_desc[i], group_blk) - group_blk;
 		if (diff > 0)
 			printf(" (+%ld)", diff);
+		free_blocks = fs->group_desc[i].bg_free_blocks_count;
+		free_blocks += (__u32)fs->group_desc[i].bg_free_blocks_count_hi << 16;
+		free_inodes = fs->group_desc[i].bg_free_inodes_count;
+		free_inodes += (__u32)fs->group_desc[i].bg_free_inodes_count_hi << 16;
+		used_dirs = fs->group_desc[i].bg_used_dirs_count;
+		used_dirs += (__u32)fs->group_desc[i].bg_used_dirs_count_hi << 16;
 		printf (_("\n  %d free blocks, %d free inodes, "
 			  "%d directories\n"),
-			fs->group_desc[i].bg_free_blocks_count,
-			fs->group_desc[i].bg_free_inodes_count,
-			fs->group_desc[i].bg_used_dirs_count);
+			free_blocks, free_inodes, used_dirs);
 		if (block_bitmap) {
 			fputs(_("  Free blocks: "), stdout);
 			print_free (i, block_bitmap,
Index: e2fsprogs/resize/resize2fs.c
===================================================================
--- e2fsprogs.orig/resize/resize2fs.c	2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/resize/resize2fs.c	2006-05-24 15:26:05.000000000 +0200
@@ -187,6 +187,7 @@
 	unsigned long	i, j, old_desc_blocks, max_group;
 	unsigned int	meta_bg, meta_bg_size;
 	int		has_super;
+	int		free_blocks;
 
 	EXT2_BLOCKS_COUNT_SET(fs->super, new_size);
 
@@ -333,8 +334,12 @@
 	} else
 		numblocks = fs->super->s_blocks_per_group;
 	i = old_fs->group_desc_count - 1;
-	fs->group_desc[i].bg_free_blocks_count += (numblocks-old_numblocks);
-		
+	free_blocks = fs->group_desc[i].bg_free_blocks_count;
+	free_blocks += (__u32)fs->group_desc[i].bg_free_blocks_count_hi << 16;
+	free_blocks += (numblocks-old_numblocks);
+	fs->group_desc[i].bg_free_blocks_count = free_blocks;
+	fs->group_desc[i].bg_free_blocks_count_hi = free_blocks >> 16;
+
 	/*
 	 * If the number of block groups is staying the same, we're
 	 * done and can exit now.  (If the number block groups is
@@ -407,9 +412,13 @@
 		fs->super->s_free_inodes_count +=
 			fs->super->s_inodes_per_group;
 		fs->group_desc[i].bg_free_blocks_count = numblocks;
+		fs->group_desc[i].bg_free_blocks_count_hi = numblocks >> 16;
 		fs->group_desc[i].bg_free_inodes_count =
 			fs->super->s_inodes_per_group;
+		fs->group_desc[i].bg_free_inodes_count_hi =
+			fs->super->s_inodes_per_group >> 16;
 		fs->group_desc[i].bg_used_dirs_count = 0;
+		fs->group_desc[i].bg_used_dirs_count_hi = 0;
 
 		retval = ext2fs_allocate_group_table(fs, i, 0);
 		if (retval) goto errout;
@@ -434,6 +443,7 @@
 	blk_t		group_block;
 	unsigned long	i;
 	unsigned long	max_group;
+	int		free_blocks;
 	
 	fs = rfs->new_fs;
 	ext2fs_mark_super_dirty(fs);
@@ -566,14 +576,18 @@
 		/*
 		 * Mark block used for the block bitmap 
 		 */
-		ext2fs_mark_block_bitmap(bmap,
-					 EXT2_BLOCK_BITMAP(&fs->group_desc[i], block));
+		for (j = 0, b = EXT2_BLOCK_BITMAP(&fs->group_desc[i], block);
+		     j <  EXT2_BLOCK_BITMAP_PER_GROUP(fs->super);
+		     j++, b++)
+			ext2fs_mark_block_bitmap(bmap, b);
 
 		/*
 		 * Mark block used for the inode bitmap 
 		 */
-		ext2fs_mark_block_bitmap(bmap,
-					 EXT2_INODE_BITMAP(&fs->group_desc[i], block));
+		for (j = 0, b = EXT2_INODE_BITMAP(&fs->group_desc[i], block);
+		     j <  EXT2_INODE_BITMAP_PER_GROUP(fs->super);
+		     j++, b++)
+			ext2fs_mark_block_bitmap(bmap, b);
 		block += fs->super->s_blocks_per_group;
 	}
 	return 0;
@@ -1221,8 +1235,14 @@
 		if (retval) goto errout;
 
 		group = (new_inode-1) / EXT2_INODES_PER_GROUP(rfs->new_fs->super);
-		if (LINUX_S_ISDIR(inode.i_mode))
-			rfs->new_fs->group_desc[group].bg_used_dirs_count++;
+		if (LINUX_S_ISDIR(inode.i_mode)) {
+			__u32 used_dirs;
+			used_dirs = rfs->new_fs->group_desc[group].bg_used_dirs_count;
+			used_dirs += (__u32)rfs->new_fs->group_desc[group].bg_used_dirs_count_hi << 16;
+			used_dirs++;
+			rfs->new_fs->group_desc[group].bg_used_dirs_count = used_dirs;
+			rfs->new_fs->group_desc[group].bg_used_dirs_count_hi = used_dirs >> 16;
+		}
 		
 #ifdef RESIZE2FS_DEBUG
 		if (rfs->flags & RESIZE_DEBUG_INODEMAP)
@@ -1580,6 +1600,8 @@
 		    (blk == EXT2_BLOCKS_COUNT(fs->super)-1)) {
 			fs->group_desc[group++].bg_free_blocks_count =
 				group_free;
+			fs->group_desc[group++].bg_free_blocks_count_hi =
+				group_free >> 16;
 			count = 0;
 			group_free = 0;
 		}
@@ -1603,6 +1625,8 @@
 		    (ino == fs->super->s_inodes_count)) {
 			fs->group_desc[group++].bg_free_inodes_count =
 				group_free;
+			fs->group_desc[group++].bg_free_inodes_count_hi =
+				group_free >> 16;
 			count = 0;
 			group_free = 0;
 		}
Index: e2fsprogs/misc/mke2fs.c
===================================================================
--- e2fsprogs.orig/misc/mke2fs.c	2006-05-24 15:25:39.000000000 +0200
+++ e2fsprogs/misc/mke2fs.c	2006-05-24 15:26:05.000000000 +0200
@@ -219,6 +219,7 @@
 	blk_t			group_block;
 	int			group;
 	int			group_bad;
+	int			free_blocks;
 
 	if (!bb_list)
 		return;
@@ -260,7 +261,11 @@
 						group_block);
 				group_bad++;
 				group = ext2fs_group_of_blk(fs, group_block+j);
-				fs->group_desc[group].bg_free_blocks_count++;
+				free_blocks = fs->group_desc[group].bg_free_blocks_count;
+				free_blocks += (__u32)fs->group_desc[group].bg_free_blocks_count_hi << 16; 
+				free_blocks++;
+				fs->group_desc[group].bg_free_blocks_count = free_blocks;
+				fs->group_desc[group].bg_free_blocks_count_hi = free_blocks >> 16;
 				EXT2_FREE_BLOCKS_COUNT_SET(fs->super, EXT2_FREE_BLOCKS_COUNT(fs->super) + 1);
 			}
 		}
@@ -455,15 +460,17 @@
 			if ((i == 0) ||
 			    (i == fs->group_desc_count-1))
 				continue;
-			if (bg->bg_free_inodes_count ==
+			if ((bg->bg_free_inodes_count + (bg->bg_free_inodes_count_hi<<16)) ==
 			    sb->s_inodes_per_group) {
 				bg->bg_free_inodes_count = 0;
+				bg->bg_free_inodes_count_hi = 0;
 				bg->bg_flags |= EXT2_BG_INODE_UNINIT;
 				sb->s_free_inodes_count -= 
 					sb->s_inodes_per_group;
 			}
 			blks = ext2fs_super_and_bgd_loc(fs, i, 0, 0, 0, 0);
-			if (bg->bg_free_blocks_count == blks) {
+			if ((bg->bg_free_blocks_count + (bg->bg_free_blocks_count<< 16)) == 
+				blks) {
 				bg->bg_free_blocks_count = 0;
 				bg->bg_flags |= EXT2_BG_BLOCK_UNINIT;
 				EXT2_FREE_BLOCKS_COUNT_SET(sb, 
@@ -543,9 +550,14 @@
 static void create_bad_block_inode(ext2_filsys fs, badblocks_list bb_list)
 {
 	errcode_t	retval;
+	__u32		free_inodes;
 	
 	ext2fs_mark_inode_bitmap(fs->inode_map, EXT2_BAD_INO);
-	fs->group_desc[0].bg_free_inodes_count--;
+	free_inodes = fs->group_desc[0].bg_free_inodes_count;
+	free_inodes += (__u32)fs->group_desc[0].bg_free_inodes_count_hi << 16;
+	free_inodes--;
+	fs->group_desc[0].bg_free_inodes_count = free_inodes;
+	fs->group_desc[0].bg_free_inodes_count_hi = free_inodes >> 16;
 	fs->super->s_free_inodes_count--;
 	retval = ext2fs_update_bb_inode(fs, bb_list);
 	if (retval) {
@@ -560,11 +572,16 @@
 {
 	ext2_ino_t	i;
 	int		group;
+	__u32		free_inodes;
 
 	for (i = EXT2_ROOT_INO + 1; i < EXT2_FIRST_INODE(fs->super); i++) {
 		ext2fs_mark_inode_bitmap(fs->inode_map, i);
 		group = ext2fs_group_of_ino(fs, i);
-		fs->group_desc[group].bg_free_inodes_count--;
+		free_inodes = fs->group_desc[group].bg_free_inodes_count;
+		free_inodes += (__u32)fs->group_desc[group].bg_free_inodes_count_hi << 16;
+		free_inodes--;
+		fs->group_desc[group].bg_free_inodes_count = free_inodes;
+		fs->group_desc[group].bg_free_inodes_count_hi = free_inodes >> 16;
 		fs->super->s_free_inodes_count--;
 	}
 	ext2fs_mark_ib_dirty(fs);
@@ -1401,12 +1418,14 @@
 	}
 
 	if (fs_param.s_blocks_per_group) {
-		if (fs_param.s_blocks_per_group < 256 ||
-		    fs_param.s_blocks_per_group > 8 * (unsigned) blocksize) {
+		if (fs_param.s_blocks_per_group < 256) {
 			com_err(program_name, 0,
 				_("blocks per group count out of range"));
 			exit(1);
 		}
+		if (fs_param.s_blocks_per_group > 8 * (unsigned) blocksize) {
+			fs_param.s_feature_ro_compat |= EXT2_FEATURE_RO_COMPAT_BIG_BG;
+		}
 	}
 
 	if ((blocksize > 4096) &&
Index: e2fsprogs/lib/ext2fs/openfs.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/openfs.c	2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/lib/ext2fs/openfs.c	2006-05-24 15:26:05.000000000 +0200
@@ -252,7 +252,8 @@
 	 */
 	blocks_per_group = EXT2_BLOCKS_PER_GROUP(fs->super);
 	if (blocks_per_group == 0 ||
-	    blocks_per_group > EXT2_MAX_BLOCKS_PER_GROUP(fs->super) ||
+	    (!(fs->super->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_BIG_BG)) &&
+	      (blocks_per_group > EXT2_MAX_BLOCKS_PER_GROUP(fs->super)) ||
 	    fs->inode_blocks_per_group > EXT2_MAX_INODES_PER_GROUP(fs->super)) {
 		retval = EXT2_ET_CORRUPT_SUPERBLOCK;
 		goto cleanup;
Index: e2fsprogs/lib/ext2fs/closefs.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/closefs.c	2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/lib/ext2fs/closefs.c	2006-05-24 15:26:05.000000000 +0200
@@ -100,7 +100,9 @@
 		}
 	}
 		
-	numblocks -= 2 + fs->inode_blocks_per_group;
+	numblocks -= EXT2_BLOCK_BITMAP_PER_GROUP(fs->super) +
+		     EXT2_INODE_BITMAP_PER_GROUP(fs->super) +
+		     fs->inode_blocks_per_group;
 
 	if (ret_super_blk)
 		*ret_super_blk = super_blk;
Index: e2fsprogs/e2fsck/journal.c
===================================================================
--- e2fsprogs.orig/e2fsck/journal.c	2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/e2fsck/journal.c	2006-05-24 15:26:05.000000000 +0200
@@ -851,6 +851,7 @@
 	errcode_t		retval;
 	const char * const *	cpp;
 	int			group, mount_flags;
+	__u32			free_inodes;
 	
 	clear_problem_context(&pctx);
 
@@ -947,7 +948,11 @@
 	group = ext2fs_group_of_ino(fs, ino);
 	ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
 	ext2fs_mark_ib_dirty(fs);
-	fs->group_desc[group].bg_free_inodes_count++;
+	free_inodes = fs->group_desc[group].bg_free_inodes_count;
+	free_inodes += (__u32)fs->group_desc[group].bg_free_inodes_count_hi << 16;
+	free_inodes++;
+	fs->group_desc[group].bg_free_inodes_count = free_inodes;
+	fs->group_desc[group].bg_free_inodes_count_hi = free_inodes >> 16;
 	fs->super->s_free_inodes_count++;
 	return;
 
Index: e2fsprogs/lib/ext2fs/ext2_fs.h
===================================================================
--- e2fsprogs.orig/lib/ext2fs/ext2_fs.h	2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/lib/ext2fs/ext2_fs.h	2006-05-24 15:29:43.000000000 +0200
@@ -143,8 +143,10 @@
 	__u16	bg_free_blocks_count;	/* Free blocks count */
 	__u16	bg_free_inodes_count;	/* Free inodes count */
 	__u16	bg_used_dirs_count;	/* Directories count */
-	__u16	bg_pad;
-	__u32	bg_reserved1;
+	__u8	bg_used_dirs_count_hi;	/* Directories count */
+	__u8	bg_pad;
+	__u16	bg_free_blocks_count_hi;	/* Free blocks count */
+	__u16	bg_free_inodes_count_hi;	/* Free inodes count */
 	__u16	bg_flags;
 	__u16	bg_reserved2[3];
 };
@@ -235,6 +237,14 @@
 #define EXT2_DESC_PER_BLOCK_BITS(s)	(EXT2_SB(s)->s_desc_per_block_bits)
 #else
 #define EXT2_DESC_PER_BLOCK(s)		(EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc))
+/* several block bitmaps per group */
+#define EXT2_BLOCK_BITMAP_NBYTES(s)	((EXT2_BLOCKS_PER_GROUP(s) + 7) / 8)
+#define EXT2_BLOCK_BITMAP_PER_GROUP(s)	((EXT2_BLOCK_BITMAP_NBYTES(s) + (EXT2_BLOCK_SIZE(s) - 1)) / EXT2_BLOCK_SIZE(s))
+#define EXT2_BLOCK_BITMAP_SIZE(s)	(EXT2_BLOCK_BITMAP_PER_GROUP(s) *  EXT2_BLOCK_SIZE(s))
+/* several inode bitmaps per group */
+#define EXT2_INODE_BITMAP_NBYTES(s)	((EXT2_INODES_PER_GROUP(s) + 7) / 8)
+#define EXT2_INODE_BITMAP_PER_GROUP(s)	((EXT2_INODE_BITMAP_NBYTES(s) + (EXT2_BLOCK_SIZE(s) - 1)) / EXT2_BLOCK_SIZE(s))
+#define EXT2_INODE_BITMAP_SIZE(s)	(EXT2_INODE_BITMAP_PER_GROUP(s) *  EXT2_BLOCK_SIZE(s))
 #endif
 
 /*
@@ -635,6 +645,7 @@
 #define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER	0x0001
 #define EXT2_FEATURE_RO_COMPAT_LARGE_FILE	0x0002
 /* #define EXT2_FEATURE_RO_COMPAT_BTREE_DIR	0x0004 not used */
+#define EXT2_FEATURE_RO_COMPAT_BIG_BG		0x0008
 #define EXT2_FEATURE_RO_COMPAT_64BIT		0x0010
 
 #define EXT2_FEATURE_INCOMPAT_COMPRESSION	0x0001
@@ -650,6 +661,7 @@
 #define EXT2_FEATURE_RO_COMPAT_SUPP	(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
 					 EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
 					 EXT2_FEATURE_RO_COMPAT_BTREE_DIR| \
+					 EXT2_FEATURE_RO_COMPAT_BIG_BG| \
 					 EXT2_FEATURE_RO_COMPAT_64BIT)
 
 /*
Index: e2fsprogs/e2fsck/pass1.c
===================================================================
--- e2fsprogs.orig/e2fsck/pass1.c	2006-05-24 15:25:39.000000000 +0200
+++ e2fsprogs/e2fsck/pass1.c	2006-05-24 15:26:05.000000000 +0200
@@ -2035,33 +2035,40 @@
 		 * Mark block used for the block bitmap 
 		 */
 		if (EXT2_IS_USED_BLOCK_BITMAP(&fs->group_desc[i])) {
-			if (ext2fs_test_block_bitmap(ctx->block_found_map,
-				     EXT2_BLOCK_BITMAP(&fs->group_desc[i], block))) {
-				pctx.blk = EXT2_BLOCK_BITMAP(&fs->group_desc[i], block);
-				if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
-					ctx->invalid_block_bitmap_flag[i]++;
-					ctx->invalid_bitmaps++;
+			for (j = 0, b = EXT2_BLOCK_BITMAP(&fs->group_desc[i], block);
+			     j <  EXT2_BLOCK_BITMAP_PER_GROUP(fs->super);
+			     j++, b++) {
+				if (ext2fs_test_block_bitmap(ctx->block_found_map,
+							     b)) {
+					pctx.blk = b;
+					if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
+						ctx->invalid_block_bitmap_flag[i]++;
+						ctx->invalid_bitmaps++;
+					}
+				} else {
+				    ext2fs_mark_block_bitmap(ctx->block_found_map,
+							     b);
 				}
-			} else {
-			    ext2fs_mark_block_bitmap(ctx->block_found_map,
-				      EXT2_BLOCK_BITMAP(&fs->group_desc[i], block));
-		    }
-			
+			}
 		}
 		/*
 		 * Mark block used for the inode bitmap 
 		 */
 		if (EXT2_IS_USED_INODE_BITMAP(&fs->group_desc[i])) {
-			if (ext2fs_test_block_bitmap(ctx->block_found_map,
-				     EXT2_INODE_BITMAP(&fs->group_desc[i], block))) {
-				pctx.blk = EXT2_INODE_BITMAP(&fs->group_desc[i], block);
-				if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
-					ctx->invalid_inode_bitmap_flag[i]++;
-					ctx->invalid_bitmaps++;
-				} 
-			} else {
-			    ext2fs_mark_block_bitmap(ctx->block_found_map,
-				     EXT2_INODE_BITMAP(&fs->group_desc[i], block));
+			for (j = 0, b = EXT2_INODE_BITMAP(&fs->group_desc[i], block);
+			     j <  EXT2_INODE_BITMAP_PER_GROUP(fs->super);
+			     j++, b++) {
+				if (ext2fs_test_block_bitmap(ctx->block_found_map,
+							     b)) {
+					pctx.blk = b;
+					if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
+						ctx->invalid_inode_bitmap_flag[i]++;
+						ctx->invalid_bitmaps++;
+					}
+				} else {
+				    ext2fs_mark_block_bitmap(ctx->block_found_map,
+							     b);
+				}
 			}
 		}
 		block += fs->super->s_blocks_per_group;
Index: e2fsprogs/e2fsck/super.c
===================================================================
--- e2fsprogs.orig/e2fsck/super.c	2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/e2fsck/super.c	2006-05-24 15:26:05.000000000 +0200
@@ -451,6 +451,8 @@
 	blk_t	should_be;
 	struct problem_context	pctx;
 	__u32	free_blocks = 0, free_inodes = 0;
+	__u32	group_free_blocks, group_free_inodes, used_dirs;
+	int big_bg;
 
 	inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super);
 	ipg_max = inodes_per_block * (blocks_per_group - 4);
@@ -472,6 +474,9 @@
 	/*
 	 * Verify the super block constants...
 	 */
+
+	big_bg = (fs->super->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_BIG_BG) ? 0 : MAX_CHECK;
+
 	check_super_value(ctx, "inodes_count", sb->s_inodes_count,
 			  MIN_CHECK, 1, 0);
 	check_super_value(ctx, "blocks_count", EXT2_BLOCKS_COUNT(sb),
@@ -484,12 +489,12 @@
 	check_super_value(ctx, "log_frag_size", sb->s_log_frag_size,
 			  MIN_CHECK | MAX_CHECK, 0, sb->s_log_block_size);
 	check_super_value(ctx, "frags_per_group", sb->s_frags_per_group,
-			  MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group,
+			  MIN_CHECK | big_bg, sb->s_blocks_per_group,
 			  bpg_max);
 	check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group,
-			  MIN_CHECK | MAX_CHECK, 8, bpg_max);
+			  MIN_CHECK | big_bg, 8, bpg_max);
 	check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group,
-			  MIN_CHECK | MAX_CHECK, inodes_per_block, ipg_max);
+			  MIN_CHECK | big_bg, inodes_per_block, ipg_max);
 	check_super_value(ctx, "r_blocks_count", EXT2_R_BLOCKS_COUNT(sb),
 			  MAX_CHECK, 0, EXT2_BLOCKS_COUNT(sb) / 2);
 	check_super_value(ctx, "reserved_gdt_blocks", 
@@ -604,14 +609,22 @@
 			ctx->invalid_inode_table_flag[i]++;
 			ctx->invalid_bitmaps++;
 		}
-		free_blocks += gd->bg_free_blocks_count;
-		free_inodes += gd->bg_free_inodes_count;
+		group_free_blocks = gd->bg_free_blocks_count;
+		group_free_blocks += (__u32)gd->bg_free_blocks_count_hi << 16;
+		group_free_inodes = gd->bg_free_inodes_count;
+		group_free_inodes += (__u32)gd->bg_free_inodes_count_hi << 16;
+		used_dirs = gd->bg_used_dirs_count;
+		used_dirs += (__u32)gd->bg_used_dirs_count_hi << 16;
+
+
+		free_blocks += group_free_blocks;
+		free_inodes += group_free_inodes;
 		first_block += sb->s_blocks_per_group;
 		last_block += sb->s_blocks_per_group;
 
-		if ((gd->bg_free_blocks_count > sb->s_blocks_per_group) ||
-		    (gd->bg_free_inodes_count > sb->s_inodes_per_group) ||
-		    (gd->bg_used_dirs_count > sb->s_inodes_per_group))
+		if ((group_free_blocks > sb->s_blocks_per_group) ||
+		    (group_free_inodes > sb->s_inodes_per_group) ||
+		    (used_dirs > sb->s_inodes_per_group))
 			ext2fs_unmark_valid(fs);
 
 	}
Index: e2fsprogs/lib/ext2fs/alloc_tables.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/alloc_tables.c	2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/lib/ext2fs/alloc_tables.c	2006-05-24 15:26:05.000000000 +0200
@@ -61,25 +61,35 @@
 
 	if (!EXT2_IS_USED_BLOCK_BITMAP(&fs->group_desc[group])) {
 		retval = ext2fs_get_free_blocks(fs, start_blk, last_blk,
-						1, bmap, &new_blk);
+						EXT2_BLOCK_BITMAP_PER_GROUP(fs->super),
+						bmap, &new_blk);
 		if (retval == EXT2_ET_BLOCK_ALLOC_FAIL) 
 			retval = ext2fs_get_free_blocks(fs, group_blk,
-					last_blk, 1, bmap, &new_blk);
+					last_blk, EXT2_BLOCK_BITMAP_PER_GROUP(fs->super),
+					bmap, &new_blk);
 		if (retval)
 			return retval;
-		ext2fs_mark_block_bitmap(bmap, new_blk);
+		for (j=0, blk = new_blk;
+		     j < EXT2_BLOCK_BITMAP_PER_GROUP(fs->super);
+		     j++, blk++)
+			ext2fs_mark_block_bitmap(bmap, blk);
 		EXT2_BLOCK_BITMAP_SET(&fs->group_desc[group], group_blk, new_blk);
 	}
 
 	if (!EXT2_IS_USED_INODE_BITMAP(&fs->group_desc[group])) {
 		retval = ext2fs_get_free_blocks(fs, start_blk, last_blk,
-						1, bmap, &new_blk);
+						EXT2_INODE_BITMAP_PER_GROUP(fs->super),
+						bmap, &new_blk);
 		if (retval == EXT2_ET_BLOCK_ALLOC_FAIL) 
 			retval = ext2fs_get_free_blocks(fs, group_blk,
-					last_blk, 1, bmap, &new_blk);
+					last_blk, EXT2_INODE_BITMAP_PER_GROUP(fs->super),
+					bmap, &new_blk);
 		if (retval)
 			return retval;
-		ext2fs_mark_block_bitmap(bmap, new_blk);
+		for (j=0, blk = new_blk;
+		     j < EXT2_INODE_BITMAP_PER_GROUP(fs->super);
+		     j++, blk++)
+			ext2fs_mark_block_bitmap(bmap, blk);
 		EXT2_INODE_BITMAP_SET(&fs->group_desc[group], group_blk, new_blk);
 	}
 
Index: e2fsprogs/lib/ext2fs/dblist.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/dblist.c	2006-05-24 15:22:49.000000000 +0200
+++ e2fsprogs/lib/ext2fs/dblist.c	2006-05-24 15:26:05.000000000 +0200
@@ -31,16 +31,19 @@
 {
 	dgrp_t	i;
 	ext2_ino_t	num_dirs, max_dirs;
+	__u32		used_dirs;
 
 	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
 	
 	num_dirs = 0;
 	max_dirs = fs->super->s_inodes_per_group;
 	for (i = 0; i < fs->group_desc_count; i++) {
-		if (fs->group_desc[i].bg_used_dirs_count > max_dirs)
+		used_dirs = fs->group_desc[i].bg_used_dirs_count;
+		used_dirs += (__u32)fs->group_desc[i].bg_used_dirs_count_hi << 16;
+		if (used_dirs > max_dirs)
 			num_dirs += max_dirs / 8;
 		else
-			num_dirs += fs->group_desc[i].bg_used_dirs_count;
+			num_dirs += used_dirs;
 	}
 	if (num_dirs > fs->super->s_inodes_count)
 		num_dirs = fs->super->s_inodes_count;
Index: e2fsprogs/misc/e2image.c
===================================================================
--- e2fsprogs.orig/misc/e2image.c	2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/misc/e2image.c	2006-05-24 15:26:05.000000000 +0200
@@ -277,16 +277,20 @@
 		 * Mark block used for the block bitmap 
 		 */
 		if (EXT2_IS_USED_BLOCK_BITMAP(&fs->group_desc[i])) {
-			ext2fs_mark_block_bitmap(meta_block_map,
-				     EXT2_BLOCK_BITMAP(&fs->group_desc[i], block));
+			for (j = 0, b = EXT2_BLOCK_BITMAP(&fs->group_desc[i], block);
+			     j <  EXT2_BLOCK_BITMAP_PER_GROUP(fs->super);
+			     j++, b++)
+				ext2fs_mark_block_bitmap(meta_block_map, b);
 		}
 		
 		/*
 		 * Mark block used for the inode bitmap 
 		 */
 		if (EXT2_IS_USED_INODE_BITMAP(&fs->group_desc[i])) {
-			ext2fs_mark_block_bitmap(meta_block_map,
-				 EXT2_INODE_BITMAP(&fs->group_desc[i], block));
+			for (j = 0, b = EXT2_INODE_BITMAP(&fs->group_desc[i], block);
+			     j <  EXT2_INODE_BITMAP_PER_GROUP(fs->super);
+			     j++, b++)
+				ext2fs_mark_block_bitmap(meta_block_map, b);
 		}
 		block += fs->super->s_blocks_per_group;
 	}
Index: e2fsprogs/lib/ext2fs/initialize.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/initialize.c	2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/lib/ext2fs/initialize.c	2006-05-24 15:26:05.000000000 +0200
@@ -240,20 +240,22 @@
 	 */
 	ipg = ((blk_t)super->s_inodes_count + (blk_t)fs->group_desc_count - 1) /
 		fs->group_desc_count;
-	if (ipg > fs->blocksize * 8) {
-		if (super->s_blocks_per_group >= 256) {
-			/* Try again with slightly different parameters */
-			super->s_blocks_per_group -= 8;
-			EXT2_BLOCKS_COUNT_SET(super, EXT2_BLOCKS_COUNT(param));
-			super->s_frags_per_group = super->s_blocks_per_group *
-				frags_per_block;
-			goto retry;
-		} else
-			return EXT2_ET_TOO_MANY_INODES;
-	}
+	if ( !(super->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_BIG_BG) ) {
+		if (ipg > fs->blocksize * 8) {
+			if (super->s_blocks_per_group >= 256) {
+				/* Try again with slightly different parameters */
+				super->s_blocks_per_group -= 8;
+				EXT2_BLOCKS_COUNT_SET(super, EXT2_BLOCKS_COUNT(param));
+				super->s_frags_per_group = super->s_blocks_per_group *
+					frags_per_block;
+				goto retry;
+			} else
+				return EXT2_ET_TOO_MANY_INODES;
+		}
 
-	if (ipg > (unsigned) EXT2_MAX_INODES_PER_GROUP(super))
-		ipg = EXT2_MAX_INODES_PER_GROUP(super);
+		if (ipg > (unsigned) EXT2_MAX_INODES_PER_GROUP(super))
+			ipg = EXT2_MAX_INODES_PER_GROUP(super);
+	}
 
 	super->s_inodes_per_group = ipg;
 	if (super->s_inodes_count > ipg * fs->group_desc_count)
@@ -375,9 +377,13 @@
 
 		EXT2_FREE_BLOCKS_COUNT_SET(super, EXT2_FREE_BLOCKS_COUNT(super) + numblocks);
 		fs->group_desc[i].bg_free_blocks_count = numblocks;
+		fs->group_desc[i].bg_free_blocks_count_hi = numblocks >> 16;
 		fs->group_desc[i].bg_free_inodes_count =
 			fs->super->s_inodes_per_group;
+		fs->group_desc[i].bg_free_inodes_count_hi =
+			fs->super->s_inodes_per_group >> 16;
 		fs->group_desc[i].bg_used_dirs_count = 0;
+		fs->group_desc[i].bg_used_dirs_count_hi = 0;
 		
 		group_block += super->s_blocks_per_group;
 	}
Index: e2fsprogs/misc/tune2fs.c
===================================================================
--- e2fsprogs.orig/misc/tune2fs.c	2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/misc/tune2fs.c	2006-05-24 15:26:05.000000000 +0200
@@ -213,7 +213,18 @@
 	block = *blocknr;
 	ext2fs_unmark_block_bitmap(fs->block_map,block);
 	group = ext2fs_group_of_blk(fs, block);
-	fs->group_desc[group].bg_free_blocks_count++;
+	if (fs->super->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_BIG_BG) {
+		__u32 val;
+
+		val = fs->group_desc[group].bg_free_blocks_count +
+		      ((__u32)fs->group_desc[group].bg_free_blocks_count_hi << 16);
+		val++;
+		fs->group_desc[group].bg_free_blocks_count = val;
+		fs->group_desc[group].bg_free_blocks_count_hi = val >> 16;
+	}
+	else
+		fs->group_desc[group].bg_free_blocks_count++;
+
 	EXT2_FREE_BLOCKS_COUNT_SET(fs->super, EXT2_FREE_BLOCKS_COUNT(fs->super) + 1);
 	return 0;
 }
Index: e2fsprogs/lib/ext2fs/rw_bitmaps.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/rw_bitmaps.c	2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/lib/ext2fs/rw_bitmaps.c	2006-05-24 15:26:05.000000000 +0200
@@ -74,20 +74,22 @@
 	block_bitmap = inode_bitmap = 0;
 	if (do_block) {
 		block_bitmap = fs->block_map->bitmap;
-		block_nbytes = EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
-		retval = ext2fs_get_mem(fs->blocksize, &block_buf);
+		block_nbytes = EXT2_BLOCK_BITMAP_NBYTES(fs->super);
+		retval = ext2fs_get_mem(EXT2_BLOCK_BITMAP_SIZE(fs->super),
+					&block_buf);
 		if (retval)
 			return retval;
-		memset(block_buf, 0xff, fs->blocksize);
+		memset(block_buf, 0xff, EXT2_BLOCK_BITMAP_SIZE(fs->super));
 	}
 	if (do_inode) {
 		inode_bitmap = fs->inode_map->bitmap;
 		inode_nbytes = (size_t) 
-			((EXT2_INODES_PER_GROUP(fs->super)+7) / 8);
-		retval = ext2fs_get_mem(fs->blocksize, &inode_buf);
+			EXT2_INODE_BITMAP_NBYTES(fs->super);
+		retval = ext2fs_get_mem(EXT2_INODE_BITMAP_SIZE(fs->super), 
+					&inode_buf);
 		if (retval)
 			return retval;
-		memset(inode_buf, 0xff, fs->blocksize);
+		memset(inode_buf, 0xff, EXT2_INODE_BITMAP_SIZE(fs->super));
 	}
 
 	for (i = 0; i < fs->group_desc_count; i++) {
@@ -106,7 +108,9 @@
 				  - fs->super->s_first_data_block)
 				 % EXT2_BLOCKS_PER_GROUP(fs->super));
 			if (nbits)
-				for (j = nbits; j < fs->blocksize * 8; j++)
+				for (j = nbits; 
+				     j < EXT2_BLOCK_BITMAP_SIZE(fs->super) * 8;
+				     j++)
 					ext2fs_set_bit(j, block_buf);
 		}
 		if (EXT2_IS_USED_BLOCK_BITMAP(&fs->group_desc[i])) {
@@ -117,7 +121,8 @@
 				ext2fs_swap_bitmap(fs, block_buf, 
 						   block_nbytes);
 #endif
-			retval = io_channel_write_blk(fs->io, blk, 1,
+			retval = io_channel_write_blk(fs->io, blk, 
+					EXT2_BLOCK_BITMAP_PER_GROUP(fs->super),
 						      block_buf);
 			if (retval)
 				return EXT2_ET_BLOCK_BITMAP_WRITE;
@@ -142,7 +147,8 @@
 				ext2fs_swap_bitmap(fs, inode_buf, 
 						   inode_nbytes);
 #endif
-			retval = io_channel_write_blk(fs->io, blk, 1,
+			retval = io_channel_write_blk(fs->io, blk,
+					EXT2_INODE_BITMAP_PER_GROUP(fs->super),
 						      inode_buf);
 			if (retval)
 				return EXT2_ET_INODE_BITMAP_WRITE;
@@ -168,8 +174,8 @@
 	char *block_bitmap = 0, *inode_bitmap = 0;
 	char *buf;
 	errcode_t retval;
-	int block_nbytes = (int) EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
-	int inode_nbytes = (int) EXT2_INODES_PER_GROUP(fs->super) / 8;
+	int block_nbytes = (int) EXT2_BLOCK_BITMAP_NBYTES(fs->super);
+	int inode_nbytes = (int) EXT2_INODE_BITMAP_NBYTES(fs->super);
 	int lazy_flag = 0;
 	blk_t	blk;
 


-------------------------------------------------------
All the advantages of Linux Managed Hosting--Without the Cost and Risk!
Fully trained technicians. The highest number of Red Hat certifications in
the hosting industry. Fanatical Support. Click to learn more
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=107521&bid=248729&dat=121642
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.