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

Alexandre Ratchov <[email protected]>
Newsgroups gmane.comp.file-systems.ext2.devel
Message-ID <[email protected]>
Introduce 64bit management. blk_t becomes 64bit wide. Manage
meta-data structures as introduced by kernel patch "[RFC 3/5]
support >32 bit ext3: 64 bit superblock changes".



Index: e2fsprogs/resize/resize2fs.c
===================================================================
--- e2fsprogs.orig/resize/resize2fs.c	2006-05-24 15:30:20.000000000 +0200
+++ e2fsprogs/resize/resize2fs.c	2006-05-24 15:30:29.000000000 +0200
@@ -52,15 +52,16 @@
 /*
  * Some helper CPP macros
  */
+#define FS_RELATIVE(fs,i) ((((blk_t)fs->super->s_first_data_block + (blk_t)i * (blk_t)fs->super->s_blocks_per_group) >> 32) ? (((blk_t)fs->super->s_first_data_block + (blk_t)i * (blk_t)fs->super->s_blocks_per_group) >> 32) : 0)
 #define FS_BLOCK_BM(fs, i) ((fs)->group_desc[(i)].bg_block_bitmap)
 #define FS_INODE_BM(fs, i) ((fs)->group_desc[(i)].bg_inode_bitmap)
 #define FS_INODE_TB(fs, i) ((fs)->group_desc[(i)].bg_inode_table)
 
-#define IS_BLOCK_BM(fs, i, blk) ((blk) == FS_BLOCK_BM((fs),(i)))
-#define IS_INODE_BM(fs, i, blk) ((blk) == FS_INODE_BM((fs),(i)))
+#define IS_BLOCK_BM(fs, i, blk) ((blk) - FS_RELATIVE(fs,i)== FS_BLOCK_BM((fs),(i)))
+#define IS_INODE_BM(fs, i, blk) ((blk) - FS_RELATIVE(fs,i)== FS_INODE_BM((fs),(i)))
 
-#define IS_INODE_TB(fs, i, blk) (((blk) >= FS_INODE_TB((fs), (i))) && \
-				 ((blk) < (FS_INODE_TB((fs), (i)) + \
+#define IS_INODE_TB(fs, i, blk) (((blk) - FS_RELATIVE(fs,i)>= FS_INODE_TB((fs), (i))) && \
+				 ((blk) - FS_RELATIVE(fs,i)< (FS_INODE_TB((fs), (i)) + \
 					   (fs)->inode_blocks_per_group)))
 
 
@@ -100,7 +101,7 @@
 	if (retval)
 		goto errout;
 
-	*new_size = rfs->new_fs->super->s_blocks_count;
+	*new_size = EXT2_BLOCKS_COUNT(rfs->new_fs->super);
 
 	retval = blocks_to_move(rfs);
 	if (retval)
@@ -109,8 +110,8 @@
 #ifdef RESIZE2FS_DEBUG
 	if (rfs->flags & RESIZE_DEBUG_BMOVE)
 		printf("Number of free blocks: %u/%u, Needed: %d\n",
-		       rfs->old_fs->super->s_free_blocks_count,
-		       rfs->new_fs->super->s_free_blocks_count,
+		       EXT2_FREE_BLOCKS_COUNT(rfs->old_fs->super),
+		       EXT2_FREE_BLOCKS_COUNT(rfs->new_fs->super),
 		       rfs->needed_blocks);
 #endif
 	
@@ -187,10 +188,10 @@
 	unsigned int	meta_bg, meta_bg_size;
 	int		has_super;
 
-	fs->super->s_blocks_count = new_size;
+	EXT2_BLOCKS_COUNT_SET(fs->super, new_size);
 
 retry:
-	fs->group_desc_count = (fs->super->s_blocks_count -
+	fs->group_desc_count = (EXT2_BLOCKS_COUNT(fs->super) -
 				fs->super->s_first_data_block +
 				EXT2_BLOCKS_PER_GROUP(fs->super) - 1)
 		/ EXT2_BLOCKS_PER_GROUP(fs->super);
@@ -217,12 +218,12 @@
 	 * necessary data structures.  If not, we need to get rid of
 	 * it.
 	 */
-	rem = (fs->super->s_blocks_count - fs->super->s_first_data_block) %
+	rem = (EXT2_BLOCKS_COUNT(fs->super) - fs->super->s_first_data_block) %
 		fs->super->s_blocks_per_group;
 	if ((fs->group_desc_count == 1) && rem && (rem < overhead))
 		return EXT2_ET_TOOSMALL;
 	if (rem && (rem < overhead+50)) {
-		fs->super->s_blocks_count -= rem;
+		EXT2_BLOCKS_COUNT_SET(fs->super, EXT2_BLOCKS_COUNT(fs->super) - rem);
 		goto retry;
 	}
 	/*
@@ -234,21 +235,21 @@
 	/*
 	 * Adjust the number of free blocks
 	 */
-	blk = old_fs->super->s_blocks_count;
-	if (blk > fs->super->s_blocks_count)
-		fs->super->s_free_blocks_count -=
-			(blk - fs->super->s_blocks_count);
+	blk =  EXT2_BLOCKS_COUNT(old_fs->super);
+	if (blk > EXT2_BLOCKS_COUNT(fs->super))
+		EXT2_FREE_BLOCKS_COUNT_SET(fs->super, EXT2_FREE_BLOCKS_COUNT(fs->super) -
+				(blk - EXT2_BLOCKS_COUNT(fs->super)));
 	else
-		fs->super->s_free_blocks_count +=
-			(fs->super->s_blocks_count - blk);
+		EXT2_FREE_BLOCKS_COUNT_SET(fs->super, EXT2_FREE_BLOCKS_COUNT(fs->super) +
+				(EXT2_BLOCKS_COUNT(fs->super) - blk));
 
 	/*
 	 * Adjust the number of reserved blocks
 	 */
-	blk = old_fs->super->s_r_blocks_count * 100 /
-		old_fs->super->s_blocks_count;
-	fs->super->s_r_blocks_count = ((fs->super->s_blocks_count * blk)
-				       / 100);
+	blk = EXT2_R_BLOCKS_COUNT(old_fs->super) * 100 /
+		EXT2_BLOCKS_COUNT(old_fs->super);
+	EXT2_R_BLOCKS_COUNT_SET(fs->super,
+			((EXT2_BLOCKS_COUNT(fs->super) * blk) / 100));
 
 	/*
 	 * Adjust the bitmaps for size
@@ -261,7 +262,7 @@
 	real_end = ((EXT2_BLOCKS_PER_GROUP(fs->super)
 		     * fs->group_desc_count)) - 1 +
 			     fs->super->s_first_data_block;
-	retval = ext2fs_resize_block_bitmap(fs->super->s_blocks_count-1,
+	retval = ext2fs_resize_block_bitmap(EXT2_BLOCKS_COUNT(fs->super)-1,
 					    real_end, fs->block_map);
 
 	if (retval) goto errout;
@@ -318,13 +319,13 @@
 	/*
 	 * Fix the count of the last (old) block group
 	 */
-	old_numblocks = (old_fs->super->s_blocks_count -
+	old_numblocks = (EXT2_BLOCKS_COUNT(old_fs->super) -
 			 old_fs->super->s_first_data_block) %
 				 old_fs->super->s_blocks_per_group;
 	if (!old_numblocks)
 		old_numblocks = old_fs->super->s_blocks_per_group;
 	if (old_fs->group_desc_count == fs->group_desc_count) {
-		numblocks = (fs->super->s_blocks_count -
+		numblocks = (EXT2_BLOCKS_COUNT(fs->super) -
 			     fs->super->s_first_data_block) %
 			fs->super->s_blocks_per_group;
 		if (!numblocks)
@@ -364,7 +365,7 @@
 		adjblocks = 0;
 
 		if (i == fs->group_desc_count-1) {
-			numblocks = (fs->super->s_blocks_count -
+			numblocks = (EXT2_BLOCKS_COUNT(fs->super) -
 				     fs->super->s_first_data_block) %
 					     fs->super->s_blocks_per_group;
 			if (!numblocks)
@@ -402,7 +403,7 @@
 		adjblocks += 2 + fs->inode_blocks_per_group;
 		
 		numblocks -= adjblocks;
-		fs->super->s_free_blocks_count -= adjblocks;
+		EXT2_FREE_BLOCKS_COUNT_SET(fs->super, EXT2_FREE_BLOCKS_COUNT(fs->super) - adjblocks);
 		fs->super->s_free_inodes_count +=
 			fs->super->s_inodes_per_group;
 		fs->group_desc[i].bg_free_blocks_count = numblocks;
@@ -498,7 +499,7 @@
 		 * Write out the new inode table
 		 */
 		retval = io_channel_write_blk(fs->io,
-					      fs->group_desc[i].bg_inode_table,
+					      EXT2_INODE_TABLE(&fs->group_desc[i], group_block),
 					      fs->inode_blocks_per_group,
 					      rfs->itable_buf);
 		if (retval) goto errout;
@@ -557,7 +558,7 @@
 		/*
 		 * Mark the blocks used for the inode table
 		 */
-		for (j = 0, b = fs->group_desc[i].bg_inode_table;
+		for (j = 0, b = EXT2_INODE_TABLE(&fs->group_desc[i], block);
 		     j < (unsigned int) fs->inode_blocks_per_group;
 		     j++, b++)
 			ext2fs_mark_block_bitmap(bmap, b);
@@ -566,13 +567,13 @@
 		 * Mark block used for the block bitmap 
 		 */
 		ext2fs_mark_block_bitmap(bmap,
-					 fs->group_desc[i].bg_block_bitmap);
+					 EXT2_BLOCK_BITMAP(&fs->group_desc[i], block));
 
 		/*
 		 * Mark block used for the inode bitmap 
 		 */
 		ext2fs_mark_block_bitmap(bmap,
-					 fs->group_desc[i].bg_inode_bitmap);
+					 EXT2_INODE_BITMAP(&fs->group_desc[i], block));
 		block += fs->super->s_blocks_per_group;
 	}
 	return 0;
@@ -632,7 +633,7 @@
 
 	fs = rfs->new_fs;
 	old_fs = rfs->old_fs;
-	if (old_fs->super->s_blocks_count > fs->super->s_blocks_count)
+	if (EXT2_BLOCKS_COUNT(old_fs->super) > EXT2_BLOCKS_COUNT(fs->super))
 		fs = rfs->old_fs;
 	
 	retval = ext2fs_allocate_block_bitmap(fs, _("reserved blocks"),
@@ -660,8 +661,8 @@
 	 * If we're shrinking the filesystem, we need to move all of
 	 * the blocks that don't fit any more
 	 */
-	for (blk = fs->super->s_blocks_count;
-	     blk < old_fs->super->s_blocks_count; blk++) {
+	for (blk = EXT2_BLOCKS_COUNT(fs->super);
+	     blk < EXT2_BLOCKS_COUNT(old_fs->super); blk++) {
 		if (ext2fs_test_block_bitmap(old_fs->block_map, blk) &&
 		    !ext2fs_test_block_bitmap(meta_bmap, blk)) {
 			ext2fs_mark_block_bitmap(rfs->move_blocks, blk);
@@ -739,23 +740,23 @@
 						  group_blk + has_super);
 		}
 
-		if (fs->group_desc[i].bg_inode_table &&
-		    fs->group_desc[i].bg_inode_bitmap &&
-		    fs->group_desc[i].bg_block_bitmap)
+		if (EXT2_IS_USED_INODE_TABLE(&fs->group_desc[i]) &&
+		    EXT2_IS_USED_INODE_BITMAP(&fs->group_desc[i]) &&
+		    EXT2_IS_USED_BLOCK_BITMAP(&fs->group_desc[i]))
 			goto next_group;
 
 		/*
 		 * Reserve the existing meta blocks that we know
 		 * aren't to be moved.
 		 */
-		if (fs->group_desc[i].bg_block_bitmap)
+		if (EXT2_IS_USED_BLOCK_BITMAP(&fs->group_desc[i]))
 			ext2fs_mark_block_bitmap(rfs->reserve_blocks,
-				 fs->group_desc[i].bg_block_bitmap);
-		if (fs->group_desc[i].bg_inode_bitmap)
+				 EXT2_BLOCK_BITMAP(&fs->group_desc[i], group_blk));
+		if (EXT2_IS_USED_INODE_BITMAP(&fs->group_desc[i]))
 			ext2fs_mark_block_bitmap(rfs->reserve_blocks,
-				 fs->group_desc[i].bg_inode_bitmap);
-		if (fs->group_desc[i].bg_inode_table)
-			for (blk = fs->group_desc[i].bg_inode_table, j=0;
+				 EXT2_INODE_BITMAP(&fs->group_desc[i], group_blk));
+		if (EXT2_IS_USED_INODE_TABLE(&fs->group_desc[i]))
+			for (blk = EXT2_INODE_TABLE(&fs->group_desc[i], group_blk), j=0;
 			     j < fs->inode_blocks_per_group ; j++, blk++)
 				ext2fs_mark_block_bitmap(rfs->reserve_blocks,
 							 blk);
@@ -806,7 +807,7 @@
 		 * allocation bitmap, and move any blocks that might 
 		 * be necessary.
 		 */
-		for (blk = fs->group_desc[i].bg_inode_table, j=0;
+		for (blk = EXT2_INODE_TABLE(&fs->group_desc[i], group_blk), j=0;
 		     j < fs->inode_blocks_per_group ; j++, blk++) {
 			ext2fs_mark_block_bitmap(fs->block_map, blk);
 			if (ext2fs_test_block_bitmap(old_fs->block_map, blk) &&
@@ -819,7 +820,7 @@
 		 * Make sure the old inode table is reserved in the
 		 * block reservation bitmap.
 		 */
-		for (blk = rfs->old_fs->group_desc[i].bg_inode_table, j=0;
+		for (blk = EXT2_INODE_TABLE(&rfs->old_fs->group_desc[i], group_blk), j=0;
 		     j < fs->inode_blocks_per_group ; j++, blk++)
 			ext2fs_mark_block_bitmap(rfs->reserve_blocks, blk);
 		
@@ -858,9 +859,9 @@
 	rfs->new_blk = rfs->new_fs->super->s_first_data_block;
 #if 0
 	/* HACK for testing */
-	if (rfs->new_fs->super->s_blocks_count >
-	    rfs->old_fs->super->s_blocks_count)
-		rfs->new_blk = rfs->old_fs->super->s_blocks_count;
+	if (EXT2_BLOCKS_COUNT(rfs->new_fs->super) >
+	    EXT2_BLOCKS_COUNT(rfs->old_fs->super))
+		rfs->new_blk = EXT2_BLOCKS_COUNT(rfs->old_fs->super);
 #endif
 }
 
@@ -869,7 +870,7 @@
 	ext2_filsys	fs = rfs->new_fs;
 	
 	while (1) {
-		if (rfs->new_blk >= fs->super->s_blocks_count) {
+		if (rfs->new_blk >= EXT2_BLOCKS_COUNT(fs->super)) {
 			if (rfs->alloc_state == DESPERATION)
 				return 0;
 
@@ -886,7 +887,7 @@
 		    ext2fs_test_block_bitmap(rfs->reserve_blocks,
 					     rfs->new_blk) ||
 		    ((rfs->alloc_state == AVOID_OLD) &&
-		     (rfs->new_blk < rfs->old_fs->super->s_blocks_count) &&
+		     (rfs->new_blk < EXT2_BLOCKS_COUNT(rfs->old_fs->super)) &&
 		     ext2fs_test_block_bitmap(rfs->old_fs->block_map,
 					      rfs->new_blk))) {
 			rfs->new_blk++;
@@ -931,7 +932,7 @@
 	to_move = moved = 0;
 	init_block_alloc(rfs);
 	for (blk = old_fs->super->s_first_data_block;
-	     blk < old_fs->super->s_blocks_count; blk++) {
+	     blk < EXT2_BLOCKS_COUNT(old_fs->super); blk++) {
 		if (!ext2fs_test_block_bitmap(old_fs->block_map, blk))
 			continue;
 		if (!ext2fs_test_block_bitmap(rfs->move_blocks, blk))
@@ -1125,10 +1126,10 @@
 	 * is larger.  We need to do this to avoid catching an error
 	 * by the block iterator routines
 	 */
-	orig_size = rfs->old_fs->super->s_blocks_count;
-	if (orig_size < rfs->new_fs->super->s_blocks_count)
-		rfs->old_fs->super->s_blocks_count =
-			rfs->new_fs->super->s_blocks_count;
+	orig_size = EXT2_BLOCKS_COUNT(rfs->old_fs->super);
+	if (orig_size < EXT2_BLOCKS_COUNT(rfs->new_fs->super))
+		EXT2_BLOCKS_COUNT_SET(rfs->old_fs->super,
+			EXT2_BLOCKS_COUNT(rfs->new_fs->super));
 
 	retval = ext2fs_open_inode_scan(rfs->old_fs, 0, &scan);
 	if (retval) goto errout;
@@ -1237,7 +1238,7 @@
 	io_channel_flush(rfs->old_fs->io);
 
 errout:
-	rfs->old_fs->super->s_blocks_count = orig_size;
+	EXT2_BLOCKS_COUNT_SET(rfs->old_fs->super, orig_size);
 	if (rfs->bmap) {
 		ext2fs_free_extent_table(rfs->bmap);
 		rfs->bmap = 0;
@@ -1396,10 +1397,13 @@
 	 * Figure out how many inode tables we need to move
 	 */
 	to_move = moved = 0;
-	for (i=0; i < max_groups; i++)
-		if (rfs->old_fs->group_desc[i].bg_inode_table !=
-		    fs->group_desc[i].bg_inode_table)
+	for (i=0; i < max_groups; i++) {
+		if (EXT2_INODE_TABLE(&rfs->old_fs->group_desc[i],
+					EXT2_GROUP_BASE(rfs->old_fs->super, i)) !=
+		    EXT2_INODE_TABLE(&fs->group_desc[i],
+			    		EXT2_GROUP_BASE(fs->super, i)))
 			to_move++;
+	}
 
 	if (to_move == 0)
 		return 0;
@@ -1414,8 +1418,10 @@
 	rfs->old_fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
 
 	for (i=0; i < max_groups; i++) {
-		old_blk = rfs->old_fs->group_desc[i].bg_inode_table;
-		new_blk = fs->group_desc[i].bg_inode_table;
+		old_blk = EXT2_INODE_TABLE(&rfs->old_fs->group_desc[i],
+				EXT2_GROUP_BASE(rfs->old_fs->super, i));
+		new_blk = EXT2_INODE_TABLE(&fs->group_desc[i],
+				EXT2_GROUP_BASE(fs->super, i));
 		diff = new_blk - old_blk;
 		
 #ifdef RESIZE2FS_DEBUG
@@ -1468,11 +1474,13 @@
 				goto errout;
 		}
 
-		for (blk = rfs->old_fs->group_desc[i].bg_inode_table, j=0;
+		for (blk = EXT2_INODE_TABLE(&rfs->old_fs->group_desc[i], 
+					EXT2_GROUP_BASE(rfs->old_fs->super, i)), j=0;
 		     j < fs->inode_blocks_per_group ; j++, blk++)
 			ext2fs_unmark_block_bitmap(fs->block_map, blk);
 
-		rfs->old_fs->group_desc[i].bg_inode_table = new_blk;
+		EXT2_INODE_TABLE_SET(&rfs->old_fs->group_desc[i], 
+					EXT2_GROUP_BASE(rfs->old_fs->super, i), new_blk);
 		ext2fs_mark_super_dirty(rfs->old_fs);
 		ext2fs_flush(rfs->old_fs);
 
@@ -1562,21 +1570,21 @@
 	 * First calculate the block statistics
 	 */
 	for (blk = fs->super->s_first_data_block;
-	     blk < fs->super->s_blocks_count; blk++) {
+	     blk < EXT2_BLOCKS_COUNT(fs->super); blk++) {
 		if (!ext2fs_fast_test_block_bitmap(fs->block_map, blk)) {
 			group_free++;
 			total_free++;
 		}
 		count++;
 		if ((count == fs->super->s_blocks_per_group) ||
-		    (blk == fs->super->s_blocks_count-1)) {
+		    (blk == EXT2_BLOCKS_COUNT(fs->super)-1)) {
 			fs->group_desc[group++].bg_free_blocks_count =
 				group_free;
 			count = 0;
 			group_free = 0;
 		}
 	}
-	fs->super->s_free_blocks_count = total_free;
+	EXT2_FREE_BLOCKS_COUNT_SET(fs->super, total_free);
 	
 	/*
 	 * Next, calculate the inode statistics
Index: e2fsprogs/misc/dumpe2fs.c
===================================================================
--- e2fsprogs.orig/misc/dumpe2fs.c	2006-05-24 15:30:20.000000000 +0200
+++ e2fsprogs/misc/dumpe2fs.c	2006-05-24 15:30:29.000000000 +0200
@@ -58,9 +58,9 @@
 static void print_number(blk_t num)
 {
 	if (hex_format) 
-		printf("0x%04lx", num);
+		printf("0x%04llx", num);
 	else
-		printf("%lu", num);
+		printf("%llu", num);
 }
 
 static void print_range(unsigned long a, unsigned long b)
@@ -156,8 +156,8 @@
 		ext2fs_super_and_bgd_loc(fs, i, &super_blk, 
 					 &old_desc_blk, &new_desc_blk, 0);
 		next_blk = group_blk + fs->super->s_blocks_per_group;
-		if (next_blk > fs->super->s_blocks_count)
-			next_blk = fs->super->s_blocks_count;
+		if (next_blk > EXT2_BLOCKS_COUNT(fs->super))
+			next_blk = EXT2_BLOCKS_COUNT(fs->super);
 		printf (_("Group %lu: (Blocks "), i);
 		print_range(group_blk, next_blk - 1);
 		fputs(")", stdout);
@@ -187,20 +187,20 @@
 		if (has_super)
 			fputc('\n', stdout);
 		fputs(_("  Block bitmap at "), stdout);
-		print_number(fs->group_desc[i].bg_block_bitmap);
-		diff = fs->group_desc[i].bg_block_bitmap - group_blk;
+		print_number(EXT2_BLOCK_BITMAP(&fs->group_desc[i], group_blk));
+		diff = EXT2_BLOCK_BITMAP(&fs->group_desc[i], group_blk) - group_blk;
 		if (diff >= 0)
 			printf(" (+%ld)", diff);
 		fputs(_(", Inode bitmap at "), stdout);
-		print_number(fs->group_desc[i].bg_inode_bitmap);
-		diff = fs->group_desc[i].bg_inode_bitmap - group_blk;
+		print_number(EXT2_INODE_BITMAP(&fs->group_desc[i], group_blk));
+		diff = EXT2_INODE_BITMAP(&fs->group_desc[i], group_blk) - group_blk;
 		if (diff >= 0)
 			printf(" (+%ld)", diff);
 		fputs(_("\n  Inode table at "), stdout);
-		print_range(fs->group_desc[i].bg_inode_table,
-			    fs->group_desc[i].bg_inode_table +
+		print_range(EXT2_INODE_TABLE(&fs->group_desc[i], group_blk),
+			    EXT2_INODE_TABLE(&fs->group_desc[i], group_blk) +
 			    inode_blocks_per_group - 1);
-		diff = fs->group_desc[i].bg_inode_table - group_blk;
+		diff = EXT2_INODE_TABLE(&fs->group_desc[i], group_blk) - group_blk;
 		if (diff > 0)
 			printf(" (+%ld)", diff);
 		printf (_("\n  %d free blocks, %d free inodes, "
Index: e2fsprogs/lib/ext2fs/ext_attr.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/ext_attr.c	2006-05-24 15:30:05.000000000 +0200
+++ e2fsprogs/lib/ext2fs/ext_attr.c	2006-05-24 15:30:29.000000000 +0200
@@ -74,7 +74,7 @@
 	struct ext2_ext_attr_header *header;
 	char	*buf = 0;
 
-	if ((blk >= fs->super->s_blocks_count) ||
+	if ((blk >= EXT2_BLOCKS_COUNT(fs->super)) ||
 	    (blk < fs->super->s_first_data_block))
 		return EXT2_ET_BAD_EA_BLOCK_NUM;
 
Index: e2fsprogs/misc/mke2fs.c
===================================================================
--- e2fsprogs.orig/misc/mke2fs.c	2006-05-24 15:30:20.000000000 +0200
+++ e2fsprogs/misc/mke2fs.c	2006-05-24 15:30:29.000000000 +0200
@@ -190,7 +190,7 @@
 
 	sprintf(buf, "badblocks -b %d -X %s%s%s %d", fs->blocksize,
 		quiet ? "" : "-s ", (cflag > 1) ? "-w " : "",
-		fs->device_name, fs->super->s_blocks_count);
+		fs->device_name, EXT2_BLOCKS_COUNT(fs->super));
 	if (verbose)
 		printf(_("Running command: %s\n"), buf);
 	f = popen(buf, "r");
@@ -261,7 +261,7 @@
 				group_bad++;
 				group = ext2fs_group_of_blk(fs, group_block+j);
 				fs->group_desc[group].bg_free_blocks_count++;
-				fs->super->s_free_blocks_count++;
+				EXT2_FREE_BLOCKS_COUNT_SET(fs->super, EXT2_FREE_BLOCKS_COUNT(fs->super) + 1);
 			}
 		}
 		group_block += fs->super->s_blocks_per_group;
@@ -418,7 +418,7 @@
 	for (i = 0; i < fs->group_desc_count; i++) {
 		progress_update(&progress, i);
 		
-		blk = fs->group_desc[i].bg_inode_table;
+		blk = EXT2_INODE_TABLE(&fs->group_desc[i], EXT2_GROUP_BASE(fs->super, i));
 		num = fs->inode_blocks_per_group;
 
 		if (!(lazy_flag &&
@@ -466,7 +466,8 @@
 			if (bg->bg_free_blocks_count == blks) {
 				bg->bg_free_blocks_count = 0;
 				bg->bg_flags |= EXT2_BG_BLOCK_UNINIT;
-				sb->s_free_blocks_count -= blks;
+				EXT2_FREE_BLOCKS_COUNT_SET(sb, 
+						EXT2_FREE_BLOCKS_COUNT(sb) - blks);
 			}
 		}
 	}
@@ -525,14 +526,16 @@
 		exit(1);
 	}
 	
-	for (i=1; i < EXT2_NDIR_BLOCKS; i++) {
-		if ((lpf_size += fs->blocksize) >= 16*1024)
-			break;
-		retval = ext2fs_expand_dir(fs, ino);
-		if (retval) {
-			com_err("ext2fs_expand_dir", retval,
-				_("while expanding /lost+found"));
-			exit(1);
+	if (!(fs->super->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_64BIT)) {
+		for (i=1; i < EXT2_NDIR_BLOCKS; i++) {
+			if ((lpf_size += fs->blocksize) >= 16*1024)
+				break;
+			retval = ext2fs_expand_dir(fs, ino);
+			if (retval) {
+				com_err("ext2fs_expand_dir", retval,
+					_("while expanding /lost+found"));
+				exit(1);
+			}
 		}
 	}
 }
@@ -618,7 +621,7 @@
 	int			count;
 
 	retval = ext2fs_create_journal_superblock(fs,
-				  fs->super->s_blocks_count, 0, &buf);
+				  EXT2_BLOCKS_COUNT(fs->super), 0, &buf);
 	if (retval) {
 		com_err("create_journal_dev", retval,
 			_("while initializing journal superblock"));
@@ -628,9 +631,9 @@
 		memset(&progress, 0, sizeof(progress));
 	else
 		progress_init(&progress, _("Zeroing journal device: "),
-			      fs->super->s_blocks_count);
+			      EXT2_BLOCKS_COUNT(fs->super));
 
-	retval = zero_blocks(fs, 0, fs->super->s_blocks_count,
+	retval = zero_blocks(fs, 0, EXT2_BLOCKS_COUNT(fs->super),
 			     &progress, &blk, &count);
 	if (retval) {
 		com_err("create_journal_dev", retval,
@@ -660,9 +663,9 @@
 	dgrp_t			i;
 	int			need, col_left;
 	
-	if (fs_param.s_blocks_count != s->s_blocks_count)
+	if (EXT2_BLOCKS_COUNT(&fs_param) != EXT2_BLOCKS_COUNT(s))
 		fprintf(stderr, _("warning: %u blocks unused.\n\n"),
-		       fs_param.s_blocks_count - s->s_blocks_count);
+		       EXT2_BLOCKS_COUNT(&fs_param) - EXT2_BLOCKS_COUNT(s));
 
 	memset(buf, 0, sizeof(buf));
 	strncpy(buf, s->s_volume_name, sizeof(s->s_volume_name));
@@ -676,11 +679,11 @@
 		s->s_log_block_size);
 	printf(_("Fragment size=%u (log=%u)\n"), fs->fragsize,
 		s->s_log_frag_size);
-	printf(_("%u inodes, %lu blocks\n"), s->s_inodes_count,
-	       s->s_blocks_count);
-	printf(_("%lu blocks (%2.2f%%) reserved for the super user\n"),
-		s->s_r_blocks_count,
-	       100.0 * s->s_r_blocks_count / s->s_blocks_count);
+	printf(_("%u inodes, %llu blocks\n"), s->s_inodes_count,
+	       EXT2_BLOCKS_COUNT(s));
+	printf(_("%llu blocks (%2.2f%%) reserved for the super user\n"),
+		EXT2_R_BLOCKS_COUNT(s),
+	       100.0 * EXT2_R_BLOCKS_COUNT(s) / EXT2_BLOCKS_COUNT(s));
 	printf(_("First data block=%u\n"), s->s_first_data_block);
 	if (s->s_reserved_gdt_blocks)
 		printf(_("Maximum filesystem blocks=%lu\n"),
@@ -715,7 +718,7 @@
 			col_left = 72;
 		}
 		col_left -= need;
-		printf("%lu", group_block);
+		printf("%llu", group_block);
 	}
 	printf("\n\n");
 }
@@ -806,7 +809,7 @@
 				r_usage++;
 				continue;
 			}
-			if (resize <= param->s_blocks_count) {
+			if (resize <= EXT2_BLOCKS_COUNT(param)) {
 				fprintf(stderr, 
 					_("The resize maximum must be greater "
 					  "than the filesystem size.\n"));
@@ -819,7 +822,7 @@
 			if (!bpg)
 				bpg = blocksize * 8;
 			gdpb = blocksize / sizeof(struct ext2_group_desc);
-			group_desc_count = (param->s_blocks_count +
+			group_desc_count = (EXT2_BLOCKS_COUNT(param) +
 					    bpg - 1) / bpg;
 			desc_blocks = (group_desc_count +
 				       gdpb - 1) / gdpb;
@@ -1189,9 +1192,10 @@
 			blocksize, sys_page_size);
 	}
 	if (optind < argc) {
-		fs_param.s_blocks_count = parse_num_blocks(argv[optind++], 
-				fs_param.s_log_block_size);
-		if (!fs_param.s_blocks_count) {
+		EXT2_BLOCKS_COUNT_SET(&fs_param,
+				parse_num_blocks(argv[optind++], 
+				fs_param.s_log_block_size));
+		if (!EXT2_BLOCKS_COUNT(&fs_param)) {
 			com_err(program_name, 0, _("invalid blocks count - %s"),
 				argv[optind - 1]);
 			exit(1);
@@ -1206,8 +1210,8 @@
 
 	fs_param.s_log_frag_size = fs_param.s_log_block_size;
 
-	if (noaction && fs_param.s_blocks_count) {
-		dev_size = fs_param.s_blocks_count;
+	if (noaction && (EXT2_BLOCKS_COUNT(&fs_param))) {
+		dev_size = EXT2_BLOCKS_COUNT(&fs_param);
 		retval = 0;
 	} else {
 	retry:
@@ -1228,7 +1232,7 @@
 			_("while trying to determine filesystem size"));
 		exit(1);
 	}
-	if (!fs_param.s_blocks_count) {
+	if (!EXT2_BLOCKS_COUNT(&fs_param)) {
 		if (retval == EXT2_ET_UNIMPLEMENTED) {
 			com_err(program_name, 0,
 				_("Couldn't determine device size; you "
@@ -1248,20 +1252,24 @@
 				  ));
 				exit(1);
 			}
-			fs_param.s_blocks_count = dev_size;
+			if (dev_size >> 31) {
+				fs_param.s_feature_ro_compat |= EXT2_FEATURE_RO_COMPAT_64BIT;
+			}
+			EXT2_BLOCKS_COUNT_SET(&fs_param, dev_size);
 			if (sys_page_size > EXT2_BLOCK_SIZE(&fs_param))
-				fs_param.s_blocks_count &= ~((sys_page_size /
-					   EXT2_BLOCK_SIZE(&fs_param))-1);
+				EXT2_BLOCKS_COUNT_SET(&fs_param,
+						EXT2_BLOCKS_COUNT(&fs_param) & ~((sys_page_size /
+								EXT2_BLOCK_SIZE(&fs_param))-1));
 		}
 		
-	} else if (!force && (fs_param.s_blocks_count > dev_size)) {
+	} else if (!force && (EXT2_BLOCKS_COUNT(&fs_param) > dev_size)) {
 		com_err(program_name, 0,
 			_("Filesystem larger than apparent device size."));
 		proceed_question();
 	}
 
 	if (!fs_type) {
-		int megs = fs_param.s_blocks_count * 
+		int megs = EXT2_BLOCKS_COUNT(&fs_param) *
 			(EXT2_BLOCK_SIZE(&fs_param) / 1024) / 1024;
 
 		if (megs <= 3)
@@ -1358,7 +1366,7 @@
 		if ((blocksize < 0) && (use_bsize < (-blocksize)))
 			use_bsize = -blocksize;
 		blocksize = use_bsize;
-		fs_param.s_blocks_count /= blocksize / 1024;
+		EXT2_BLOCKS_COUNT_SET(&fs_param, EXT2_BLOCKS_COUNT(&fs_param) / (blocksize / 1024));
 	}
 
 	if (inode_ratio == 0) {
@@ -1427,14 +1435,15 @@
 	 * Calculate number of inodes based on the inode ratio
 	 */
 	fs_param.s_inodes_count = num_inodes ? num_inodes : 
-		((__u64) fs_param.s_blocks_count * blocksize)
+		((__u64) EXT2_BLOCKS_COUNT(&fs_param) * blocksize)
 			/ inode_ratio;
 
 	/*
 	 * Calculate number of blocks to reserve
 	 */
-	fs_param.s_r_blocks_count = (fs_param.s_blocks_count * reserved_ratio)
-		/ 100;
+	EXT2_R_BLOCKS_COUNT_SET(&fs_param, 
+		(EXT2_BLOCKS_COUNT(&fs_param) * reserved_ratio)
+		/ 100);
 }
 
 int main (int argc, char *argv[])
@@ -1565,7 +1574,7 @@
 	} else {
 		/* rsv must be a power of two (64kB is MD RAID sb alignment) */
 		unsigned int rsv = 65536 / fs->blocksize;
-		unsigned long blocks = fs->super->s_blocks_count;
+		unsigned long blocks = EXT2_BLOCKS_COUNT(fs->super);
 		unsigned long start;
 		blk_t ret_blk;
 
Index: e2fsprogs/lib/ext2fs/ext2_fs.h
===================================================================
--- e2fsprogs.orig/lib/ext2fs/ext2_fs.h	2006-05-24 15:30:20.000000000 +0200
+++ e2fsprogs/lib/ext2fs/ext2_fs.h	2006-05-24 15:30:29.000000000 +0200
@@ -152,6 +152,38 @@
 #define EXT2_BG_INODE_UNINIT	0x0001 /* Inode table/bitmap not initialized */
 #define EXT2_BG_BLOCK_UNINIT	0x0002 /* Block bitmap not initialized */
 
+#define EXT2_GROUP_BASE(s,g)	((blk_t)(s)->s_first_data_block + \
+				 (blk_t)(s)->s_blocks_per_group * (g))
+
+#define EXT2_RELATIVE(group_base, block)		   \
+	((blk_t)(block) < (blk_t)(group_base) ?	   \
+		(blk_t)(block) + (blk_t)(group_base) - 1 : \
+		(blk_t)(block))
+#define EXT2_RELATIVE_SET(group_base, block, value)		 \
+	(block) = (blk_t)(value) & 0xFFFFFFFF00000000ULL ? \
+		  (blk_t)(value) - (blk_t)(group_base) + 1 :	 \
+		  (blk_t)(value)
+
+#define EXT2_BLOCK_BITMAP(bg, group_base)	\
+		EXT2_RELATIVE((group_base),(bg)->bg_block_bitmap)
+#define EXT2_INODE_BITMAP(bg, group_base)	\
+		EXT2_RELATIVE((group_base),(bg)->bg_inode_bitmap)
+#define EXT2_INODE_TABLE(bg, group_base)	\
+		EXT2_RELATIVE((group_base),(bg)->bg_inode_table)
+
+#define EXT2_BLOCK_BITMAP_SET(bg, group_base, value)	\
+		EXT2_RELATIVE_SET((group_base),(bg)->bg_block_bitmap, value)
+#define EXT2_INODE_BITMAP_SET(bg, group_base, value)	\
+		EXT2_RELATIVE_SET((group_base),(bg)->bg_inode_bitmap, value)
+#define EXT2_INODE_TABLE_SET(bg, group_base, value)	\
+		EXT2_RELATIVE_SET((group_base),(bg)->bg_inode_table, value)
+
+#define EXT2_IS_USED_BLOCK_BITMAP(bg)	\
+	((bg)->bg_block_bitmap != 0)
+#define EXT2_IS_USED_INODE_BITMAP(bg)	\
+	((bg)->bg_inode_bitmap != 0)
+#define EXT2_IS_USED_INODE_TABLE(bg)	\
+	((bg)->bg_inode_table != 0)
 /*
  * Data structures used by the directory indexing feature
  *
@@ -526,11 +558,36 @@
 	__u16	s_reserved_word_pad;
 	__u32	s_default_mount_opts;
 	__u32	s_first_meta_bg;	/* First metablock group */
+	/* 64bit support valid if EXT3_FEATURE_RO_COMPAT_64BIT */
+	__u32	s_blocks_count_hi;	/* Blocks count */
+	__u32	s_r_blocks_count_hi;	/* Reserved blocks count */
+	__u32	s_free_blocks_count_hi;	/* Free blocks count */
 	__u32	s_mkfs_time;		/* When the filesystem was created */
 	__u32	s_jnl_blocks[17]; 	/* Backup of the journal inode */
 	__u32	s_reserved[172];	/* Padding to the end of the block */
 };
 
+#define EXT2_BLOCKS_COUNT(s)	(((s)->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_64BIT ? ((__u64)(s)->s_blocks_count_hi << 32) : 0) | (__u64)(s)->s_blocks_count)
+#define EXT2_BLOCKS_COUNT_SET(s,v)	do {				\
+	(s)->s_blocks_count = (v);					\
+	if ((s)->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_64BIT)	\
+		(s)->s_blocks_count_hi = ((__u64)(v)) >> 32;		\
+} while (0)
+
+#define EXT2_R_BLOCKS_COUNT(s)	(((s)->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_64BIT ? ((__u64)(s)->s_r_blocks_count_hi << 32) : 0) | (__u64)(s)->s_r_blocks_count)
+#define EXT2_R_BLOCKS_COUNT_SET(s,v)	do {				\
+	(s)->s_r_blocks_count = (v);					\
+	if ((s)->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_64BIT)	\
+		(s)->s_r_blocks_count_hi = ((__u64)(v)) >> 32;		\
+} while (0)
+
+#define EXT2_FREE_BLOCKS_COUNT(s)	(((s)->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_64BIT ? ((__u64)(s)->s_free_blocks_count_hi << 32) : 0) | (__u64)(s)->s_free_blocks_count)
+#define EXT2_FREE_BLOCKS_COUNT_SET(s,v)	do {				\
+	(s)->s_free_blocks_count = (v);					\
+	if ((s)->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_64BIT)	\
+		(s)->s_free_blocks_count_hi = ((__u64)(v)) >> 32;	\
+} while (0)
+
 /*
  * Codes for operating systems
  */
@@ -578,6 +635,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_64BIT		0x0010
 
 #define EXT2_FEATURE_INCOMPAT_COMPRESSION	0x0001
 #define EXT2_FEATURE_INCOMPAT_FILETYPE		0x0002
@@ -591,7 +649,8 @@
 #define EXT2_FEATURE_INCOMPAT_SUPP	(EXT2_FEATURE_INCOMPAT_FILETYPE)
 #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_BTREE_DIR| \
+					 EXT2_FEATURE_RO_COMPAT_64BIT)
 
 /*
  * Default values for user and/or group using reserved blocks
Index: e2fsprogs/lib/ext2fs/bb_inode.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/bb_inode.c	2006-05-24 15:30:18.000000000 +0200
+++ e2fsprogs/lib/ext2fs/bb_inode.c	2006-05-24 15:30:29.000000000 +0200
@@ -166,7 +166,7 @@
 	/*
 	 * If the block number is outrageous, clear it and ignore it.
 	 */
-	if (*block_nr >= fs->super->s_blocks_count ||
+	if (*block_nr >= EXT2_BLOCKS_COUNT(fs->super) ||
 	    *block_nr < fs->super->s_first_data_block) {
 		*block_nr = 0;
 		return BLOCK_CHANGED;
Index: e2fsprogs/e2fsck/swapfs.c
===================================================================
--- e2fsprogs.orig/e2fsck/swapfs.c	2006-05-24 15:30:05.000000000 +0200
+++ e2fsprogs/e2fsck/swapfs.c	2006-05-24 15:30:29.000000000 +0200
@@ -131,7 +131,8 @@
 						    "block interate buffer");
 	for (group = 0; group < fs->group_desc_count; group++) {
 		retval = io_channel_read_blk(fs->io,
-		      fs->group_desc[group].bg_inode_table,
+		      EXT2_INODE_TABLE(&fs->group_desc[group], 
+			      EXT2_GROUP_BASE(fs->super, group)),
 		      fs->inode_blocks_per_group, buf);
 		if (retval) {
 			com_err("swap_inodes", retval,
@@ -169,7 +170,8 @@
 				ext2fs_swap_inode(fs, inode, inode, 1);
 		}
 		retval = io_channel_write_blk(fs->io,
-		      fs->group_desc[group].bg_inode_table,
+		      EXT2_INODE_TABLE(&fs->group_desc[group], 
+			      EXT2_GROUP_BASE(fs->super, group)),
 		      fs->inode_blocks_per_group, buf);
 		if (retval) {
 			com_err("swap_inodes", retval,
Index: e2fsprogs/debugfs/lsdel.c
===================================================================
--- e2fsprogs.orig/debugfs/lsdel.c	2006-05-24 15:30:05.000000000 +0200
+++ e2fsprogs/debugfs/lsdel.c	2006-05-24 15:30:29.000000000 +0200
@@ -57,7 +57,7 @@
 	lsd->num_blocks++;
 
 	if (*block_nr < fs->super->s_first_data_block ||
-	    *block_nr >= fs->super->s_blocks_count) {
+	    *block_nr >= EXT2_BLOCKS_COUNT(fs->super)) {
 		lsd->bad_blocks++;
 		return BLOCK_ABORT;
 	}
Index: e2fsprogs/lib/ext2fs/initialize.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/initialize.c	2006-05-24 15:30:20.000000000 +0200
+++ e2fsprogs/lib/ext2fs/initialize.c	2006-05-24 15:30:29.000000000 +0200
@@ -75,8 +75,8 @@
 	/* We set it at 1024x the current filesystem size, or
 	 * the upper block count limit (2^32), whichever is lower.
 	 */
-	if (sb->s_blocks_count < max_blocks / 1024)
-		max_blocks = sb->s_blocks_count * 1024;
+	if (EXT2_BLOCKS_COUNT(sb) < max_blocks / 1024)
+		max_blocks = EXT2_BLOCKS_COUNT(sb) * 1024;
 	rsv_groups = (max_blocks - sb->s_first_data_block + bpg - 1) / bpg;
 	rsv_gdb = (rsv_groups + gdpb - 1) / gdpb - fs->desc_blocks;
 	if (rsv_gdb > EXT2_ADDR_PER_BLOCK(sb))
@@ -106,8 +106,9 @@
 	int		rsv_gdt;
 	int		io_flags;
 	char		*buf;
+	blk_t		inodes;
 
-	if (!param || !param->s_blocks_count)
+	if (!param || !EXT2_BLOCKS_COUNT(param))
 		return EXT2_ET_INVALID_ARGUMENT;
 	
 	retval = ext2fs_get_mem(sizeof(struct struct_ext2_filsys), &fs);
@@ -180,15 +181,16 @@
 	fs->fragsize = EXT2_FRAG_SIZE(super);
 	frags_per_block = fs->blocksize / fs->fragsize;
 
-	/* default: (fs->blocksize*8) blocks/group, up to 2^16 (GDT limit) */
 	set_field(s_blocks_per_group, fs->blocksize * 8);
+	/* default: (fs->blocksize*8) blocks/group, up to 2^16 (GDT limit) */
 	if (super->s_blocks_per_group > EXT2_MAX_BLOCKS_PER_GROUP(super))
 		super->s_blocks_per_group = EXT2_MAX_BLOCKS_PER_GROUP(super);
+
 	super->s_frags_per_group = super->s_blocks_per_group * frags_per_block;
 	
-	super->s_blocks_count = param->s_blocks_count;
-	super->s_r_blocks_count = param->s_r_blocks_count;
-	if (super->s_r_blocks_count >= param->s_blocks_count) {
+	EXT2_BLOCKS_COUNT_SET(super, EXT2_BLOCKS_COUNT(param));
+	EXT2_R_BLOCKS_COUNT_SET(super, EXT2_R_BLOCKS_COUNT(param));
+	if (EXT2_R_BLOCKS_COUNT(super) >= EXT2_BLOCKS_COUNT(param)) {
 		retval = EXT2_ET_INVALID_ARGUMENT;
 		goto cleanup;
 	}
@@ -205,7 +207,7 @@
 	}
 
 retry:
-	fs->group_desc_count = (super->s_blocks_count -
+	fs->group_desc_count = (EXT2_BLOCKS_COUNT(super) -
 				super->s_first_data_block +
 				EXT2_BLOCKS_PER_GROUP(super) - 1)
 		/ EXT2_BLOCKS_PER_GROUP(super);
@@ -218,7 +220,10 @@
 		/ EXT2_DESC_PER_BLOCK(super);
 
 	i = fs->blocksize >= 4096 ? 1 : 4096 / fs->blocksize;
-	set_field(s_inodes_count, super->s_blocks_count / i);
+	inodes = EXT2_BLOCKS_COUNT(super) / i;
+	if (inodes & 0xFFFFFFFF00000000ULL)
+		inodes = 0xFFFFFFFF;
+	set_field(s_inodes_count, inodes);
 
 	/*
 	 * Make sure we have at least EXT2_FIRST_INO + 1 inodes, so
@@ -239,7 +244,7 @@
 		if (super->s_blocks_per_group >= 256) {
 			/* Try again with slightly different parameters */
 			super->s_blocks_per_group -= 8;
-			super->s_blocks_count = param->s_blocks_count;
+			EXT2_BLOCKS_COUNT_SET(super, EXT2_BLOCKS_COUNT(param));
 			super->s_frags_per_group = super->s_blocks_per_group *
 				frags_per_block;
 			goto retry;
@@ -318,12 +323,12 @@
 	 * necessary data structures.  If not, we need to get rid of
 	 * it.
 	 */
-	rem = ((super->s_blocks_count - super->s_first_data_block) %
+	rem = ((EXT2_BLOCKS_COUNT(super) - super->s_first_data_block) %
 	       super->s_blocks_per_group);
 	if ((fs->group_desc_count == 1) && rem && (rem < overhead))
 		return EXT2_ET_TOOSMALL;
 	if (rem && (rem < overhead+50)) {
-		super->s_blocks_count -= rem;
+		EXT2_BLOCKS_COUNT_SET(super, EXT2_BLOCKS_COUNT(super) - rem);
 		goto retry;
 	}
 
@@ -364,11 +369,11 @@
 	 * by this routine), they are accounted for nevertheless.
 	 */
 	group_block = super->s_first_data_block;
-	super->s_free_blocks_count = 0;
+	EXT2_FREE_BLOCKS_COUNT_SET(super, 0);
 	for (i = 0; i < fs->group_desc_count; i++) {
 		numblocks = ext2fs_reserve_super_and_bgd(fs, i, fs->block_map);
 
-		super->s_free_blocks_count += numblocks;
+		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_inodes_count =
 			fs->super->s_inodes_per_group;
Index: e2fsprogs/lib/ext2fs/openfs.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/openfs.c	2006-05-24 15:30:05.000000000 +0200
+++ e2fsprogs/lib/ext2fs/openfs.c	2006-05-24 15:30:29.000000000 +0200
@@ -42,8 +42,7 @@
 	bg = (fs->blocksize / sizeof (struct ext2_group_desc)) * i;
 	if (ext2fs_bg_has_super(fs, bg))
 		has_super = 1;
-	ret_blk = (fs->super->s_first_data_block + has_super + 
-		   (bg * fs->super->s_blocks_per_group));
+	ret_blk = EXT2_GROUP_BASE(fs->super, bg) + has_super;
 	/*
 	 * If group_block is not the normal value, we're trying to use
 	 * the backup group descriptors and superblock --- so use the
@@ -54,7 +53,7 @@
 	 */
 	if (group_block != fs->super->s_first_data_block &&
 	    ((ret_blk + fs->super->s_blocks_per_group) <
-	     fs->super->s_blocks_count))
+	     EXT2_BLOCKS_COUNT(fs->super)))
 		ret_blk += fs->super->s_blocks_per_group;
 	return ret_blk;
 }
@@ -258,7 +257,7 @@
 		retval = EXT2_ET_CORRUPT_SUPERBLOCK;
 		goto cleanup;
 	}
-	fs->group_desc_count = (fs->super->s_blocks_count -
+	fs->group_desc_count = (EXT2_BLOCKS_COUNT(fs->super) -
 				fs->super->s_first_data_block +
 				blocks_per_group - 1) / blocks_per_group;
 	fs->desc_blocks = (fs->group_desc_count +
Index: e2fsprogs/lib/ext2fs/read_bb.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/read_bb.c	2006-05-24 15:30:05.000000000 +0200
+++ e2fsprogs/lib/ext2fs/read_bb.c	2006-05-24 15:30:29.000000000 +0200
@@ -49,7 +49,7 @@
 		return 0;
 	
 	if ((*block_nr < fs->super->s_first_data_block) ||
-	    (*block_nr >= fs->super->s_blocks_count))
+	    (*block_nr >= EXT2_BLOCKS_COUNT(fs->super)))
 		return 0;	/* Ignore illegal blocks */
 
 	rb->err = ext2fs_badblocks_list_add(rb->bb_list, *block_nr);
Index: e2fsprogs/lib/ext2fs/alloc_tables.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/alloc_tables.c	2006-05-24 15:30:05.000000000 +0200
+++ e2fsprogs/lib/ext2fs/alloc_tables.c	2006-05-24 15:30:29.000000000 +0200
@@ -34,12 +34,11 @@
 	blk_t		group_blk, start_blk, last_blk, new_blk, blk;
 	int		j;
 
-	group_blk = fs->super->s_first_data_block +
-		(group * fs->super->s_blocks_per_group);
+	group_blk = EXT2_GROUP_BASE(fs->super, group);
 	
 	last_blk = group_blk + fs->super->s_blocks_per_group;
-	if (last_blk >= fs->super->s_blocks_count)
-		last_blk = fs->super->s_blocks_count - 1;
+	if (last_blk >= EXT2_BLOCKS_COUNT(fs->super))
+		last_blk = EXT2_BLOCKS_COUNT(fs->super) - 1;
 
 	if (!bmap)
 		bmap = fs->block_map;
@@ -60,7 +59,7 @@
 	} else
 		start_blk = group_blk;
 
-	if (!fs->group_desc[group].bg_block_bitmap) {
+	if (!EXT2_IS_USED_BLOCK_BITMAP(&fs->group_desc[group])) {
 		retval = ext2fs_get_free_blocks(fs, start_blk, last_blk,
 						1, bmap, &new_blk);
 		if (retval == EXT2_ET_BLOCK_ALLOC_FAIL) 
@@ -69,10 +68,10 @@
 		if (retval)
 			return retval;
 		ext2fs_mark_block_bitmap(bmap, new_blk);
-		fs->group_desc[group].bg_block_bitmap = new_blk;
+		EXT2_BLOCK_BITMAP_SET(&fs->group_desc[group], group_blk, new_blk);
 	}
 
-	if (!fs->group_desc[group].bg_inode_bitmap) {
+	if (!EXT2_IS_USED_INODE_BITMAP(&fs->group_desc[group])) {
 		retval = ext2fs_get_free_blocks(fs, start_blk, last_blk,
 						1, bmap, &new_blk);
 		if (retval == EXT2_ET_BLOCK_ALLOC_FAIL) 
@@ -81,13 +80,13 @@
 		if (retval)
 			return retval;
 		ext2fs_mark_block_bitmap(bmap, new_blk);
-		fs->group_desc[group].bg_inode_bitmap = new_blk;
+		EXT2_INODE_BITMAP_SET(&fs->group_desc[group], group_blk, new_blk);
 	}
 
 	/*
 	 * Allocate the inode table
 	 */
-	if (!fs->group_desc[group].bg_inode_table) {
+	if (!EXT2_IS_USED_INODE_TABLE(&fs->group_desc[group])) {
 		retval = ext2fs_get_free_blocks(fs, group_blk, last_blk,
 						fs->inode_blocks_per_group,
 						bmap, &new_blk);
@@ -97,7 +96,7 @@
 		     j < fs->inode_blocks_per_group;
 		     j++, blk++)
 			ext2fs_mark_block_bitmap(bmap, blk);
-		fs->group_desc[group].bg_inode_table = new_blk;
+		EXT2_INODE_TABLE_SET(&fs->group_desc[group], group_blk, new_blk);
 	}
 
 	
Index: e2fsprogs/e2fsck/pass1.c
===================================================================
--- e2fsprogs.orig/e2fsck/pass1.c	2006-05-24 15:30:20.000000000 +0200
+++ e2fsprogs/e2fsck/pass1.c	2006-05-24 15:30:29.000000000 +0200
@@ -179,7 +179,7 @@
 		if ((inode->i_size >= fs->blocksize) ||
 		    (blocks != fs->blocksize >> 9) ||
 		    (inode->i_block[0] < fs->super->s_first_data_block) ||
-		    (inode->i_block[0] >= fs->super->s_blocks_count))
+		    (inode->i_block[0] >= EXT2_BLOCKS_COUNT(fs->super)))
 			return 0;
 
 		for (i = 1; i < EXT2_N_BLOCKS; i++)
@@ -1175,7 +1175,7 @@
 	 */
 	if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) ||
 	    (blk < fs->super->s_first_data_block) ||
-	    (blk >= fs->super->s_blocks_count)) {
+	    (blk >= EXT2_BLOCKS_COUNT(fs->super))) {
 		mark_inode_bad(ctx, ino);
 		return 0;
 	}
@@ -1329,7 +1329,7 @@
 	blk = inode->i_block[0];
 	if (((blk == 0) ||
 	     (blk < fs->super->s_first_data_block) ||
-	     (blk >= fs->super->s_blocks_count)) &&
+	     (blk >= EXT2_BLOCKS_COUNT(fs->super))) &&
 	    fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
 		return 1;
 
@@ -1536,8 +1536,8 @@
 	if (block < super) {
 		sprintf(problem, "< FIRSTBLOCK (%u)", super);
 		return(problem);
-	} else if (block >= fs->super->s_blocks_count) {
-		sprintf(problem, "> BLOCKS (%lu)", fs->super->s_blocks_count);
+	} else if (block >= EXT2_BLOCKS_COUNT(fs->super)) {
+		sprintf(problem, "> BLOCKS (%llu)", EXT2_BLOCKS_COUNT(fs->super));
 		return(problem);
 	}
 	for (i = 0; i < fs->group_desc_count; i++) {
@@ -1551,16 +1551,16 @@
 				"of group %d", i);
 			break;
 		}
-		if (block == fs->group_desc[i].bg_block_bitmap) {
+		if (block == EXT2_BLOCK_BITMAP(&fs->group_desc[i], super)) {
 			sprintf(problem, "is the block bitmap of group %d", i);
 			break;
 		}
-		if (block == fs->group_desc[i].bg_inode_bitmap) {
+		if (block == EXT2_INODE_BITMAP(&fs->group_desc[i], super)) {
 			sprintf(problem, "is the inode bitmap of group %d", i);
 			break;
 		}
-		if (block >= fs->group_desc[i].bg_inode_table &&
-		    (block < fs->group_desc[i].bg_inode_table
+		if (block >= EXT2_INODE_TABLE(&fs->group_desc[i], super) &&
+		    (block < EXT2_INODE_TABLE(&fs->group_desc[i], super)
 		     + fs->inode_blocks_per_group)) {
 			sprintf(problem, "is in the inode table of group %d",
 				i);
@@ -1664,7 +1664,7 @@
 		problem = PR_1_TOOBIG_SYMLINK;
 	    
 	if (blk < fs->super->s_first_data_block ||
-	    blk >= fs->super->s_blocks_count)
+	    blk >= EXT2_BLOCKS_COUNT(fs->super))
 		problem = PR_1_ILLEGAL_BLOCK_NUM;
 
 	if (problem) {
@@ -1752,7 +1752,7 @@
 	pctx->blkcount = blockcnt;
 
 	if ((blk < fs->super->s_first_data_block) ||
-	    (blk >= fs->super->s_blocks_count)) {
+	    (blk >= EXT2_BLOCKS_COUNT(fs->super))) {
 		if (fix_problem(ctx, PR_1_BB_ILLEGAL_BLOCK_NUM, pctx)) {
 			*block_nr = 0;
 			return BLOCK_CHANGED;
@@ -1833,22 +1833,22 @@
 			return 0;
 		}
 	skip_super:
-		if (blk == fs->group_desc[i].bg_block_bitmap) {
+		if (blk == EXT2_BLOCK_BITMAP(&fs->group_desc[i], first_block)) {
 			if (fix_problem(ctx, PR_1_BB_BAD_BLOCK, pctx)) {
 				ctx->invalid_block_bitmap_flag[i]++;
 				ctx->invalid_bitmaps++;
 			}
 			return 0;
 		}
-		if (blk == fs->group_desc[i].bg_inode_bitmap) {
+		if (blk == EXT2_INODE_BITMAP(&fs->group_desc[i], first_block)) {
 			if (fix_problem(ctx, PR_1_IB_BAD_BLOCK, pctx)) {
 				ctx->invalid_inode_bitmap_flag[i]++;
 				ctx->invalid_bitmaps++;
 			}
 			return 0;
 		}
-		if ((blk >= fs->group_desc[i].bg_inode_table) &&
-		    (blk < (fs->group_desc[i].bg_inode_table +
+		if ((blk >= EXT2_INODE_TABLE(&fs->group_desc[i], first_block)) &&
+		    (blk < (EXT2_INODE_TABLE(&fs->group_desc[i], first_block) +
 			    fs->inode_blocks_per_group))) {
 			/*
 			 * If there are bad blocks in the inode table,
@@ -1885,7 +1885,7 @@
 	return 0;
 }
 
-static void new_table_block(e2fsck_t ctx, blk_t first_block, int group, 
+static void new_table_block(e2fsck_t ctx, blk_t first_block, int group,
 			    const char *name, int num, blk_t *new_block)
 {
 	ext2_filsys fs = ctx->fs;
@@ -1959,20 +1959,20 @@
 			blk_t blk;
 			new_table_block(ctx, first_block, i, _("block bitmap"),
 					1, &blk);
-			fs->group_desc[i].bg_block_bitmap = blk;
+			EXT2_BLOCK_BITMAP_SET(&fs->group_desc[i], first_block, blk);
 		}
 		if (ctx->invalid_inode_bitmap_flag[i]) {
 			blk_t blk;
 			new_table_block(ctx, first_block, i, _("inode bitmap"),
 					1, &blk);
-			fs->group_desc[i].bg_inode_bitmap = blk;
+			EXT2_INODE_BITMAP_SET(&fs->group_desc[i], first_block, blk);
 		}
 		if (ctx->invalid_inode_table_flag[i]) {
 			blk_t blk;
 			new_table_block(ctx, first_block, i, _("inode table"),
 					fs->inode_blocks_per_group, 
 					&blk);
-			fs->group_desc[i].bg_inode_table = blk;
+			EXT2_INODE_TABLE_SET(&fs->group_desc[i], first_block, blk);
 			ctx->flags |= E2F_FLAG_RESTART;
 		}
 		first_block += fs->super->s_blocks_per_group;
@@ -2003,8 +2003,8 @@
 		/*
 		 * Mark the blocks used for the inode table
 		 */
-		if (fs->group_desc[i].bg_inode_table) {
-			for (j = 0, b = fs->group_desc[i].bg_inode_table;
+		if (EXT2_IS_USED_INODE_TABLE(&fs->group_desc[i])) {
+			for (j = 0, b = EXT2_INODE_TABLE(&fs->group_desc[i], block);
 			     j < fs->inode_blocks_per_group;
 			     j++, b++) {
 				if (ext2fs_test_block_bitmap(ctx->block_found_map,
@@ -2025,34 +2025,34 @@
 		/*
 		 * Mark block used for the block bitmap 
 		 */
-		if (fs->group_desc[i].bg_block_bitmap) {
+		if (EXT2_IS_USED_BLOCK_BITMAP(&fs->group_desc[i])) {
 			if (ext2fs_test_block_bitmap(ctx->block_found_map,
-				     fs->group_desc[i].bg_block_bitmap)) {
-				pctx.blk = fs->group_desc[i].bg_block_bitmap;
+				     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++;
 				}
 			} else {
 			    ext2fs_mark_block_bitmap(ctx->block_found_map,
-				     fs->group_desc[i].bg_block_bitmap);
+				      EXT2_BLOCK_BITMAP(&fs->group_desc[i], block));
 		    }
 			
 		}
 		/*
 		 * Mark block used for the inode bitmap 
 		 */
-		if (fs->group_desc[i].bg_inode_bitmap) {
+		if (EXT2_IS_USED_INODE_BITMAP(&fs->group_desc[i])) {
 			if (ext2fs_test_block_bitmap(ctx->block_found_map,
-				     fs->group_desc[i].bg_inode_bitmap)) {
-				pctx.blk = fs->group_desc[i].bg_inode_bitmap;
+				     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,
-				     fs->group_desc[i].bg_inode_bitmap);
+				     EXT2_INODE_BITMAP(&fs->group_desc[i], block));
 			}
 		}
 		block += fs->super->s_blocks_per_group;
Index: e2fsprogs/misc/findsuper.c
===================================================================
--- e2fsprogs.orig/misc/findsuper.c	2006-05-24 15:30:05.000000000 +0200
+++ e2fsprogs/misc/findsuper.c	2006-05-24 15:30:29.000000000 +0200
@@ -183,12 +183,12 @@
 			continue;
 		if (ext2.s_log_block_size > 4)
 			WHY("log block size > 4 (%u)\n", ext2.s_log_block_size);
-		if (ext2.s_r_blocks_count > ext2.s_blocks_count)
+		if (EXT2_R_BLOCKS_COUNT(&ext2) > EXT2_BLOCKS_COUNT(&ext2))
 			WHY("r_blocks_count > blocks_count (%u > %u)\n",
-			    ext2.s_r_blocks_count, ext2.s_blocks_count);
-		if (ext2.s_free_blocks_count > ext2.s_blocks_count)
+			    EXT2_R_BLOCKS_COUNT(&ext2), EXT2_BLOCKS_COUNT(&ext2));
+		if (EXT2_FREE_BLOCKS_COUNT(&ext2) > EXT2_BLOCKS_COUNT(&ext2))
 			WHY("free_blocks_count > blocks_count\n (%u > %u)\n",
-			    ext2.s_free_blocks_count, ext2.s_blocks_count);
+			    EXT2_FREE_BLOCKS_COUNT(&ext2), EXT2_BLOCKS_COUNT(&ext2));
 		if (ext2.s_free_inodes_count > ext2.s_inodes_count)
 			WHY("free_inodes_count > inodes_count (%u > %u)\n",
 			    ext2.s_free_inodes_count, ext2.s_inodes_count);
@@ -197,7 +197,7 @@
 		s=ctime(&tm);
 		s[24]=0;
 		printf("\r%14Ld %9Ld %9d %5d %4d %s\n",
-		       sk, sk >> 10, ext2.s_blocks_count,
+		       sk, sk >> 10, EXT2_BLOCKS_COUNT(&ext2),
 		       1 << (ext2.s_log_block_size + 10),
 		       ext2.s_block_group_nr, s);
 	}
Index: e2fsprogs/tests/progs/test_icount.c
===================================================================
--- e2fsprogs.orig/tests/progs/test_icount.c	2006-05-24 15:30:05.000000000 +0200
+++ e2fsprogs/tests/progs/test_icount.c	2006-05-24 15:30:29.000000000 +0200
@@ -307,7 +307,7 @@
 	 * Create a sample filesystem structure
 	 */
 	memset(&param, 0, sizeof(struct ext2_super_block));
-	param.s_blocks_count = 80000;
+	EXT2_BLOCKS_COUNT_SET(&param, 80000);
 	param.s_inodes_count = 20000;
 	retval = ext2fs_initialize("/dev/null", 0, &param,
 				   unix_io_manager, &test_fs);
Index: e2fsprogs/lib/ext2fs/block.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/block.c	2006-05-24 15:30:20.000000000 +0200
+++ e2fsprogs/lib/ext2fs/block.c	2006-05-24 15:30:29.000000000 +0200
@@ -53,7 +53,7 @@
 		ctx->bcount += limit;
 		return ret;
 	}
-	if (*ind_block >= ctx->fs->super->s_blocks_count ||
+	if (*ind_block >= EXT2_BLOCKS_COUNT(ctx->fs->super) ||
 	    *ind_block < ctx->fs->super->s_first_data_block) {
 		ctx->errcode = EXT2_ET_BAD_IND_BLOCK;
 		ret |= BLOCK_ERROR;
@@ -132,7 +132,7 @@
 		ctx->bcount += limit*limit;
 		return ret;
 	}
-	if (*dind_block >= ctx->fs->super->s_blocks_count ||
+	if (*dind_block >= EXT2_BLOCKS_COUNT(ctx->fs->super) ||
 	    *dind_block < ctx->fs->super->s_first_data_block) {
 		ctx->errcode = EXT2_ET_BAD_DIND_BLOCK;
 		ret |= BLOCK_ERROR;
@@ -214,7 +214,7 @@
 		ctx->bcount += limit*limit*limit;
 		return ret;
 	}
-	if (*tind_block >= ctx->fs->super->s_blocks_count ||
+	if (*tind_block >= EXT2_BLOCKS_COUNT(ctx->fs->super) ||
 	    *tind_block < ctx->fs->super->s_first_data_block) {
 		ctx->errcode = EXT2_ET_BAD_TIND_BLOCK;
 		ret |= BLOCK_ERROR;
Index: e2fsprogs/lib/ext2fs/closefs.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/closefs.c	2006-05-24 15:30:05.000000000 +0200
+++ e2fsprogs/lib/ext2fs/closefs.c	2006-05-24 15:30:29.000000000 +0200
@@ -57,8 +57,7 @@
 	int	numblocks, has_super;
 	int	old_desc_blocks;
 
-	group_block = fs->super->s_first_data_block +
-		(group * fs->super->s_blocks_per_group);
+	group_block = EXT2_GROUP_BASE(fs->super, group);
 
 	if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG)
 		old_desc_blocks = fs->super->s_first_meta_bg;
@@ -67,7 +66,7 @@
 			fs->desc_blocks + fs->super->s_reserved_gdt_blocks;
 
 	if (group == fs->group_desc_count-1) {
-		numblocks = (fs->super->s_blocks_count -
+		numblocks = (EXT2_BLOCKS_COUNT(fs->super) -
 			     fs->super->s_first_data_block) %
 			fs->super->s_blocks_per_group;
 		if (!numblocks)
Index: e2fsprogs/lib/ext2fs/read_bb_file.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/read_bb_file.c	2006-05-24 15:30:05.000000000 +0200
+++ e2fsprogs/lib/ext2fs/read_bb_file.c	2006-05-24 15:30:29.000000000 +0200
@@ -59,7 +59,7 @@
 			continue;
 		if (fs &&
 		    ((blockno < fs->super->s_first_data_block) ||
-		    (blockno >= fs->super->s_blocks_count))) {
+		    (blockno >= EXT2_BLOCKS_COUNT(fs->super)))) {
 			if (invalid)
 				(invalid)(fs, blockno, buf, priv_data);
 			continue;
Index: e2fsprogs/debugfs/unused.c
===================================================================
--- e2fsprogs.orig/debugfs/unused.c	2006-05-24 15:30:05.000000000 +0200
+++ e2fsprogs/debugfs/unused.c	2006-05-24 15:30:29.000000000 +0200
@@ -32,7 +32,7 @@
 	errcode_t	retval;
 
 	for (blk=current_fs->super->s_first_data_block;
-	     blk < current_fs->super->s_blocks_count; blk++) {
+	     blk < EXT2_BLOCKS_COUNT(current_fs->super); blk++) {
 		if (ext2fs_test_block_bitmap(current_fs->block_map,blk))
 			continue;
 		retval = io_channel_read_blk(current_fs->io, blk, 1, buf);
Index: e2fsprogs/lib/ext2fs/alloc_stats.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/alloc_stats.c	2006-05-24 15:30:05.000000000 +0200
+++ e2fsprogs/lib/ext2fs/alloc_stats.c	2006-05-24 15:30:29.000000000 +0200
@@ -46,7 +46,7 @@
 	else
 		ext2fs_unmark_block_bitmap(fs->block_map, blk);
 	fs->group_desc[group].bg_free_blocks_count -= inuse;
-	fs->super->s_free_blocks_count -= inuse;
+	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/ext2ed/init.c
===================================================================
--- e2fsprogs.orig/ext2ed/init.c	2006-05-24 15:30:05.000000000 +0200
+++ e2fsprogs/ext2ed/init.c	2006-05-24 15:30:29.000000000 +0200
@@ -415,13 +415,13 @@
 			file_system_info.first_group_desc_offset=2*EXT2_MIN_BLOCK_SIZE;
 		else
 			file_system_info.first_group_desc_offset=file_system_info.block_size;
-		file_system_info.groups_count=(	sb->s_blocks_count-sb->s_first_data_block+sb->s_blocks_per_group-1) /
+		file_system_info.groups_count=(	EXT2_BLOCKS_COUNT(sb)-sb->s_first_data_block+sb->s_blocks_per_group-1) /
 						sb->s_blocks_per_group;
 	
 		file_system_info.inodes_per_block=file_system_info.block_size/sizeof (struct ext2_inode);
 		file_system_info.blocks_per_group=sb->s_inodes_per_group/file_system_info.inodes_per_block;
 		file_system_info.no_blocks_in_group=sb->s_blocks_per_group;
-		file_system_info.file_system_size=(sb->s_blocks_count-1)*file_system_info.block_size;
+		file_system_info.file_system_size=(EXT2_BLOCKS_COUNT(sb)-1)*file_system_info.block_size;
 	}
 
 	else {
Index: e2fsprogs/lib/ext2fs/alloc.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/alloc.c	2006-05-24 15:30:05.000000000 +0200
+++ e2fsprogs/lib/ext2fs/alloc.c	2006-05-24 15:30:29.000000000 +0200
@@ -84,7 +84,7 @@
 		map = fs->block_map;
 	if (!map)
 		return EXT2_ET_NO_BLOCK_BITMAP;
-	if (!goal || (goal >= fs->super->s_blocks_count))
+	if (!goal || (goal >= EXT2_BLOCKS_COUNT(fs->super)))
 		goal = fs->super->s_first_data_block;
 	i = goal;
 	do {
@@ -93,7 +93,7 @@
 			return 0;
 		}
 		i++;
-		if (i >= fs->super->s_blocks_count)
+		if (i >= EXT2_BLOCKS_COUNT(fs->super))
 			i = fs->super->s_first_data_block;
 	} while (i != goal);
 	return EXT2_ET_BLOCK_ALLOC_FAIL;
@@ -160,7 +160,7 @@
 	if (!num)
 		num = 1;
 	do {
-		if (b+num-1 > fs->super->s_blocks_count)
+		if (b+num-1 > EXT2_BLOCKS_COUNT(fs->super))
 			b = fs->super->s_first_data_block;
 		if (ext2fs_fast_test_block_bitmap_range(map, b, num)) {
 			*ret = b;
Index: e2fsprogs/lib/ext2fs/tst_iscan.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/tst_iscan.c	2006-05-24 15:30:20.000000000 +0200
+++ e2fsprogs/lib/ext2fs/tst_iscan.c	2006-05-24 15:30:29.000000000 +0200
@@ -71,7 +71,7 @@
 	initialize_ext2_error_table();
 
 	memset(&param, 0, sizeof(param));
-	param.s_blocks_count = 12000;
+	EXT2_BLOCKS_COUNT_SET(&param, 12000);
 
 
 	test_io_cb_read_blk = test_read_blk;
@@ -182,7 +182,8 @@
 		ext2fs_mark_block_bitmap(touched_map, test_vec[i]);
 	}
 	for (i = 0; i < test_fs->group_desc_count; i++) {
-		for (j=0, blk = test_fs->group_desc[i].bg_inode_table;
+		for (j=0, blk = EXT2_INODE_TABLE(&test_fs->group_desc[i],
+					EXT2_GROUP_BASE(test_fs->super, i));
 		     j < test_fs->inode_blocks_per_group;
 		     j++, blk++) {
 			if (!ext2fs_test_block_bitmap(touched_map, blk) &&
Index: e2fsprogs/lib/ext2fs/inode.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/inode.c	2006-05-24 15:30:20.000000000 +0200
+++ e2fsprogs/lib/ext2fs/inode.c	2006-05-24 15:30:29.000000000 +0200
@@ -142,8 +142,8 @@
 	scan->current_group = 0;
 	scan->groups_left = fs->group_desc_count - 1;
 	scan->inode_buffer_blocks = buffer_blocks ? buffer_blocks : 8;
-	scan->current_block = scan->fs->
-		group_desc[scan->current_group].bg_inode_table;
+	scan->current_block = EXT2_INODE_TABLE(&scan->fs->group_desc[scan->current_group],
+				EXT2_GROUP_BASE(scan->fs->super, scan->current_group));
 	scan->inodes_left = EXT2_INODES_PER_GROUP(scan->fs->super);
 	scan->blocks_left = scan->fs->inode_blocks_per_group;
 	retval = ext2fs_get_mem((size_t) (scan->inode_buffer_blocks * 
@@ -221,8 +221,8 @@
 	scan->current_group++;
 	scan->groups_left--;
 			
-	scan->current_block = scan->fs->
-		group_desc[scan->current_group].bg_inode_table;
+	scan->current_block = EXT2_INODE_TABLE(&scan->fs->group_desc[scan->current_group],
+				EXT2_GROUP_BASE(scan->fs->super, scan->current_group));
 
 	scan->current_inode = scan->current_group *
 		EXT2_INODES_PER_GROUP(scan->fs->super);
@@ -547,9 +547,10 @@
 		offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) *
 			EXT2_INODE_SIZE(fs->super);
 		block = offset >> EXT2_BLOCK_SIZE_BITS(fs->super);
-		if (!fs->group_desc[(unsigned)group].bg_inode_table)
+		if (!EXT2_IS_USED_INODE_TABLE(&fs->group_desc[(unsigned)group]))
 			return EXT2_ET_MISSING_INODE_TABLE;
-		block_nr = fs->group_desc[(unsigned)group].bg_inode_table + 
+		block_nr = EXT2_INODE_TABLE(&fs->group_desc[(unsigned)group],
+			EXT2_GROUP_BASE(fs->super, group)) +
 			block;
 		io = fs->io;
 	}
@@ -671,9 +672,10 @@
 	offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) *
 		EXT2_INODE_SIZE(fs->super);
 	block = offset >> EXT2_BLOCK_SIZE_BITS(fs->super);
-	if (!fs->group_desc[(unsigned) group].bg_inode_table)
+	if (!EXT2_IS_USED_INODE_TABLE(&fs->group_desc[(unsigned) group]))
 		return EXT2_ET_MISSING_INODE_TABLE;
-	block_nr = fs->group_desc[(unsigned) group].bg_inode_table + block;
+	block_nr = EXT2_INODE_TABLE(&fs->group_desc[(unsigned) group], 
+			EXT2_GROUP_BASE(fs->super, group)) + block;
 
 	offset &= (EXT2_BLOCK_SIZE(fs->super) - 1);
 
Index: e2fsprogs/e2fsck/badblocks.c
===================================================================
--- e2fsprogs.orig/e2fsck/badblocks.c	2006-05-24 15:30:20.000000000 +0200
+++ e2fsprogs/e2fsck/badblocks.c	2006-05-24 15:30:29.000000000 +0200
@@ -19,7 +19,7 @@
 
 static void invalid_block(ext2_filsys fs EXT2FS_ATTR((unused)), blk_t blk)
 {
-	printf(_("Bad block %lu out of range; ignored.\n"), blk);
+	printf(_("Bad block %llu out of range; ignored.\n"), blk);
 	return;
 }
 
@@ -75,7 +75,7 @@
 		sprintf(buf, "badblocks -b %d -X %s%s%s %d", fs->blocksize,
 			(ctx->options & E2F_OPT_PREEN) ? "" : "-s ",
 			(ctx->options & E2F_OPT_WRITECHECK) ? "-n " : "",
-			fs->device_name, fs->super->s_blocks_count);
+			fs->device_name, EXT2_BLOCKS_COUNT(fs->super));
 		f = popen(buf, "r");
 		if (!f) {
 			com_err("read_bad_blocks_file", errno,
@@ -124,7 +124,7 @@
 	/*
 	 * If the block number is outrageous, clear it and ignore it.
 	 */
-	if (*block_nr >= fs->super->s_blocks_count ||
+	if (*block_nr >= EXT2_BLOCKS_COUNT(fs->super)||
 	    *block_nr < fs->super->s_first_data_block) {
 		printf(_("Warning: illegal block %u found in bad block inode.  "
 			 "Cleared.\n"), *block_nr);
Index: e2fsprogs/ext2ed/super_com.c
===================================================================
--- e2fsprogs.orig/ext2ed/super_com.c	2006-05-24 15:30:05.000000000 +0200
+++ e2fsprogs/ext2ed/super_com.c	2006-05-24 15:30:29.000000000 +0200
@@ -29,9 +29,9 @@
 	
 	show (command_line);
 
-	if (super->s_blocks_count != 0) {
-		wmove (show_pad,2,40);wprintw (show_pad,"%2.2f%%",100*(float) super->s_r_blocks_count/ (float) super->s_blocks_count);
-		wmove (show_pad,3,40);wprintw (show_pad,"%2.2f%%",100*(float) super->s_free_blocks_count/ (float) super->s_blocks_count);
+	if (EXT2_BLOCKS_COUNT(super) != 0) {
+		wmove (show_pad,2,40);wprintw (show_pad,"%2.2f%%",100*(float) EXT2_R_BLOCKS_COUNT(super) / (float) EXT2_BLOCKS_COUNT(super));
+		wmove (show_pad,3,40);wprintw (show_pad,"%2.2f%%",100*(float) EXT2_FREE_BLOCKS_COUNT(super)/ (float) EXT2_BLOCKS_COUNT(super));
 	}
 	
 	if (super->s_inodes_count != 0) {
Index: e2fsprogs/lib/ext2fs/imager.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/imager.c	2006-05-24 15:30:05.000000000 +0200
+++ e2fsprogs/lib/ext2fs/imager.c	2006-05-24 15:30:29.000000000 +0200
@@ -71,9 +71,10 @@
 		return ENOMEM;
 	
 	for (group = 0; group < fs->group_desc_count; group++) {
-		blk = fs->group_desc[(unsigned)group].bg_inode_table;
-		if (!blk)
+		if (!EXT2_IS_USED_INODE_TABLE(&fs->group_desc[(unsigned)group]))
 			return EXT2_ET_MISSING_INODE_TABLE;
+		blk = EXT2_INODE_TABLE(&fs->group_desc[(unsigned)group],
+				EXT2_GROUP_BASE(fs->super, group));
 		left = fs->inode_blocks_per_group;
 		while (left) {
 			c = BUF_BLOCKS;
@@ -143,11 +144,12 @@
 		return ENOMEM;
 	
 	for (group = 0; group < fs->group_desc_count; group++) {
-		blk = fs->group_desc[(unsigned)group].bg_inode_table;
-		if (!blk) {
+		if (!EXT2_IS_USED_INODE_TABLE(&fs->group_desc[(unsigned)group])) {
 			retval = EXT2_ET_MISSING_INODE_TABLE;
 			goto errout;
 		}
+		blk = EXT2_INODE_TABLE(&fs->group_desc[(unsigned)group],
+				EXT2_GROUP_BASE(fs->super, group));
 		left = fs->inode_blocks_per_group;
 		while (left) {
 			c = BUF_BLOCKS;
Index: e2fsprogs/e2fsck/pass2.c
===================================================================
--- e2fsprogs.orig/e2fsck/pass2.c	2006-05-24 15:30:05.000000000 +0200
+++ e2fsprogs/e2fsck/pass2.c	2006-05-24 15:30:29.000000000 +0200
@@ -1077,7 +1077,7 @@
 	if (HOLE_BLKADDR(*block_nr))
 		return 0;
 	if ((*block_nr < fs->super->s_first_data_block) ||
-	    (*block_nr >= fs->super->s_blocks_count))
+	    (*block_nr >= EXT2_BLOCKS_COUNT(fs->super)))
 		return 0;
 	ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
 	ext2fs_block_alloc_stats(fs, *block_nr, -1);
@@ -1286,7 +1286,7 @@
 
 	if (inode.i_file_acl &&
 	    ((inode.i_file_acl < fs->super->s_first_data_block) ||
-	     (inode.i_file_acl >= fs->super->s_blocks_count))) {
+	     (inode.i_file_acl >= EXT2_BLOCKS_COUNT(fs->super)))) {
 		if (fix_problem(ctx, PR_2_FILE_ACL_BAD, &pctx)) {
 			inode.i_file_acl = 0;
 			inode_modified++;
Index: e2fsprogs/lib/ext2fs/check_desc.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/check_desc.c	2006-05-24 15:30:05.000000000 +0200
+++ e2fsprogs/lib/ext2fs/check_desc.c	2006-05-24 15:30:29.000000000 +0200
@@ -43,22 +43,22 @@
 		 * Check to make sure block bitmap for group is
 		 * located within the group.
 		 */
-		if (fs->group_desc[i].bg_block_bitmap < block ||
-		    fs->group_desc[i].bg_block_bitmap >= next)
+		if (EXT2_BLOCK_BITMAP(&fs->group_desc[i], block) < block ||
+		    EXT2_BLOCK_BITMAP(&fs->group_desc[i], block) >= next)
 			return EXT2_ET_GDESC_BAD_BLOCK_MAP;
 		/*
 		 * Check to make sure inode bitmap for group is
 		 * located within the group
 		 */
-		if (fs->group_desc[i].bg_inode_bitmap < block ||
-		    fs->group_desc[i].bg_inode_bitmap >= next)
+		if (EXT2_INODE_BITMAP(&fs->group_desc[i], block) < block ||
+		    EXT2_INODE_BITMAP(&fs->group_desc[i], block) >= next)
 			return EXT2_ET_GDESC_BAD_INODE_MAP;
 		/*
 		 * Check to make sure inode table for group is located
 		 * within the group
 		 */
-		if (fs->group_desc[i].bg_inode_table < block ||
-		    ((fs->group_desc[i].bg_inode_table +
+		if (EXT2_INODE_TABLE(&fs->group_desc[i], block) < block ||
+		    ((EXT2_INODE_TABLE(&fs->group_desc[i], block) +
 		      fs->inode_blocks_per_group) >= next))
 			return EXT2_ET_GDESC_BAD_INODE_TABLE;
 		
Index: e2fsprogs/lib/ext2fs/bmove.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/bmove.c	2006-05-24 15:30:05.000000000 +0200
+++ e2fsprogs/lib/ext2fs/bmove.c	2006-05-24 15:30:29.000000000 +0200
@@ -50,7 +50,7 @@
 	 */
 	if (ext2fs_test_block_bitmap(pb->reserve, block)) {
 		do {
-			if (++block >= fs->super->s_blocks_count)
+			if (++block >= EXT2_BLOCKS_COUNT(fs->super))
 				block = fs->super->s_first_data_block;
 			if (block == orig) {
 				pb->error = EXT2_ET_BLOCK_ALLOC_FAIL;
Index: e2fsprogs/misc/util.c
===================================================================
--- e2fsprogs.orig/misc/util.c	2006-05-24 15:30:05.000000000 +0200
+++ e2fsprogs/misc/util.c	2006-05-24 15:30:29.000000000 +0200
@@ -251,7 +251,7 @@
 {
 	blk_t j_blocks;
 
-	if (fs->super->s_blocks_count < 2048) {
+	if (EXT2_BLOCKS_COUNT(fs->super) < 2048) {
 		fputs(_("\nFilesystem too small for a journal\n"), stderr);
 		return 0;
 	}
@@ -266,7 +266,7 @@
 				j_blocks);
 			exit(1);
 		}
-		if (j_blocks > fs->super->s_free_blocks_count) {
+		if (j_blocks > EXT2_FREE_BLOCKS_COUNT(fs->super)) {
 			fputs(_("\nJournal size too big for filesystem.\n"),
 			      stderr);
 			exit(1);
@@ -274,13 +274,13 @@
 		return j_blocks;
 	}
 
-	if (fs->super->s_blocks_count < 32768)
+	if (EXT2_BLOCKS_COUNT(fs->super) < 32768)
 		j_blocks = 1024;
-	else if (fs->super->s_blocks_count < 256*1024)
+	else if (EXT2_BLOCKS_COUNT(fs->super) < 256*1024)
 		j_blocks = 4096;
-	else if (fs->super->s_blocks_count < 512*1024)
+	else if (EXT2_BLOCKS_COUNT(fs->super) < 512*1024)
 		j_blocks = 8192;
-	else if (fs->super->s_blocks_count < 1024*1024)
+	else if (EXT2_BLOCKS_COUNT(fs->super) < 1024*1024)
 		j_blocks = 16384;
 	else
 		j_blocks = 32768;
Index: e2fsprogs/misc/tune2fs.c
===================================================================
--- e2fsprogs.orig/misc/tune2fs.c	2006-05-24 15:30:20.000000000 +0200
+++ e2fsprogs/misc/tune2fs.c	2006-05-24 15:30:29.000000000 +0200
@@ -214,7 +214,7 @@
 	ext2fs_unmark_block_bitmap(fs->block_map,block);
 	group = ext2fs_group_of_blk(fs, block);
 	fs->group_desc[group].bg_free_blocks_count++;
-	fs->super->s_free_blocks_count++;
+	EXT2_FREE_BLOCKS_COUNT_SET(fs->super, EXT2_FREE_BLOCKS_COUNT(fs->super) + 1);
 	return 0;
 }
 
@@ -824,19 +824,19 @@
 		printf (_("Setting interval between checks to %lu seconds\n"), interval);
 	}
 	if (m_flag) {
-		sb->s_r_blocks_count = sb->s_blocks_count * reserved_ratio /100;
+		EXT2_R_BLOCKS_COUNT_SET(sb, EXT2_BLOCKS_COUNT(sb) * reserved_ratio / 100);
 		ext2fs_mark_super_dirty(fs);
-		printf (_("Setting reserved blocks percentage to %g%% (%lu blocks)\n"),
-			reserved_ratio, sb->s_r_blocks_count);
+		printf (_("Setting reserved blocks percentage to %g%% (%llu blocks)\n"),
+			reserved_ratio, EXT2_R_BLOCKS_COUNT(sb));
 	}
 	if (r_flag) {
-		if (reserved_blocks >= sb->s_blocks_count/2) {
+		if (reserved_blocks >= EXT2_BLOCKS_COUNT(sb)/2) {
 			com_err (program_name, 0,
 				 _("reserved blocks count is too big (%lu)"),
 				 reserved_blocks);
 			exit (1);
 		}
-		sb->s_r_blocks_count = reserved_blocks;
+		EXT2_R_BLOCKS_COUNT_SET(sb, reserved_blocks);
 		ext2fs_mark_super_dirty(fs);
 		printf (_("Setting reserved blocks count to %lu\n"),
 			reserved_blocks);
Index: e2fsprogs/misc/e2image.c
===================================================================
--- e2fsprogs.orig/misc/e2image.c	2006-05-24 15:30:20.000000000 +0200
+++ e2fsprogs/misc/e2image.c	2006-05-24 15:30:29.000000000 +0200
@@ -266,8 +266,8 @@
 		/*
 		 * Mark the blocks used for the inode table
 		 */
-		if (fs->group_desc[i].bg_inode_table) {
-			for (j = 0, b = fs->group_desc[i].bg_inode_table;
+		if (EXT2_IS_USED_INODE_TABLE(&fs->group_desc[i])) {
+			for (j = 0, b = EXT2_INODE_TABLE(&fs->group_desc[i], block);
 			     j < (unsigned) fs->inode_blocks_per_group;
 			     j++, b++)
 				ext2fs_mark_block_bitmap(meta_block_map, b);
@@ -276,17 +276,17 @@
 		/*
 		 * Mark block used for the block bitmap 
 		 */
-		if (fs->group_desc[i].bg_block_bitmap) {
+		if (EXT2_IS_USED_BLOCK_BITMAP(&fs->group_desc[i])) {
 			ext2fs_mark_block_bitmap(meta_block_map,
-				     fs->group_desc[i].bg_block_bitmap);
+				     EXT2_BLOCK_BITMAP(&fs->group_desc[i], block));
 		}
 		
 		/*
 		 * Mark block used for the inode bitmap 
 		 */
-		if (fs->group_desc[i].bg_inode_bitmap) {
+		if (EXT2_IS_USED_INODE_BITMAP(&fs->group_desc[i])) {
 			ext2fs_mark_block_bitmap(meta_block_map,
-				 fs->group_desc[i].bg_inode_bitmap);
+				 EXT2_INODE_BITMAP(&fs->group_desc[i], block));
 		}
 		block += fs->super->s_blocks_per_group;
 	}
@@ -413,7 +413,7 @@
 		exit(1);
 	}
 	memset(zero_buf, 0, fs->blocksize);
-	for (blk = 0; blk < fs->super->s_blocks_count; blk++) {
+	for (blk = 0; blk < EXT2_BLOCKS_COUNT(fs->super); blk++) {
 		if ((blk >= fs->super->s_first_data_block) &&
 		    ext2fs_test_block_bitmap(meta_block_map, blk)) {
 			retval = io_channel_read_blk(fs->io, blk, 1, buf);
Index: e2fsprogs/lib/ext2fs/bitmaps.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/bitmaps.c	2006-05-24 15:30:20.000000000 +0200
+++ e2fsprogs/lib/ext2fs/bitmaps.c	2006-05-24 15:30:29.000000000 +0200
@@ -150,7 +150,7 @@
 	fs->write_bitmaps = ext2fs_write_bitmaps;
 
 	start = fs->super->s_first_data_block;
-	end = fs->super->s_blocks_count-1;
+	end = EXT2_BLOCKS_COUNT(fs->super)-1;
 	real_end = (EXT2_BLOCKS_PER_GROUP(fs->super)  
 		    * fs->group_desc_count)-1 + start;
 	
Index: e2fsprogs/lib/e2p/ls.c
===================================================================
--- e2fsprogs.orig/lib/e2p/ls.c	2006-05-24 15:30:20.000000000 +0200
+++ e2fsprogs/lib/e2p/ls.c	2006-05-24 15:30:29.000000000 +0200
@@ -192,9 +192,9 @@
 	fprintf(f, "Filesystem OS type:       %s\n", str);
 	free(str);
 	fprintf(f, "Inode count:              %u\n", sb->s_inodes_count);
-	fprintf(f, "Block count:              %lu\n", sb->s_blocks_count);
-	fprintf(f, "Reserved block count:     %lu\n", sb->s_r_blocks_count);
-	fprintf(f, "Free blocks:              %lu\n", sb->s_free_blocks_count);
+	fprintf(f, "Block count:              %llu\n", EXT2_BLOCKS_COUNT(sb));
+	fprintf(f, "Reserved block count:     %llu\n", EXT2_R_BLOCKS_COUNT(sb));
+	fprintf(f, "Free blocks:              %llu\n", EXT2_FREE_BLOCKS_COUNT(sb));
 	fprintf(f, "Free inodes:              %u\n", sb->s_free_inodes_count);
 	fprintf(f, "First block:              %u\n", sb->s_first_data_block);
 	fprintf(f, "Block size:               %u\n", EXT2_BLOCK_SIZE(sb));
Index: e2fsprogs/e2fsck/super.c
===================================================================
--- e2fsprogs.orig/e2fsck/super.c	2006-05-24 15:30:20.000000000 +0200
+++ e2fsprogs/e2fsck/super.c	2006-05-24 15:30:29.000000000 +0200
@@ -90,7 +90,7 @@
 		return 0;
 
 	if ((blk < fs->super->s_first_data_block) ||
-	    (blk >= fs->super->s_blocks_count)) {
+	    (blk >= EXT2_BLOCKS_COUNT(fs->super))) {
 		fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, pctx);
 	return_abort:
 		pb->abort = 1;
@@ -387,7 +387,7 @@
 	if ((i < EXT2_N_BLOCKS) || !blk || !inode.i_links_count ||
 	    !(inode.i_mode & LINUX_S_IFREG) ||
 	    (blk < fs->super->s_first_data_block ||
-	     blk >= fs->super->s_blocks_count)) {
+	     blk >= EXT2_BLOCKS_COUNT(fs->super))) {
 	resize_inode_invalid:
 		if (fix_problem(ctx, PR_0_RESIZE_INODE_INVALID, &pctx)) {
 			memset(&inode, 0, sizeof(inode));
@@ -474,10 +474,10 @@
 	 */
 	check_super_value(ctx, "inodes_count", sb->s_inodes_count,
 			  MIN_CHECK, 1, 0);
-	check_super_value(ctx, "blocks_count", sb->s_blocks_count,
+	check_super_value(ctx, "blocks_count", EXT2_BLOCKS_COUNT(sb),
 			  MIN_CHECK, 1, 0);
 	check_super_value(ctx, "first_data_block", sb->s_first_data_block,
-			  MAX_CHECK, 0, sb->s_blocks_count);
+			  MAX_CHECK, 0, EXT2_BLOCKS_COUNT(sb));
 	check_super_value(ctx, "log_block_size", sb->s_log_block_size,
 			  MIN_CHECK | MAX_CHECK, 0,
 			  EXT2_MAX_BLOCK_LOG_SIZE - EXT2_MIN_BLOCK_LOG_SIZE);
@@ -490,8 +490,8 @@
 			  MIN_CHECK | MAX_CHECK, 8, bpg_max);
 	check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group,
 			  MIN_CHECK | MAX_CHECK, inodes_per_block, ipg_max);
-	check_super_value(ctx, "r_blocks_count", sb->s_r_blocks_count,
-			  MAX_CHECK, 0, sb->s_blocks_count / 2);
+	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", 
 			  sb->s_reserved_gdt_blocks, MAX_CHECK, 0,
 			  fs->blocksize/4);
@@ -515,8 +515,8 @@
 			return;
 		}
 		if ((pctx.errcode != EXT2_ET_UNIMPLEMENTED) &&
-		    (ctx->num_blocks < sb->s_blocks_count)) {
-			pctx.blk = sb->s_blocks_count;
+		    (ctx->num_blocks < EXT2_BLOCKS_COUNT(sb))) {
+			pctx.blk = EXT2_BLOCKS_COUNT(sb);
 			pctx.blk2 = ctx->num_blocks;
 			if (fix_problem(ctx, PR_0_FS_SIZE_WRONG, &pctx)) {
 				ctx->flags |= E2F_FLAG_ABORT;
@@ -572,35 +572,35 @@
 		pctx.group = i;
 		
 		if (i == fs->group_desc_count - 1)
-			last_block = sb->s_blocks_count;
-		if ((gd->bg_block_bitmap < first_block) ||
-		    (gd->bg_block_bitmap >= last_block)) {
-			pctx.blk = gd->bg_block_bitmap;
+			last_block = EXT2_BLOCKS_COUNT(sb);
+		if ((EXT2_BLOCK_BITMAP(gd, first_block) < first_block) ||
+		    (EXT2_BLOCK_BITMAP(gd, first_block) >= last_block)) {
+			pctx.blk = EXT2_BLOCK_BITMAP(gd, first_block);
 			if (fix_problem(ctx, PR_0_BB_NOT_GROUP, &pctx))
-				gd->bg_block_bitmap = 0;
+				EXT2_BLOCK_BITMAP_SET(gd, 0, 0);
 		}
-		if (gd->bg_block_bitmap == 0) {
+		if (!EXT2_IS_USED_BLOCK_BITMAP(gd)) {
 			ctx->invalid_block_bitmap_flag[i]++;
 			ctx->invalid_bitmaps++;
 		}
-		if ((gd->bg_inode_bitmap < first_block) ||
-		    (gd->bg_inode_bitmap >= last_block)) {
-			pctx.blk = gd->bg_inode_bitmap;
+		if ((EXT2_INODE_BITMAP(gd, first_block) < first_block) ||
+		    (EXT2_INODE_BITMAP(gd, first_block)>= last_block)) {
+			pctx.blk = EXT2_INODE_BITMAP(gd, first_block);
 			if (fix_problem(ctx, PR_0_IB_NOT_GROUP, &pctx))
-				gd->bg_inode_bitmap = 0;
+				EXT2_INODE_BITMAP_SET(gd, 0, 0);
 		}
-		if (gd->bg_inode_bitmap == 0) {
+		if (!EXT2_IS_USED_INODE_BITMAP(gd)) {
 			ctx->invalid_inode_bitmap_flag[i]++;
 			ctx->invalid_bitmaps++;
 		}
-		if ((gd->bg_inode_table < first_block) ||
-		    ((gd->bg_inode_table +
+		if ((EXT2_INODE_TABLE(gd, first_block) < first_block) ||
+		    ((EXT2_INODE_TABLE(gd, first_block) +
 		      fs->inode_blocks_per_group - 1) >= last_block)) {
-			pctx.blk = gd->bg_inode_table;
+			pctx.blk = EXT2_INODE_TABLE(gd, first_block);
 			if (fix_problem(ctx, PR_0_ITABLE_NOT_GROUP, &pctx))
-				gd->bg_inode_table = 0;
+				EXT2_INODE_TABLE_SET(gd, 0, 0);
 		}
-		if (gd->bg_inode_table == 0) {
+		if (!EXT2_IS_USED_INODE_TABLE(gd)) {
 			ctx->invalid_inode_table_flag[i]++;
 			ctx->invalid_bitmaps++;
 		}
@@ -623,18 +623,18 @@
 	 * inodes; if the filesystem is not unmounted cleanly, the
 	 * global counts may not be accurate.
 	 */
-	if ((free_blocks != sb->s_free_blocks_count) ||
+	if ((free_blocks != EXT2_FREE_BLOCKS_COUNT(sb)) ||
 	    (free_inodes != sb->s_free_inodes_count)) {
 		if (ctx->options & E2F_OPT_READONLY)
 			ext2fs_unmark_valid(fs);
 		else {
-			sb->s_free_blocks_count = free_blocks;
+			EXT2_FREE_BLOCKS_COUNT_SET(sb, free_blocks);
 			sb->s_free_inodes_count = free_inodes;
 			ext2fs_mark_super_dirty(fs);
 		}
 	}
 	
-	if ((sb->s_free_blocks_count > sb->s_blocks_count) ||
+	if ((EXT2_FREE_BLOCKS_COUNT(sb) > EXT2_BLOCKS_COUNT(sb)) ||
 	    (sb->s_free_inodes_count > sb->s_inodes_count))
 		ext2fs_unmark_valid(fs);
 
Index: e2fsprogs/e2fsck/pass5.c
===================================================================
--- e2fsprogs.orig/e2fsck/pass5.c	2006-05-24 15:30:20.000000000 +0200
+++ e2fsprogs/e2fsck/pass5.c	2006-05-24 15:30:29.000000000 +0200
@@ -130,11 +130,11 @@
 
 	if ((fs->super->s_first_data_block <
 	     ext2fs_get_block_bitmap_start(ctx->block_found_map)) ||
-	    (fs->super->s_blocks_count-1 >
+	    (EXT2_BLOCKS_COUNT(fs->super)-1 >
 	     ext2fs_get_block_bitmap_end(ctx->block_found_map))) {
 		pctx.num = 1;
 		pctx.blk = fs->super->s_first_data_block;
-		pctx.blk2 = fs->super->s_blocks_count -1;
+		pctx.blk2 = EXT2_BLOCKS_COUNT(fs->super) -1;
 		pctx.ino = ext2fs_get_block_bitmap_start(ctx->block_found_map);
 		pctx.ino2 = ext2fs_get_block_bitmap_end(ctx->block_found_map);
 		fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
@@ -145,11 +145,11 @@
 		       
 	if ((fs->super->s_first_data_block <
 	     ext2fs_get_block_bitmap_start(fs->block_map)) ||
-	    (fs->super->s_blocks_count-1 >
+	    (EXT2_BLOCKS_COUNT(fs->super)-1 >
 	     ext2fs_get_block_bitmap_end(fs->block_map))) {
 		pctx.num = 2;
 		pctx.blk = fs->super->s_first_data_block;
-		pctx.blk2 = fs->super->s_blocks_count -1;
+		pctx.blk2 = EXT2_BLOCKS_COUNT(fs->super) -1;
 		pctx.ino = ext2fs_get_block_bitmap_start(fs->block_map);
 		pctx.ino2 = ext2fs_get_block_bitmap_end(fs->block_map);
 		fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
@@ -171,7 +171,7 @@
 		skip_group++;
 	super = fs->super->s_first_data_block;
 	for (i = fs->super->s_first_data_block;
-	     i < fs->super->s_blocks_count;
+	     i < EXT2_BLOCKS_COUNT(fs->super);
 	     i++) {
 		actual = ext2fs_fast_test_block_bitmap(ctx->block_found_map, i);
 
@@ -180,12 +180,12 @@
 			    (i <= super + fs->desc_blocks) &&
 			    ext2fs_bg_has_super(fs, group))
 				bitmap = 1;
-			else if (i == fs->group_desc[group].bg_block_bitmap)
+			else if (i == EXT2_BLOCK_BITMAP(&fs->group_desc[group], i))
 				bitmap = 1;
-			else if (i == fs->group_desc[group].bg_inode_bitmap)
+			else if (i == EXT2_INODE_BITMAP(&fs->group_desc[group], i))
 				bitmap = 1;
-			else if (i >= fs->group_desc[group].bg_inode_table &&
-				 (i < fs->group_desc[group].bg_inode_table
+			else if (i >= EXT2_INODE_TABLE(&fs->group_desc[group], i) &&
+				 (i < EXT2_INODE_TABLE(&fs->group_desc[group], i)
 				  + fs->inode_blocks_per_group))
 				bitmap = 1;
 			else
@@ -231,7 +231,7 @@
 		}
 		blocks ++;
 		if ((blocks == fs->super->s_blocks_per_group) ||
-		    (i == fs->super->s_blocks_count-1)) {
+		    (i == EXT2_BLOCKS_COUNT(fs->super)-1)) {
 			free_array[group] = group_free;
 			group ++;
 			blocks = 0;
@@ -243,7 +243,7 @@
 						    fs->group_desc_count*2))
 					return;
 			if (lazy_bg &&
-			    (i != fs->super->s_blocks_count-1) &&
+			    (i != EXT2_BLOCKS_COUNT(fs->super)-1) &&
 			    (fs->group_desc[group].bg_flags &
 			     EXT2_BG_BLOCK_UNINIT))
 				skip_group++;
@@ -292,13 +292,13 @@
 				ext2fs_unmark_valid(fs);
 		}
 	}
-	if (free_blocks != fs->super->s_free_blocks_count) {
+	if (free_blocks != EXT2_FREE_BLOCKS_COUNT(fs->super)) {
 		pctx.group = 0;
-		pctx.blk = fs->super->s_free_blocks_count;
+		pctx.blk = EXT2_FREE_BLOCKS_COUNT(fs->super);
 		pctx.blk2 = free_blocks;
 
 		if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) {
-			fs->super->s_free_blocks_count = free_blocks;
+			EXT2_FREE_BLOCKS_COUNT_SET(fs->super, free_blocks);
 			ext2fs_mark_super_dirty(fs);
 		} else
 			ext2fs_unmark_valid(fs);
Index: e2fsprogs/e2fsck/journal.c
===================================================================
--- e2fsprogs.orig/e2fsck/journal.c	2006-05-24 15:30:20.000000000 +0200
+++ e2fsprogs/e2fsck/journal.c	2006-05-24 15:30:29.000000000 +0200
@@ -276,7 +276,7 @@
 				continue;
 			}
 			if (blk < sb->s_first_data_block ||
-			    blk >= sb->s_blocks_count) {
+			    blk >= EXT2_BLOCKS_COUNT(sb)) {
 				retval = EXT2_ET_BAD_BLOCK_NUM;
 				goto try_backup_journal;
 			}
@@ -367,7 +367,7 @@
 			goto errout;
 		}
 		
-		journal->j_maxlen = jsuper.s_blocks_count;
+		journal->j_maxlen = EXT2_BLOCKS_COUNT(&jsuper);
 		start++;
 	}
 
Index: e2fsprogs/debugfs/logdump.c
===================================================================
--- e2fsprogs.orig/debugfs/logdump.c	2006-05-24 15:30:20.000000000 +0200
+++ e2fsprogs/debugfs/logdump.c	2006-05-24 15:30:29.000000000 +0200
@@ -158,7 +158,8 @@
 				    / sizeof(struct ext2_inode));
 		
 		inode_block_to_dump = 
-			current_fs->group_desc[inode_group].bg_inode_table + 
+			EXT2_INODE_TABLE(&current_fs->group_desc[inode_group],
+					EXT2_GROUP_BASE(es, inode_group)) +
 			(group_offset / inodes_per_block);
 		inode_offset_to_dump = ((group_offset % inodes_per_block)
 					* sizeof(struct ext2_inode));
@@ -183,7 +184,8 @@
 		group_to_dump = ((block_to_dump - 
 				  es->s_first_data_block)
 				 / es->s_blocks_per_group);
-		bitmap_to_dump = current_fs->group_desc[group_to_dump].bg_block_bitmap;
+		bitmap_to_dump = EXT2_BLOCK_BITMAP(&current_fs->group_desc[group_to_dump],
+				 			EXT2_GROUP_BASE(es, group_to_dump));
 	}
 
 	if (!journal_fn && check_fs_open(argv[0]))
@@ -366,8 +368,8 @@
 		if (dump_all) {
 			fprintf(out_file, "\tuuid=%s\n", jsb_buffer);
 			fprintf(out_file, "\tblocksize=%d\n", blocksize);
-			fprintf(out_file, "\tjournal data size %lu\n",
-				(unsigned long) sb->s_blocks_count);
+			fprintf(out_file, "\tjournal data size %llu\n",
+				(unsigned long long) EXT2_BLOCKS_COUNT(sb));
 		}
 	}
 	
Index: e2fsprogs/e2fsck/unix.c
===================================================================
--- e2fsprogs.orig/e2fsck/unix.c	2006-05-24 15:30:20.000000000 +0200
+++ e2fsprogs/e2fsck/unix.c	2006-05-24 15:30:29.000000000 +0200
@@ -110,15 +110,15 @@
 	inodes = fs->super->s_inodes_count;
 	inodes_used = (fs->super->s_inodes_count -
 		       fs->super->s_free_inodes_count);
-	blocks = fs->super->s_blocks_count;
-	blocks_used = (fs->super->s_blocks_count -
-		       fs->super->s_free_blocks_count);
+	blocks = EXT2_BLOCKS_COUNT(fs->super);
+	blocks_used = (EXT2_BLOCKS_COUNT(fs->super) -
+		       EXT2_FREE_BLOCKS_COUNT(fs->super));
 
 	frag_percent = (10000 * ctx->fs_fragmented) / inodes_used;
 	frag_percent = (frag_percent + 5) / 10;
 	
 	if (!verbose) {
-		printf(_("%s: %d/%d files (%0d.%d%% non-contiguous), %lu/%lu blocks\n"),
+		printf(_("%s: %d/%d files (%0d.%d%% non-contiguous), %llu/%llu blocks\n"),
 		       ctx->device_name, inodes_used, inodes,
 		       frag_percent / 10, frag_percent % 10,
 		       blocks_used, blocks);
@@ -132,7 +132,7 @@
 		ctx->fs_fragmented, frag_percent / 10, frag_percent % 10);
 	printf (_("         # of inodes with ind/dind/tind blocks: %d/%d/%d\n"),
 		ctx->fs_ind_count, ctx->fs_dind_count, ctx->fs_tind_count);
-	printf (P_("%8lu block used (%d%%)\n", "%8lu blocks used (%d%%)\n",
+	printf (P_("%8llu block used (%d%%)\n", "%8llu blocks used (%d%%)\n",
 		   blocks_used),
 		blocks_used, (int) ((long long) 100 * blocks_used / blocks));
 	printf (P_("%8d bad block\n", "%8d bad blocks\n",
@@ -300,11 +300,11 @@
 		fputs(_(", check forced.\n"), stdout);
 		return;
 	}
-	printf(_("%s: clean, %d/%d files, %lu/%lu blocks"), ctx->device_name,
+	printf(_("%s: clean, %d/%d files, %llu/%llu blocks"), ctx->device_name,
 	       fs->super->s_inodes_count - fs->super->s_free_inodes_count,
 	       fs->super->s_inodes_count,
-	       fs->super->s_blocks_count - fs->super->s_free_blocks_count,
-	       fs->super->s_blocks_count);
+	       EXT2_BLOCKS_COUNT(fs->super) - EXT2_FREE_BLOCKS_COUNT(fs->super),
+	       EXT2_BLOCKS_COUNT(fs->super));
 	next_check = 100000;
 	if (fs->super->s_max_mnt_count > 0) {
 		next_check = fs->super->s_max_mnt_count - fs->super->s_mnt_count;
Index: e2fsprogs/e2fsck/pass1b.c
===================================================================
--- e2fsprogs.orig/e2fsck/pass1b.c	2006-05-24 15:30:20.000000000 +0200
+++ e2fsprogs/e2fsck/pass1b.c	2006-05-24 15:30:29.000000000 +0200
@@ -802,15 +802,15 @@
 		}
 		
 		/* Check the inode table */
-		if ((fs->group_desc[i].bg_inode_table) &&
-		    (test_block >= fs->group_desc[i].bg_inode_table) &&
-		    (test_block < (fs->group_desc[i].bg_inode_table +
-				   fs->inode_blocks_per_group)))
+		if ((EXT2_INODE_TABLE(&fs->group_desc[i], block) &&
+		    (test_block >= EXT2_INODE_TABLE(&fs->group_desc[i], block)) &&
+		    (test_block < (EXT2_INODE_TABLE(&fs->group_desc[i], block) +
+				   fs->inode_blocks_per_group))))
 			return 1;
 
 		/* Check the bitmap blocks */
-		if ((test_block == fs->group_desc[i].bg_block_bitmap) ||
-		    (test_block == fs->group_desc[i].bg_inode_bitmap))
+		if ((test_block == EXT2_BLOCK_BITMAP(&fs->group_desc[i], block)) ||
+		    (test_block == EXT2_INODE_BITMAP(&fs->group_desc[i], block)))
 			return 1;
 		
 		block += fs->super->s_blocks_per_group;
Index: e2fsprogs/ext2ed/inode_com.c
===================================================================
--- e2fsprogs.orig/ext2ed/inode_com.c	2006-05-24 15:30:20.000000000 +0200
+++ e2fsprogs/ext2ed/inode_com.c	2006-05-24 15:30:29.000000000 +0200
@@ -41,10 +41,11 @@
 
 	group_num=inode_offset_to_group_num (device_offset);
 	group_offset=file_system_info.first_group_desc_offset+group_num*sizeof (struct ext2_group_desc);
-
 	low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset);
 
-	entry_num=(device_offset-desc.bg_inode_table*file_system_info.block_size)/sizeof (struct ext2_inode);
+	entry_num=(device_offset-EXT2_INODE_TABLE(&desc, group_offset)*
+		  file_system_info.block_size)/
+		  sizeof (struct ext2_inode);
 
 	first_entry=0;last_entry=file_system_info.super_block.s_inodes_per_group-1;
 	inode_num=0;
@@ -53,7 +54,7 @@
 		device_offset-=sizeof (struct ext2_inode)*mult;
 		entry_num-=mult;
 		
-		sprintf (buffer,"setoffset %lu",device_offset);dispatch (buffer);
+		sprintf (buffer,"setoffset %lld",device_offset);dispatch (buffer);
 		strcpy (buffer,"show");dispatch (buffer);
 	}
 
@@ -93,7 +94,9 @@
 
 	low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset);
 
-	entry_num=(device_offset-desc.bg_inode_table*file_system_info.block_size)/sizeof (struct ext2_inode);
+	entry_num=(device_offset-EXT2_INODE_TABLE(&desc, group_offset)*
+			file_system_info.block_size)/
+		sizeof (struct ext2_inode);
 
 	first_entry=0;last_entry=file_system_info.super_block.s_inodes_per_group-1;
 	inode_num=0;
@@ -136,7 +139,8 @@
 
 	low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset);
 
-	entry_num=(device_offset-desc.bg_inode_table*file_system_info.block_size)/sizeof (struct ext2_inode);
+	entry_num=(device_offset-EXT2_INODE_TABLE(&desc, group_offset)*file_system_info.block_size)/
+		sizeof (struct ext2_inode);
 	first_entry=0;last_entry=file_system_info.super_block.s_inodes_per_group-1;
 	inode_num=group_num*file_system_info.super_block.s_inodes_per_group+1;
 	inode_num+=entry_num;
@@ -303,7 +307,9 @@
 
 	low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset);
 
-	entry_num=(device_offset-desc.bg_inode_table*file_system_info.block_size)/sizeof (struct ext2_inode);
+	entry_num=(device_offset-EXT2_INODE_TABLE(&desc, group_offset)*
+		file_system_info.block_size)/
+		sizeof (struct ext2_inode);
 
 	if (wanted_entry > entry_num) {
 		sprintf (buffer,"next %ld",wanted_entry-entry_num);
@@ -386,7 +392,8 @@
 
 	while (!found && group_num>=0 && group_num<file_system_info.groups_count) {
 		low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset);
-		if (block_num>=desc.bg_inode_table && block_num<desc.bg_inode_table+file_system_info.blocks_per_group)
+		if (block_num>=EXT2_INODE_TABLE(&desc, group_offset) &&
+				block_num<EXT2_INODE_TABLE(&desc, group_offset)+file_system_info.blocks_per_group)
 			found=1;
 		else
 			group_offset+=sizeof (struct ext2_group_desc);
@@ -415,7 +422,7 @@
 
 	low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset);
 
-	entry_num=((inode_offset-desc.bg_inode_table*file_system_info.block_size)/sizeof(struct ext2_inode);
+	entry_num=(inode_offset-EXT2_INODE_TABLE(&desc, group_offset)*
 		file_system_info.block_size)/
 		sizeof (struct ext2_inode);
 	first_entry=0;last_entry=file_system_info.super_block.s_inodes_per_group-1;
@@ -439,7 +446,7 @@
 	group_offset=file_system_info.first_group_desc_offset+group_num*sizeof (struct ext2_group_desc);
 	low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset);
 
-	inode_offset=desc.bg_inode_table*file_system_info.block_size+inode_entry*sizeof (struct ext2_inode);
+	inode_offset=EXT2_INODE_TABLE(&desc, group_offset)*file_system_info.block_size+inode_entry*sizeof (struct ext2_inode);
 
 	return (inode_offset);
 }
Index: e2fsprogs/ext2ed/group_com.c
===================================================================
--- e2fsprogs.orig/ext2ed/group_com.c	2006-05-24 15:30:20.000000000 +0200
+++ e2fsprogs/ext2ed/group_com.c	2006-05-24 15:30:29.000000000 +0200
@@ -134,11 +134,13 @@
 void type_ext2_group_desc___inode (char *command_line)
 
 {
-	blk_t inode_offset;
+	long inode_offset;
 	char buffer [80];
 	
-	inode_offset=type_data.u.t_ext2_group_desc.bg_inode_table;
-	sprintf (buffer,"setoffset block %lu",inode_offset);dispatch (buffer);
+	inode_offset=EXT2_INODE_TABLE(&type_data.u.t_ext2_group_desc,
+			EXT2_GROUP_BASE(file_system_info.super_block, group_info.group_num));
+
+	sprintf (buffer,"setoffset block %llu",inode_offset);dispatch (buffer);
 	sprintf (buffer,"settype ext2_inode");dispatch (buffer);
 }
 
@@ -150,9 +152,10 @@
 	
 	block_bitmap_info.entry_num=0;
 	block_bitmap_info.group_num=group_info.group_num;
-	
-	block_bitmap_offset=type_data.u.t_ext2_group_desc.bg_block_bitmap;
-	sprintf (buffer,"setoffset block %lu",block_bitmap_offset);dispatch (buffer);
+
+	block_bitmap_offset=EXT2_BLOCK_BITMAP(&type_data.u.t_ext2_group_desc, 
+			EXT2_GROUP_BASE(&file_system_info.super_block, group_info.group_num));
+	sprintf (buffer,"setoffset block %lld",block_bitmap_offset);dispatch (buffer);
 	sprintf (buffer,"settype block_bitmap");dispatch (buffer);
 }
 
@@ -165,8 +168,10 @@
 	inode_bitmap_info.entry_num=0;
 	inode_bitmap_info.group_num=group_info.group_num;
 	
-	inode_bitmap_offset=type_data.u.t_ext2_group_desc.bg_inode_bitmap;
-	sprintf (buffer,"setoffset block %lu",inode_bitmap_offset);dispatch (buffer);
+	inode_bitmap_offset=EXT2_INODE_BITMAP(&type_data.u.t_ext2_group_desc,
+					      EXT2_GROUP_BASE(&file_system_info.super_block,
+						      group_info.group_num));
+	sprintf (buffer,"setoffset block %lld",inode_bitmap_offset);dispatch (buffer);
 	sprintf (buffer,"settype inode_bitmap");dispatch (buffer);
 }
 
Index: e2fsprogs/debugfs/debugfs.c
===================================================================
--- e2fsprogs.orig/debugfs/debugfs.c	2006-05-24 15:30:20.000000000 +0200
+++ e2fsprogs/debugfs/debugfs.c	2006-05-24 15:30:29.000000000 +0200
@@ -232,8 +232,8 @@
 		return;
 
 	memset(&param, 0, sizeof(struct ext2_super_block));
-	param.s_blocks_count = parse_ullong(argv[2], argv[0],
-					   "blocks count", &err);
+	EXT2_BLOCKS_COUNT_SET(&param, parse_ullong(argv[2], argv[0],
+					   "blocks count", &err));
 	if (err)
 		return;
 	retval = ext2fs_initialize(argv[1], 0, &param,
@@ -316,14 +316,16 @@
 	
 	gdp = &current_fs->group_desc[0];
 	for (i = 0; i < current_fs->group_desc_count; i++, gdp++) {
-		fprintf(out, " Group %2d: block bitmap at %lu, "
-		        "inode bitmap at %lu, "
-		        "inode table at %lu\n"
+		blk_t group_base = EXT2_GROUP_BASE(current_fs->super, i);
+		fprintf(out, " Group %2d: block bitmap at %llu, "
+		        "inode bitmap at %llu, "
+		        "inode table at %llu\n"
 		        "           %d free %s, "
 		        "%d free %s, "
 		        "%d used %s\n",
-		        i, gdp->bg_block_bitmap,
-		        gdp->bg_inode_bitmap, gdp->bg_inode_table,
+		        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,
@@ -377,9 +379,9 @@
 	else
 		fprintf(lb->f, ", ");
 	if (lb->first_block == lb->last_block)
-		fprintf(lb->f, "(%lld):%lu", lb->first_bcnt, lb->first_block);
+		fprintf(lb->f, "(%lld):%lld", lb->first_bcnt, lb->first_block);
 	else
-		fprintf(lb->f, "(%lld-%lld):%lu-%lu", lb->first_bcnt,
+		fprintf(lb->f, "(%lld-%lld):%llu-%llu", lb->first_bcnt,
 			lb->last_bcnt, lb->first_block, lb->last_block);
 	lb->first_block = 0;
 }
@@ -421,11 +423,11 @@
 	else
 		fprintf(lb->f, ", ");
 	if (blockcnt == -1)
-		fprintf(lb->f, "(IND):%lu", *blocknr);
+		fprintf(lb->f, "(IND):%llu", *blocknr);
 	else if (blockcnt == -2)
-		fprintf(lb->f, "(DIND):%lu", *blocknr);
+		fprintf(lb->f, "(DIND):%llu", *blocknr);
 	else if (blockcnt == -3)
-		fprintf(lb->f, "(TIND):%lu", *blocknr);
+		fprintf(lb->f, "(TIND):%llu", *blocknr);
 	return 0;
 }
 
@@ -1713,13 +1715,15 @@
 	offset = ((ino - 1) % EXT2_INODES_PER_GROUP(current_fs->super)) *
 		EXT2_INODE_SIZE(current_fs->super);
 	block = offset >> EXT2_BLOCK_SIZE_BITS(current_fs->super);
-	if (!current_fs->group_desc[(unsigned)group].bg_inode_table) {
+	if (!EXT2_IS_USED_INODE_TABLE(&current_fs->group_desc[(unsigned)group])) {
 		com_err(argv[0], 0, "Inode table for group %lu is missing\n",
 			group);
 		return;
 	}
-	block_nr = current_fs->group_desc[(unsigned)group].bg_inode_table + 
-		block;
+
+	block_nr = EXT2_INODE_TABLE(&current_fs->group_desc[(unsigned)group],
+			EXT2_GROUP_BASE(current_fs->super, group)) +
+			block;
 	offset &= (EXT2_BLOCK_SIZE(current_fs->super) - 1);
 
 	printf("Inode %d is part of block group %lu\n"
Index: e2fsprogs/lib/ext2fs/ext2fs.h
===================================================================
--- e2fsprogs.orig/lib/ext2fs/ext2fs.h	2006-05-24 15:30:20.000000000 +0200
+++ e2fsprogs/lib/ext2fs/ext2fs.h	2006-05-24 15:30:29.000000000 +0200
@@ -71,13 +71,15 @@
 #endif /* EXT2_FLAT_INCLUDES */
 
 typedef __u32		ext2_ino_t;
-typedef __u32		blk_t;
+typedef __u64		blk_t;
 typedef __u32		pblk_t;
 typedef __u32		dgrp_t;
 typedef __u32		ext2_off_t;
 typedef __s64		e2_blkcnt_t;
 typedef __u32		ext2_dirhash_t;
 
+#define _EXT2_64BIT_BLK_T	1
+
 #if EXT2_FLAT_INCLUDES
 #include "com_err.h"
 #include "ext2_io.h"
@@ -462,7 +464,8 @@
 					 EXT3_FEATURE_INCOMPAT_RECOVER)
 #endif
 #define EXT2_LIB_FEATURE_RO_COMPAT_SUPP	(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
-					 EXT2_FEATURE_RO_COMPAT_LARGE_FILE)
+					 EXT2_FEATURE_RO_COMPAT_LARGE_FILE|\
+					 EXT2_FEATURE_RO_COMPAT_64BIT)
 /*
  * function prototypes
  */
Index: e2fsprogs/debugfs/set_fields.c
===================================================================
--- e2fsprogs.orig/debugfs/set_fields.c	2006-05-24 15:30:20.000000000 +0200
+++ e2fsprogs/debugfs/set_fields.c	2006-05-24 15:30:29.000000000 +0200
@@ -56,8 +56,11 @@
 static struct field_set_info super_fields[] = {
 	{ "inodes_count", &set_sb.s_inodes_count, 4, parse_uint },
 	{ "blocks_count", &set_sb.s_blocks_count, 4, parse_uint },
+	{ "blocks_count_hi", &set_sb.s_blocks_count_hi, 4, parse_uint },
 	{ "r_blocks_count", &set_sb.s_r_blocks_count, 4, parse_uint },
+	{ "r_blocks_count_hi", &set_sb.s_r_blocks_count_hi, 4, parse_uint },
 	{ "free_blocks_count", &set_sb.s_free_blocks_count, 4, parse_uint },
+	{ "free_blocks_count_hi", &set_sb.s_free_blocks_count_hi, 4, parse_uint },
 	{ "free_inodes_count", &set_sb.s_free_inodes_count, 4, parse_uint },
 	{ "first_data_block", &set_sb.s_first_data_block, 4, parse_uint },
 	{ "log_block_size", &set_sb.s_log_block_size, 4, parse_uint },
Index: e2fsprogs/lib/e2p/feature.c
===================================================================
--- e2fsprogs.orig/lib/e2p/feature.c	2006-05-24 15:30:05.000000000 +0200
+++ e2fsprogs/lib/e2p/feature.c	2006-05-24 15:30:29.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_64BIT,
+			"64bit" },
 	{	E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_COMPRESSION,
 			"compression" },
 	{	E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_FILETYPE,
Index: e2fsprogs/lib/ext2fs/swapfs.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/swapfs.c	2006-05-24 15:30:05.000000000 +0200
+++ e2fsprogs/lib/ext2fs/swapfs.c	2006-05-24 15:30:29.000000000 +0200
@@ -26,8 +26,11 @@
   	int i;
 	sb->s_inodes_count = ext2fs_swab32(sb->s_inodes_count);
 	sb->s_blocks_count = ext2fs_swab32(sb->s_blocks_count);
+	sb->s_blocks_count_hi = ext2fs_swab32(sb->s_blocks_count_hi);
 	sb->s_r_blocks_count = ext2fs_swab32(sb->s_r_blocks_count);
+	sb->s_r_blocks_count_hi = ext2fs_swab32(sb->s_r_blocks_count_hi);
 	sb->s_free_blocks_count = ext2fs_swab32(sb->s_free_blocks_count);
+	sb->s_free_blocks_count_hi = ext2fs_swab32(sb->s_free_blocks_count_hi);
 	sb->s_free_inodes_count = ext2fs_swab32(sb->s_free_inodes_count);
 	sb->s_first_data_block = ext2fs_swab32(sb->s_first_data_block);
 	sb->s_log_block_size = ext2fs_swab32(sb->s_log_block_size);
Index: e2fsprogs/lib/ext2fs/bitops.h
===================================================================
--- e2fsprogs.orig/lib/ext2fs/bitops.h	2006-05-24 15:30:20.000000000 +0200
+++ e2fsprogs/lib/ext2fs/bitops.h	2006-05-24 15:30:29.000000000 +0200
@@ -136,7 +136,7 @@
  * previous bit value.
  */
 
-_INLINE_ void ext2fs_fast_set_bit(unsigned int nr,void * addr)
+_INLINE_ void ext2fs_fast_set_bit(blk_t nr,void * addr)
 {
 	unsigned char	*ADDR = (unsigned char *) addr;
 
@@ -144,7 +144,7 @@
 	*ADDR |= (1 << (nr & 0x07));
 }
 
-_INLINE_ void ext2fs_fast_clear_bit(unsigned int nr, void * addr)
+_INLINE_ void ext2fs_fast_clear_bit(blk_t nr, void * addr)
 {
 	unsigned char	*ADDR = (unsigned char *) addr;
 
@@ -154,7 +154,8 @@
 
 
 #if ((defined __GNUC__) && !defined(_EXT2_USE_C_VERSIONS_) && \
-     (defined(__i386__) || defined(__i486__) || defined(__i586__)))
+     (defined(__i386__) || defined(__i486__) || defined(__i586__)) && \
+     !(defined(_EXT2_64BIT_BLK_T) && (SIZEOF_LONG == 4)))
 
 #define _EXT2_HAVE_ASM_BITOPS_
 #define _EXT2_HAVE_ASM_SWAB_
Index: e2fsprogs/lib/ext2fs/rw_bitmaps.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/rw_bitmaps.c	2006-05-24 15:30:05.000000000 +0200
+++ e2fsprogs/lib/ext2fs/rw_bitmaps.c	2006-05-24 15:30:29.000000000 +0200
@@ -91,6 +91,7 @@
 	}
 
 	for (i = 0; i < fs->group_desc_count; i++) {
+		blk_t group_base = EXT2_GROUP_BASE(fs->super, i);
 		if (!block_bitmap || !do_block)
 			goto skip_block_bitmap;
 
@@ -101,15 +102,15 @@
 		memcpy(block_buf, block_bitmap, block_nbytes);
 		if (i == fs->group_desc_count - 1) {
 			/* Force bitmap padding for the last group */
-			nbits = ((fs->super->s_blocks_count
+			nbits = ((EXT2_BLOCKS_COUNT(fs->super)
 				  - fs->super->s_first_data_block)
 				 % EXT2_BLOCKS_PER_GROUP(fs->super));
 			if (nbits)
 				for (j = nbits; j < fs->blocksize * 8; j++)
 					ext2fs_set_bit(j, block_buf);
 		}
-		blk = fs->group_desc[i].bg_block_bitmap;
-		if (blk) {
+		if (EXT2_IS_USED_BLOCK_BITMAP(&fs->group_desc[i])) {
+			 blk = EXT2_BLOCK_BITMAP(&fs->group_desc[i], EXT2_GROUP_BASE(fs->super, i));
 #ifdef EXT2_BIG_ENDIAN_BITMAPS
 			if (!((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
 			      (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)))
@@ -133,8 +134,8 @@
 			goto skip_this_inode_bitmap;
  
 		memcpy(inode_buf, inode_bitmap, inode_nbytes);
-		blk = fs->group_desc[i].bg_inode_bitmap;
-		if (blk) {
+		if (EXT2_IS_USED_INODE_BITMAP(&fs->group_desc[i])) {
+			blk = EXT2_INODE_BITMAP(&fs->group_desc[i], group_base);
 #ifdef EXT2_BIG_ENDIAN_BITMAPS
 			if (!((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
 			      (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)))
@@ -226,12 +227,14 @@
 	}
 
 	for (i = 0; i < fs->group_desc_count; i++) {
+		blk_t group_base = EXT2_GROUP_BASE(fs->super, i);
 		if (block_bitmap) {
-			blk = fs->group_desc[i].bg_block_bitmap;
-			if (lazy_flag && fs->group_desc[i].bg_flags &
-			    EXT2_BG_BLOCK_UNINIT)
-				blk = 0;
-			if (blk) {
+			if (EXT2_IS_USED_BLOCK_BITMAP(&fs->group_desc[i])) {
+				blk = EXT2_BLOCK_BITMAP(&fs->group_desc[i],
+							group_base);
+				if (lazy_flag && fs->group_desc[i].bg_flags &
+			    	    EXT2_BG_BLOCK_UNINIT)
+					blk = 0;
 				retval = io_channel_read_blk(fs->io, blk,
 					     -block_nbytes, block_bitmap);
 				if (retval) {
@@ -248,11 +251,11 @@
 			block_bitmap += block_nbytes;
 		}
 		if (inode_bitmap) {
-			blk = fs->group_desc[i].bg_inode_bitmap;
-			if (lazy_flag && fs->group_desc[i].bg_flags &
-			    EXT2_BG_INODE_UNINIT)
-				blk = 0;
-			if (blk) {
+			if (EXT2_IS_USED_INODE_BITMAP(&fs->group_desc[i])) {
+				blk = EXT2_INODE_BITMAP(&fs->group_desc[i], group_base);
+				if (lazy_flag && fs->group_desc[i].bg_flags &
+			    	    EXT2_BG_INODE_UNINIT)
+					blk = 0;
 				retval = io_channel_read_blk(fs->io, blk,
 					     -inode_nbytes, inode_bitmap);
 				if (retval) {
Index: e2fsprogs/resize/main.c
===================================================================
--- e2fsprogs.orig/resize/main.c	2006-05-24 15:30:05.000000000 +0200
+++ e2fsprogs/resize/main.c	2006-05-24 15:30:29.000000000 +0200
@@ -103,14 +103,15 @@
 
 	num = 0; sum = 0;
 	for (group = 0; group < fs->group_desc_count; group++) {
+		blk_t group_base = EXT2_GROUP_BASE(fs->super, group);
 		has_sb = ext2fs_bg_has_super(fs, group);
 		if (group == 0 || has_sb != prev_has_sb)
 			goto next;
-		b_stride = fs->group_desc[group].bg_block_bitmap - 
-			fs->group_desc[group-1].bg_block_bitmap - 
+		b_stride = EXT2_BLOCK_BITMAP(&fs->group_desc[group], group_base) - 
+			EXT2_BLOCK_BITMAP(&fs->group_desc[group-1], group_base) - 
 			fs->super->s_blocks_per_group;
-		i_stride = fs->group_desc[group].bg_inode_bitmap - 
-			fs->group_desc[group-1].bg_inode_bitmap - 
+		i_stride = EXT2_INODE_BITMAP(&fs->group_desc[group], group_base) - 
+			EXT2_INODE_BITMAP(&fs->group_desc[group-1], group_base) - 
 			fs->super->s_blocks_per_group;
 		if (b_stride != i_stride ||
 		    b_stride < 0)
@@ -374,7 +375,7 @@
 			fs->blocksize / 1024, new_size);
 		exit(1);
 	}
-	if (new_size == fs->super->s_blocks_count) {
+	if (new_size ==  EXT2_BLOCKS_COUNT(fs->super)) {
 		fprintf(stderr, _("The filesystem is already %u blocks "
 			"long.  Nothing to do!\n\n"), new_size);
 		exit(0);
Index: e2fsprogs/resize/online.c
===================================================================
--- e2fsprogs.orig/resize/online.c	2006-05-24 15:30:05.000000000 +0200
+++ e2fsprogs/resize/online.c	2006-05-24 15:30:29.000000000 +0200
@@ -32,9 +32,9 @@
 	printf(_("Filesystem at %s is mounted on %s; "
 		 "on-line resizing required\n"), fs->device_name, mtpt);
 
-	if (*new_size < sb->s_blocks_count) {
-		printf(_("On-line shrinking from %u to %u not supported.\n"),
-		       sb->s_blocks_count, *new_size);
+	if (*new_size < EXT2_BLOCKS_COUNT(sb)) {
+		printf(_("On-line shrinking from %llu to %u not supported.\n"),
+		       EXT2_BLOCKS_COUNT(sb), *new_size);
 		exit(1);
 	}
 
@@ -45,7 +45,7 @@
 		exit(1);
 	}
 
-	size=sb->s_blocks_count;
+	size=EXT2_BLOCKS_COUNT(sb);
 	if (ioctl(fd, EXT2_IOC_GROUP_EXTEND, &size)) {
 		if (errno == EPERM)
 			com_err(program_name, 0, 
@@ -59,8 +59,8 @@
 		exit(1);
 	}
 
-	r_frac = ((100 * sb->s_r_blocks_count) + sb->s_blocks_count-1) /
-		sb->s_blocks_count;
+	r_frac = ((100 * EXT2_R_BLOCKS_COUNT(sb)) + EXT2_BLOCKS_COUNT(sb)-1) /
+		EXT2_BLOCKS_COUNT(sb);
 
 	retval = ext2fs_read_bitmaps(fs);
 	if (retval)
@@ -90,6 +90,7 @@
 
 	for (i = fs->group_desc_count;
 	     i < new_fs->group_desc_count; i++) {
+		blk_t group_base = EXT2_GROUP_BASE(new_fs->super, i);
 
 		overhead = (int) (2 + new_fs->inode_blocks_per_group);
 
@@ -98,12 +99,15 @@
 				new_fs->super->s_reserved_gdt_blocks;
 
 		input.group = i;
-		input.block_bitmap = new_fs->group_desc[i].bg_block_bitmap;
-		input.inode_bitmap = new_fs->group_desc[i].bg_inode_bitmap;
-		input.inode_table = new_fs->group_desc[i].bg_inode_table;
+		input.block_bitmap = EXT2_BLOCK_BITMAP(&new_fs->group_desc[i], 
+							group_base);
+		input.inode_bitmap = EXT2_INODE_BITMAP(&new_fs->group_desc[i], 
+							group_base);
+		input.inode_table = EXT2_INODE_TABLE(&new_fs->group_desc[i], 
+							group_base);
 		input.blocks_count = sb->s_blocks_per_group;
 		if (i == new_fs->group_desc_count-1) {
-			input.blocks_count = new_fs->super->s_blocks_count -
+			input.blocks_count = EXT2_BLOCKS_COUNT(new_fs->super) -
 				sb->s_first_data_block - 
 				(i * sb->s_blocks_per_group);
 		}
Index: e2fsprogs/lib/ext2fs/tst_badblocks.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/tst_badblocks.c	2006-05-24 15:30:05.000000000 +0200
+++ e2fsprogs/lib/ext2fs/tst_badblocks.c	2006-05-24 15:30:29.000000000 +0200
@@ -227,7 +227,7 @@
 	fs->super = malloc(SUPERBLOCK_SIZE);
 	memset(fs->super, 0, SUPERBLOCK_SIZE);
 	fs->super->s_first_data_block = 1;
-	fs->super->s_blocks_count = 100;
+	EXT2_BLOCKS_COUNT_SET(fs->super, 100);
 
 	f = tmpfile();
 	if (!f) {


-------------------------------------------------------
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.