Re: Current >32bit ext3 patches against 2.6.17-rc4

Laurent Vivier <[email protected]>
Newsgroups gmane.comp.file-systems.ext2.devel
Organization Bull S.A.S.
Message-ID <[email protected]>
Hi,

Mingming Cao wrote:
[...]
> The missing parts to complete this series are:1) forward port Alex's
> extents patch on top of this series, 2) the JBM kernel fs block changes,
> as well as 3) the updated 64bit metadata changes.

find attached the 64bit metadata changes completing this series.
I use the algorithm proposed by Stephen.
Compiled but not tested as we are configuring new disks on our system.

Regards,
Laurent
-- 
Laurent Vivier
Bull, Architect of an Open World (TM)
http://www.bullopensource.org/ext4
64bit-metadata.patch (text/plain, 19.1 KB)
Index: linux-2.6.17-rc4/fs/ext3/balloc.c
===================================================================
--- linux-2.6.17-rc4.orig/fs/ext3/balloc.c	2006-05-23 17:38:32.000000000 +0200
+++ linux-2.6.17-rc4/fs/ext3/balloc.c	2006-05-23 17:38:32.000000000 +0200
@@ -88,12 +88,16 @@
 	desc = ext3_get_group_desc (sb, block_group, NULL);
 	if (!desc)
 		goto error_out;
-	bh = sb_bread(sb, le32_to_cpu(desc->bg_block_bitmap));
+	bh = sb_bread(sb, 
+		      EXT3_BLOCK_BITMAP(desc, 
+			      ext3_group_first_block_no(sb, block_group)));
 	if (!bh)
 		ext3_error (sb, "read_block_bitmap",
 			    "Cannot read block bitmap - "
-			    "block_group = %d, block_bitmap = %u",
-			    block_group, le32_to_cpu(desc->bg_block_bitmap));
+			    "block_group = %d, block_bitmap = "E3FSBLK,
+			    block_group, 
+			    EXT3_BLOCK_BITMAP(desc, 
+			      ext3_group_first_block_no(sb, block_group)));
 error_out:
 	return bh;
 }
@@ -328,7 +332,7 @@
 	es = sbi->s_es;
 	if (block < le32_to_cpu(es->s_first_data_block) ||
 	    block + count < block ||
-	    block + count > le32_to_cpu(es->s_blocks_count)) {
+	    block + count > EXT3_BLOCKS_COUNT(es)) {
 		ext3_error (sb, "ext3_free_blocks",
 			    "Freeing blocks not in datazone - "
 			    "block = "E3FSBLK", count = %lu", block, count);
@@ -356,11 +360,19 @@
 	if (!desc)
 		goto error_return;
 
-	if (in_range (le32_to_cpu(desc->bg_block_bitmap), block, count) ||
-	    in_range (le32_to_cpu(desc->bg_inode_bitmap), block, count) ||
-	    in_range (block, le32_to_cpu(desc->bg_inode_table),
+	if (in_range (EXT3_BLOCK_BITMAP(desc, 
+				ext3_group_first_block_no(sb, block_group)),
+		      block, count) ||
+	    in_range (EXT3_INODE_BITMAP(desc, 
+			    	ext3_group_first_block_no(sb, block_group)),
+		      block, count) ||
+	    in_range (block, 
+		      EXT3_INODE_TABLE(desc, 
+			      	ext3_group_first_block_no(sb, block_group)),
 		      sbi->s_itb_per_group) ||
-	    in_range (block + count - 1, le32_to_cpu(desc->bg_inode_table),
+	    in_range (block + count - 1, 
+		      EXT3_INODE_TABLE(desc, 
+			      	ext3_group_first_block_no(sb, block_group)),
 		      sbi->s_itb_per_group))
 		ext3_error (sb, "ext3_free_blocks",
 			    "Freeing blocks in system zones - "
@@ -1163,7 +1175,7 @@
 	ext3_fsblk_t free_blocks, root_blocks;
 
 	free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
-	root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
+	root_blocks = EXT3_R_BLOCKS_COUNT(sbi->s_es);
 	if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
 		sbi->s_resuid != current->fsuid &&
 		(sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
@@ -1262,7 +1274,7 @@
 	 * First, test whether the goal block is free.
 	 */
 	if (goal < le32_to_cpu(es->s_first_data_block) ||
-	    goal >= le32_to_cpu(es->s_blocks_count))
+	    goal >= EXT3_BLOCKS_COUNT(es))
 		goal = le32_to_cpu(es->s_first_data_block);
 	ext3_get_group_no_and_offset(sb, goal, &group_no, &grp_target_blk);
 	gdp = ext3_get_group_desc(sb, group_no, &gdp_bh);
@@ -1361,11 +1373,15 @@
 
 	ret_block = grp_alloc_blk + ext3_group_first_block_no(sb, group_no);
 
-	if (in_range(le32_to_cpu(gdp->bg_block_bitmap), ret_block, num) ||
-	    in_range(le32_to_cpu(gdp->bg_inode_bitmap), ret_block, num) ||
-	    in_range(ret_block, le32_to_cpu(gdp->bg_inode_table),
+	if (in_range(EXT3_BLOCK_BITMAP(gdp, ext3_group_first_block_no(sb, group_no)), 
+				ret_block, num) ||
+	    in_range(EXT3_BLOCK_BITMAP(gdp, ext3_group_first_block_no(sb, group_no)), 
+		    		ret_block, num) ||
+	    in_range(ret_block, EXT3_INODE_TABLE(gdp, 
+			    	ext3_group_first_block_no(sb, group_no)),
 		      EXT3_SB(sb)->s_itb_per_group) ||
-	    in_range(ret_block + num - 1, le32_to_cpu(gdp->bg_inode_table),
+	    in_range(ret_block + num - 1, EXT3_INODE_TABLE(gdp, 
+			    ext3_group_first_block_no(sb, group_no)),
 		      EXT3_SB(sb)->s_itb_per_group))
 		ext3_error(sb, "ext3_new_block",
 			    "Allocating block in system zone - "
@@ -1404,11 +1420,11 @@
 	jbd_unlock_bh_state(bitmap_bh);
 #endif
 
-	if (ret_block + num - 1 >= le32_to_cpu(es->s_blocks_count)) {
+	if (ret_block + num - 1 >= EXT3_BLOCKS_COUNT(es)) {
 		ext3_error(sb, "ext3_new_block",
-			    "block("E3FSBLK") >= blocks count(%d) - "
+			    "block("E3FSBLK") >= blocks count("E3FSBLK") - "
 			    "block_group = %lu, es == %p ", ret_block,
-			le32_to_cpu(es->s_blocks_count), group_no, es);
+			EXT3_BLOCKS_COUNT(es), group_no, es);
 		goto out;
 	}
 
@@ -1501,7 +1517,7 @@
 	brelse(bitmap_bh);
 	printk("ext3_count_free_blocks: stored = "E3FSBLK
 		", computed = "E3FSBLK", "E3FSBLK"\n",
-	       le32_to_cpu(es->s_free_blocks_count),
+	       EXT3_FREE_BLOCKS_COUNT(es),
 		desc_count, bitmap_count);
 	return bitmap_count;
 #else
Index: linux-2.6.17-rc4/fs/ext3/ialloc.c
===================================================================
--- linux-2.6.17-rc4.orig/fs/ext3/ialloc.c	2006-05-23 17:38:32.000000000 +0200
+++ linux-2.6.17-rc4/fs/ext3/ialloc.c	2006-05-23 17:38:32.000000000 +0200
@@ -60,12 +60,14 @@
 	if (!desc)
 		goto error_out;
 
-	bh = sb_bread(sb, le32_to_cpu(desc->bg_inode_bitmap));
+	bh = sb_bread(sb, EXT3_INODE_BITMAP(desc, 
+			      ext3_group_first_block_no(sb, block_group)));
 	if (!bh)
 		ext3_error(sb, "read_inode_bitmap",
 			    "Cannot read inode bitmap - "
-			    "block_group = %lu, inode_bitmap = %u",
-			    block_group, le32_to_cpu(desc->bg_inode_bitmap));
+			    "block_group = %lu, inode_bitmap = %llu",
+			    block_group, EXT3_INODE_BITMAP(desc, 
+			      ext3_group_first_block_no(sb, block_group)));
 error_out:
 	return bh;
 }
@@ -304,7 +306,7 @@
 		goto fallback;
 	}
 
-	blocks_per_dir = le32_to_cpu(es->s_blocks_count) - freeb;
+	blocks_per_dir = EXT3_BLOCKS_COUNT(es) - freeb;
 	sector_div(blocks_per_dir, ndirs);
 
 	max_dirs = ndirs / ngroups + inodes_per_group / 16;
Index: linux-2.6.17-rc4/fs/ext3/inode.c
===================================================================
--- linux-2.6.17-rc4.orig/fs/ext3/inode.c	2006-05-23 17:38:32.000000000 +0200
+++ linux-2.6.17-rc4/fs/ext3/inode.c	2006-05-23 17:38:32.000000000 +0200
@@ -2431,8 +2431,9 @@
 	 */
 	offset = ((ino - 1) % EXT3_INODES_PER_GROUP(sb)) *
 		EXT3_INODE_SIZE(sb);
-	block = le32_to_cpu(gdp[desc].bg_inode_table) +
-		(offset >> EXT3_BLOCK_SIZE_BITS(sb));
+	block = EXT3_INODE_TABLE((gdp+desc), 
+			ext3_group_first_block_no(sb, block_group)) +
+			(offset >> EXT3_BLOCK_SIZE_BITS(sb));
 
 	iloc->block_group = block_group;
 	iloc->offset = offset & (EXT3_BLOCK_SIZE(sb) - 1);
@@ -2499,7 +2500,9 @@
 				goto make_io;
 
 			bitmap_bh = sb_getblk(inode->i_sb,
-					le32_to_cpu(desc->bg_inode_bitmap));
+				EXT3_INODE_BITMAP(desc, 
+				     ext3_group_first_block_no(inode->i_sb,
+						     block_group)));
 			if (!bitmap_bh)
 				goto make_io;
 
Index: linux-2.6.17-rc4/fs/ext3/resize.c
===================================================================
--- linux-2.6.17-rc4.orig/fs/ext3/resize.c	2006-05-23 17:38:32.000000000 +0200
+++ linux-2.6.17-rc4/fs/ext3/resize.c	2006-05-23 17:38:32.000000000 +0200
@@ -27,7 +27,7 @@
 {
 	struct ext3_sb_info *sbi = EXT3_SB(sb);
 	struct ext3_super_block *es = sbi->s_es;
-	ext3_fsblk_t start = le32_to_cpu(es->s_blocks_count);
+	ext3_fsblk_t start = EXT3_BLOCKS_COUNT(es);
 	ext3_fsblk_t end = start + input->blocks_count;
 	unsigned group = input->group;
 	ext3_fsblk_t itend = input->inode_table + sbi->s_itb_per_group;
@@ -818,9 +818,12 @@
 	/* Update group descriptor block for new group */
 	gdp = (struct ext3_group_desc *)primary->b_data + gdb_off;
 
-	gdp->bg_block_bitmap = cpu_to_le32(input->block_bitmap);
-	gdp->bg_inode_bitmap = cpu_to_le32(input->inode_bitmap);
-	gdp->bg_inode_table = cpu_to_le32(input->inode_table);
+	EXT3_BLOCK_BITMAP_SET(gdp, ext3_group_first_block_no(sb, gdb_num), 
+				   input->block_bitmap); /* LV FIXME */
+	EXT3_INODE_BITMAP_SET(gdp, ext3_group_first_block_no(sb, gdb_num), 
+			           input->inode_bitmap); /* LV FIXME */
+	EXT3_INODE_TABLE_SET(gdp, ext3_group_first_block_no(sb, gdb_num), 
+			          input->inode_table); /* LV FIXME */
 	gdp->bg_free_blocks_count = cpu_to_le16(input->free_blocks_count);
 	gdp->bg_free_inodes_count = cpu_to_le16(EXT3_INODES_PER_GROUP(sb));
 
@@ -834,7 +837,7 @@
 	 * blocks/inodes before the group is live won't actually let us
 	 * allocate the new space yet.
 	 */
-	es->s_blocks_count = cpu_to_le32(le32_to_cpu(es->s_blocks_count) +
+	EXT3_BLOCKS_COUNT_SET(es, EXT3_BLOCKS_COUNT(es) +
 		input->blocks_count);
 	es->s_inodes_count = cpu_to_le32(le32_to_cpu(es->s_inodes_count) +
 		EXT3_INODES_PER_GROUP(sb));
@@ -870,7 +873,7 @@
 
 	/* Update the reserved block counts only once the new group is
 	 * active. */
-	es->s_r_blocks_count = cpu_to_le32(le32_to_cpu(es->s_r_blocks_count) +
+	EXT3_R_BLOCKS_COUNT_SET(es, EXT3_R_BLOCKS_COUNT(es) +
 		input->reserved_blocks);
 
 	/* Update the free space counts */
@@ -921,7 +924,7 @@
 	/* We don't need to worry about locking wrt other resizers just
 	 * yet: we're going to revalidate es->s_blocks_count after
 	 * taking lock_super() below. */
-	o_blocks_count = le32_to_cpu(es->s_blocks_count);
+	o_blocks_count = EXT3_BLOCKS_COUNT(es);
 	o_groups_count = EXT3_SB(sb)->s_groups_count;
 
 	if (test_opt(sb, DEBUG))
@@ -986,7 +989,7 @@
 	}
 
 	lock_super(sb);
-	if (o_blocks_count != le32_to_cpu(es->s_blocks_count)) {
+	if (o_blocks_count != EXT3_BLOCKS_COUNT(es)) {
 		ext3_warning(sb, __FUNCTION__,
 			     "multiple resizers run on filesystem!");
 		unlock_super(sb);
@@ -1002,7 +1005,7 @@
 		ext3_journal_stop(handle);
 		goto exit_put;
 	}
-	es->s_blocks_count = cpu_to_le32(o_blocks_count + add);
+	EXT3_BLOCKS_COUNT_SET(es, o_blocks_count + add);
 	ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
 	sb->s_dirt = 1;
 	unlock_super(sb);
@@ -1014,8 +1017,8 @@
 	if ((err = ext3_journal_stop(handle)))
 		goto exit_put;
 	if (test_opt(sb, DEBUG))
-		printk(KERN_DEBUG "EXT3-fs: extended group to %u blocks\n",
-		       le32_to_cpu(es->s_blocks_count));
+		printk(KERN_DEBUG "EXT3-fs: extended group to %llu blocks\n",
+		       EXT3_BLOCKS_COUNT(es));
 	update_backups(sb, EXT3_SB(sb)->s_sbh->b_blocknr, (char *)es,
 		       sizeof(struct ext3_super_block));
 exit_put:
Index: linux-2.6.17-rc4/fs/ext3/super.c
===================================================================
--- linux-2.6.17-rc4.orig/fs/ext3/super.c	2006-05-23 17:38:32.000000000 +0200
+++ linux-2.6.17-rc4/fs/ext3/super.c	2006-05-23 17:38:32.000000000 +0200
@@ -1140,44 +1140,48 @@
 		if ((i % EXT3_DESC_PER_BLOCK(sb)) == 0)
 			gdp = (struct ext3_group_desc *)
 					sbi->s_group_desc[desc_block++]->b_data;
-		if (le32_to_cpu(gdp->bg_block_bitmap) < block ||
-		    le32_to_cpu(gdp->bg_block_bitmap) >=
+		if (EXT3_BLOCK_BITMAP(gdp, ext3_group_first_block_no(sb, i)) <
+				block ||
+		    	EXT3_BLOCK_BITMAP(gdp, ext3_group_first_block_no(sb, i)) >=
 				block + EXT3_BLOCKS_PER_GROUP(sb))
 		{
 			ext3_error (sb, "ext3_check_descriptors",
 				    "Block bitmap for group %d"
 				    " not in group (block %lu)!",
 				    i, (unsigned long)
-					le32_to_cpu(gdp->bg_block_bitmap));
+					EXT3_BLOCK_BITMAP(gdp, ext3_group_first_block_no(sb, i)));	
 			return 0;
 		}
-		if (le32_to_cpu(gdp->bg_inode_bitmap) < block ||
-		    le32_to_cpu(gdp->bg_inode_bitmap) >=
+		if (EXT3_INODE_BITMAP(gdp, ext3_group_first_block_no(sb, i)) <
+				block ||
+		    EXT3_INODE_BITMAP(gdp, ext3_group_first_block_no(sb, i)) >=
 				block + EXT3_BLOCKS_PER_GROUP(sb))
 		{
 			ext3_error (sb, "ext3_check_descriptors",
 				    "Inode bitmap for group %d"
 				    " not in group (block %lu)!",
 				    i, (unsigned long)
-					le32_to_cpu(gdp->bg_inode_bitmap));
+					EXT3_INODE_BITMAP(gdp, ext3_group_first_block_no(sb, i)));
 			return 0;
 		}
-		if (le32_to_cpu(gdp->bg_inode_table) < block ||
-		    le32_to_cpu(gdp->bg_inode_table) + sbi->s_itb_per_group >=
-		    block + EXT3_BLOCKS_PER_GROUP(sb))
+		if (EXT3_INODE_TABLE(gdp, ext3_group_first_block_no(sb, i)) <
+			block ||
+		    EXT3_INODE_TABLE(gdp, ext3_group_first_block_no(sb, i)) +
+							sbi->s_itb_per_group >=
+			block + EXT3_BLOCKS_PER_GROUP(sb))
 		{
 			ext3_error (sb, "ext3_check_descriptors",
 				    "Inode table for group %d"
 				    " not in group (block %lu)!",
 				    i, (unsigned long)
-					le32_to_cpu(gdp->bg_inode_table));
+					EXT3_INODE_TABLE(gdp, ext3_group_first_block_no(sb, i)));
 			return 0;
 		}
 		block += EXT3_BLOCKS_PER_GROUP(sb);
 		gdp++;
 	}
 
-	sbi->s_es->s_free_blocks_count=cpu_to_le32(ext3_count_free_blocks(sb));
+	EXT3_FREE_BLOCKS_COUNT_SET(sbi->s_es, ext3_count_free_blocks(sb));
 	sbi->s_es->s_free_inodes_count=cpu_to_le32(ext3_count_free_inodes(sb));
 	return 1;
 }
@@ -1354,6 +1358,7 @@
 	int i;
 	int needs_recovery;
 	__le32 features;
+	__u64 blocks_count;
 
 	sbi = kmalloc(sizeof(*sbi), GFP_KERNEL);
 	if (!sbi)
@@ -1566,10 +1571,11 @@
 
 	if (EXT3_BLOCKS_PER_GROUP(sb) == 0)
 		goto cantfind_ext3;
-	sbi->s_groups_count = (le32_to_cpu(es->s_blocks_count) -
-			       le32_to_cpu(es->s_first_data_block) +
-			       EXT3_BLOCKS_PER_GROUP(sb) - 1) /
-			      EXT3_BLOCKS_PER_GROUP(sb);
+	blocks_count = (EXT3_BLOCKS_COUNT(es) -
+			le32_to_cpu(es->s_first_data_block) +
+			EXT3_BLOCKS_PER_GROUP(sb) - 1);
+	do_div(blocks_count, EXT3_BLOCKS_PER_GROUP(sb));
+	sbi->s_groups_count = blocks_count;
 	db_count = (sbi->s_groups_count + EXT3_DESC_PER_BLOCK(sb) - 1) /
 		   EXT3_DESC_PER_BLOCK(sb);
 	sbi->s_group_desc = kmalloc(db_count * sizeof (struct buffer_head *),
@@ -1579,7 +1585,7 @@
 		goto failed_mount;
 	}
 
-	if (le32_to_cpu(es->s_blocks_count) >
+	if (EXT3_BLOCKS_COUNT(es) >
 		(sector_t)(~0ULL) >> (sb->s_blocksize_bits - 9)) {
 		printk(KERN_ERR "EXT3-fs: filesystem on %s"
 			" too large to mount safely\n", sb->s_id);
@@ -1890,7 +1896,7 @@
 		goto out_bdev;
 	}
 
-	len = le32_to_cpu(es->s_blocks_count);
+	len = EXT3_BLOCKS_COUNT(es);
 	start = sb_block + 1;
 	brelse(bh);	/* we're done with the superblock */
 
@@ -2060,7 +2066,7 @@
 	if (!sbh)
 		return;
 	es->s_wtime = cpu_to_le32(get_seconds());
-	es->s_free_blocks_count = cpu_to_le32(ext3_count_free_blocks(sb));
+	EXT3_FREE_BLOCKS_COUNT_SET(es, ext3_count_free_blocks(sb));
 	es->s_free_inodes_count = cpu_to_le32(ext3_count_free_inodes(sb));
 	BUFFER_TRACE(sbh, "marking dirty");
 	mark_buffer_dirty(sbh);
@@ -2253,7 +2259,7 @@
 	ext3_init_journal_params(sb, sbi->s_journal);
 
 	if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY) ||
-		n_blocks_count > le32_to_cpu(es->s_blocks_count)) {
+		n_blocks_count > EXT3_BLOCKS_COUNT(es)) {
 		if (sbi->s_mount_opt & EXT3_MOUNT_ABORT) {
 			err = -EROFS;
 			goto restore_opts;
@@ -2373,10 +2379,10 @@
 
 	buf->f_type = EXT3_SUPER_MAGIC;
 	buf->f_bsize = sb->s_blocksize;
-	buf->f_blocks = le32_to_cpu(es->s_blocks_count) - overhead;
+	buf->f_blocks = EXT3_BLOCKS_COUNT(es) - overhead;
 	buf->f_bfree = percpu_counter_sum(&sbi->s_freeblocks_counter);
-	buf->f_bavail = buf->f_bfree - le32_to_cpu(es->s_r_blocks_count);
-	if (buf->f_bfree < le32_to_cpu(es->s_r_blocks_count))
+	buf->f_bavail = buf->f_bfree - EXT3_R_BLOCKS_COUNT(es);
+	if (buf->f_bfree < EXT3_R_BLOCKS_COUNT(es))
 		buf->f_bavail = 0;
 	buf->f_files = le32_to_cpu(es->s_inodes_count);
 	buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter);
Index: linux-2.6.17-rc4/include/linux/ext3_fs.h
===================================================================
--- linux-2.6.17-rc4.orig/include/linux/ext3_fs.h	2006-05-23 17:38:32.000000000 +0200
+++ linux-2.6.17-rc4/include/linux/ext3_fs.h	2006-05-23 18:10:18.000000000 +0200
@@ -140,6 +140,54 @@
 	__le32	bg_reserved[3];
 };
 
+static inline u32 EXT3_RELATIVE_ENCODE(ext3_fsblk_t group_base, 
+				       ext3_fsblk_t fs_block)
+{
+	s32 gdp_block;
+
+	if (fs_block < (1ULL<<32) && group_base < (1ULL<<32))
+		return fs_block;
+
+	gdp_block = (fs_block - group_base);
+	BUG_ON ((group_base + gdp_block) != fs_block);
+
+	return gdp_block;
+}
+
+static inline ext3_fsblk_t EXT3_RELATIVE_DECODE(ext3_fsblk_t group_base, 
+						u32 gdp_block)
+{
+	if (group_base >= (1ULL<<32))
+		return group_base + (s32) gdp_block;
+
+	if ((s32) gdp_block >= 0 && gdp_block < group_base && 
+		  group_base + gdp_block >= (1ULL<<32))
+		return group_base + gdp_block;
+
+	return gdp_block;
+}
+
+#define EXT3_BLOCK_BITMAP(bg, group_base)	\
+		EXT3_RELATIVE_DECODE(group_base, le32_to_cpu((bg)->bg_block_bitmap))
+#define EXT3_INODE_BITMAP(bg, group_base)	\
+		EXT3_RELATIVE_DECODE(group_base, le32_to_cpu((bg)->bg_inode_bitmap))
+#define EXT3_INODE_TABLE(bg, group_base)	\
+		EXT3_RELATIVE_DECODE(group_base, le32_to_cpu((bg)->bg_inode_table))
+
+#define EXT3_BLOCK_BITMAP_SET(bg, group_base, value)	\
+	do {(bg)->bg_block_bitmap = EXT3_RELATIVE_ENCODE(group_base, value);} while(0)
+#define EXT3_INODE_BITMAP_SET(bg, group_base, value)	\
+	do {(bg)->bg_inode_bitmap = EXT3_RELATIVE_ENCODE(group_base, value);} while(0)
+#define EXT3_INODE_TABLE_SET(bg, group_base, value)	\
+	do {(bg)->bg_inode_table = EXT3_RELATIVE_ENCODE(group_base, value);} while(0)
+
+#define EXT3_IS_USED_BLOCK_BITMAP(bg)	\
+	((bg)->bg_block_bitmap != 0)
+#define EXT3_IS_USED_INODE_BITMAP(bg)	\
+	((bg)->bg_inode_bitmap != 0)
+#define EXT3_IS_USED_INODE_TABLE(bg)	\
+	((bg)->bg_inode_table != 0)
+
 /*
  * Macro-instructions used to manage group descriptors
  */
@@ -485,9 +533,38 @@
 	__u16	s_reserved_word_pad;
 	__le32	s_default_mount_opts;
 	__le32	s_first_meta_bg; 	/* First metablock block group */
-	__u32	s_reserved[190];	/* Padding to the end of the block */
+	/* 64bit support valid if EXT3_FEATURE_COMPAT_64BIT */
+	__le32	s_blocks_count_hi;	/* Blocks count */
+/*100*/	__le32	s_r_blocks_count_hi;	/* Reserved blocks count */
+	__le32	s_free_blocks_count_hi;	/* Free blocks count */
+	__u32	s_reserved[187];	/* Padding to the end of the block */
 };
 
+
+#define EXT3_BLOCKS_COUNT(s)	\
+	(ext3_fsblk_t)(((__u64)le32_to_cpu((s)->s_blocks_count_hi) << 32) |	\
+	 	(__u64)le32_to_cpu((s)->s_blocks_count))
+#define EXT3_BLOCKS_COUNT_SET(s,v)	do {				\
+	(s)->s_blocks_count = cpu_to_le32((v));				\
+	(s)->s_blocks_count_hi = cpu_to_le32(((__u64)(v)) >> 32);	\
+} while (0)
+
+#define EXT3_R_BLOCKS_COUNT(s)	\
+	(ext3_fsblk_t)(((__u64)le32_to_cpu((s)->s_r_blocks_count_hi) << 32) |	\
+		 (__u64)le32_to_cpu((s)->s_r_blocks_count))
+#define EXT3_R_BLOCKS_COUNT_SET(s,v)	do {				\
+	(s)->s_r_blocks_count = cpu_to_le32((v));			\
+	(s)->s_r_blocks_count_hi = cpu_to_le32(((__u64)(v)) >> 32);	\
+} while (0)
+
+#define EXT3_FREE_BLOCKS_COUNT(s)					\
+	(ext3_fsblk_t)(((__u64)le32_to_cpu((s)->s_free_blocks_count_hi) << 32) | \
+		 (__u64)le32_to_cpu((s)->s_free_blocks_count))
+#define EXT3_FREE_BLOCKS_COUNT_SET(s,v)	do {				\
+	(s)->s_free_blocks_count = cpu_to_le32((v));			\
+	(s)->s_free_blocks_count_hi = cpu_to_le32(((__u64)(v)) >> 32);	\
+} while (0)
+
 #ifdef __KERNEL__
 static inline struct ext3_sb_info * EXT3_SB(struct super_block *sb)
 {
@@ -559,6 +636,7 @@
 #define EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER	0x0001
 #define EXT3_FEATURE_RO_COMPAT_LARGE_FILE	0x0002
 #define EXT3_FEATURE_RO_COMPAT_BTREE_DIR	0x0004
+#define EXT3_FEATURE_RO_COMPAT_64BIT		0x0010
 
 #define EXT3_FEATURE_INCOMPAT_COMPRESSION	0x0001
 #define EXT3_FEATURE_INCOMPAT_FILETYPE		0x0002
@@ -572,7 +650,8 @@
 					 EXT3_FEATURE_INCOMPAT_META_BG)
 #define EXT3_FEATURE_RO_COMPAT_SUPP	(EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \
 					 EXT3_FEATURE_RO_COMPAT_LARGE_FILE| \
-					 EXT3_FEATURE_RO_COMPAT_BTREE_DIR)
+					 EXT3_FEATURE_RO_COMPAT_BTREE_DIR| \
+					 EXT3_FEATURE_RO_COMPAT_64BIT)
 
 /*
  * Default values for user and/or group using reserved blocks
signature.asc (application/pgp-signature, 189 B)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.7 (GNU/Linux)

iD8DBQFEczTN9Kffa9pFVzwRAhWaAJ9d6evrF87yMafIPSAJbEw7iVacfQCfbc70
tE0YtTFwViBWM1TnbaT0cq0=
=wiBw
-----END PGP SIGNATURE-----
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.