lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date:	Wed, 20 Aug 2008 12:34:19 -0500
From:	"Jose R. Santos" <jrs@...ibm.com>
To:	"Theodore Ts'o" <tytso@....edu>, linux-ext4@...r.kernel.org
Subject: [PATCH 15/15][e2fsprogs] 64-bit mke2fs cleanup

From: Jose R. Santos <jrs@...ibm.com>

64-bit mke2fs cleanup

Use 64-bit interfaces in mke2fs.  This should be most most of whats
needed to support creating a 64-bit filesystem.  Things missing:

- 64-bit bitmap support being developed by Ted.  We cant make a 64bit
  fs without this.

- 64-bit badblock interface.  Waiting on Ted 64-bit bitmap patches to
  shamelessly steel some of his code. (particularly, the handling of
  different interface through the structure magic numbers)

  This is not needed to create a 64-bit filesystem, but you cant have
  bad blocks above the 32bit block number boundary.

- lost+found and journal file are not created as extent mapped files.
  Should not prevent from creating a 64-bit filesystem and since those
  are typically at the beginning of the disk, don't know if I should
  really care.  Don't know much about the extent format to know for sure.

Signed-off-by: Jose R. Santos <jrs@...ibm.com>
--

 lib/ext2fs/alloc_tables.c |   81 +++++++++++----------
 lib/ext2fs/ext2fs.h       |    6 +-
 lib/ext2fs/initialize.c   |   44 +++++++----
 misc/mke2fs.c             |  177 ++++++++++++++++++++++++---------------------
 misc/util.c               |    4 +
 5 files changed, 173 insertions(+), 139 deletions(-)

diff --git a/lib/ext2fs/alloc_tables.c b/lib/ext2fs/alloc_tables.c
index 8c0ecfc..c5d3a28 100644
--- a/lib/ext2fs/alloc_tables.c
+++ b/lib/ext2fs/alloc_tables.c
@@ -33,11 +33,11 @@
  * block number with a correct offset were the bitmaps and inode
  * tables can be allocated continously and in order.
  */
-static blk_t flexbg_offset(ext2_filsys fs, dgrp_t group, blk_t start_blk,
+static blk64_t flexbg_offset(ext2_filsys fs, dgrp_t group, blk_t start_blk,
 			   ext2fs_block_bitmap bmap, int offset, int size)
 {
 	int		flexbg, flexbg_size, elem_size;
-	blk_t		last_blk, first_free = 0;
+	blk64_t		last_blk, first_free = 0;
 	dgrp_t	       	last_grp;
 
 	flexbg_size = 1 << fs->super->s_log_groups_per_flex;
@@ -63,18 +63,18 @@ static blk_t flexbg_offset(ext2_filsys fs, dgrp_t group, blk_t start_blk,
 			return start_blk + elem_size;
 	}
 
-	start_blk = ext2fs_group_first_block(fs, flexbg_size * flexbg);
+	start_blk = ext2fs_group_first_block2(fs, flexbg_size * flexbg);
 	last_grp = group | (flexbg_size - 1);
 	if (last_grp > fs->group_desc_count)
 		last_grp = fs->group_desc_count;
-	last_blk = ext2fs_group_last_block(fs, last_grp);
+	last_blk = ext2fs_group_last_block2(fs, last_grp);
 
 	/* Find the first available block */
-	if (ext2fs_get_free_blocks(fs, start_blk, last_blk, 1, bmap,
+	if (ext2fs_get_free_blocks2(fs, start_blk, last_blk, 1, bmap,
 				   &first_free))
 		return first_free;
 
-	if (ext2fs_get_free_blocks(fs, first_free + offset, last_blk, size,
+	if (ext2fs_get_free_blocks2(fs, first_free + offset, last_blk, size,
 				   bmap, &first_free))
 		return first_free;
 
@@ -85,12 +85,12 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
 				      ext2fs_block_bitmap bmap)
 {
 	errcode_t	retval;
-	blk_t		group_blk, start_blk, last_blk, new_blk, blk;
+	blk64_t		group_blk, start_blk, last_blk, new_blk, blk;
 	dgrp_t		last_grp = 0;
 	int		j, rem_grps = 0, flexbg_size = 0;
 
-	group_blk = ext2fs_group_first_block(fs, group);
-	last_blk = ext2fs_group_last_block(fs, group);
+	group_blk = ext2fs_group_first_block2(fs, group);
+	last_blk = ext2fs_group_last_block2(fs, group);
 
 	if (!bmap)
 		bmap = fs->block_map;
@@ -109,8 +109,8 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
 	 * Allocate the block and inode bitmaps, if necessary
 	 */
 	if (fs->stride) {
-		retval = ext2fs_get_free_blocks(fs, group_blk, last_blk,
-						1, bmap, &start_blk);
+		retval = ext2fs_get_free_blocks2(fs, group_blk, last_blk,
+						 1, bmap, &start_blk);
 		if (retval)
 			return retval;
 		start_blk += fs->inode_blocks_per_group;
@@ -123,27 +123,28 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
 
 	if (flexbg_size) {
 		int prev_block = 0;
-		if (group && fs->group_desc[group-1].bg_block_bitmap)
-			prev_block = fs->group_desc[group-1].bg_block_bitmap;
+		if (group && ext2fs_block_bitmap_loc(fs, group - 1))
+			prev_block = ext2fs_block_bitmap_loc(fs, group - 1);
 		start_blk = flexbg_offset(fs, group, prev_block, bmap,
 						 0, rem_grps);
-		last_blk = ext2fs_group_last_block(fs, last_grp);
+		last_blk = ext2fs_group_last_block2(fs, last_grp);
 	}
 
-	if (!fs->group_desc[group].bg_block_bitmap) {
-		retval = ext2fs_get_free_blocks(fs, start_blk, last_blk,
-						1, bmap, &new_blk);
+	if (!ext2fs_block_bitmap_loc(fs, group)) {
+		retval = ext2fs_get_free_blocks2(fs, start_blk, last_blk,
+						 1, bmap, &new_blk);
 		if (retval == EXT2_ET_BLOCK_ALLOC_FAIL) 
-			retval = ext2fs_get_free_blocks(fs, group_blk,
+			retval = ext2fs_get_free_blocks2(fs, group_blk,
 					last_blk, 1, bmap, &new_blk);
 		if (retval)
 			return retval;
+		/* FIXME-64 */
 		ext2fs_mark_block_bitmap(bmap, new_blk);
-		fs->group_desc[group].bg_block_bitmap = new_blk;
+		ext2fs_block_bitmap_loc_set(fs, group, new_blk);
 		if (flexbg_size) {
-			dgrp_t gr = ext2fs_group_of_blk(fs, new_blk);
+			dgrp_t gr = ext2fs_group_of_blk2(fs, new_blk);
 			fs->group_desc[gr].bg_free_blocks_count--;
-			fs->super->s_free_blocks_count--;
+			ext2fs_free_blocks_count_add(fs->super, -1);
 			fs->group_desc[gr].bg_flags &= ~EXT2_BG_BLOCK_UNINIT;
 			ext2fs_group_desc_csum_set(fs, gr);
 		}
@@ -151,27 +152,28 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
 
 	if (flexbg_size) {
 		int prev_block = 0;
-		if (group && fs->group_desc[group-1].bg_inode_bitmap)
-			prev_block = fs->group_desc[group-1].bg_inode_bitmap;
+		if (group && ext2fs_inode_bitmap_loc(fs, group - 1))
+			prev_block = ext2fs_inode_bitmap_loc(fs, group - 1);
 		start_blk = flexbg_offset(fs, group, prev_block, bmap,
 						 flexbg_size, rem_grps);
-		last_blk = ext2fs_group_last_block(fs, last_grp);
+		last_blk = ext2fs_group_last_block2(fs, last_grp);
 	}
 
-	if (!fs->group_desc[group].bg_inode_bitmap) {
-		retval = ext2fs_get_free_blocks(fs, start_blk, last_blk,
-						1, bmap, &new_blk);
+	if (!ext2fs_inode_bitmap_loc(fs, group)) {
+		retval = ext2fs_get_free_blocks2(fs, start_blk, last_blk,
+						 1, bmap, &new_blk);
 		if (retval == EXT2_ET_BLOCK_ALLOC_FAIL) 
-			retval = ext2fs_get_free_blocks(fs, group_blk,
+			retval = ext2fs_get_free_blocks2(fs, group_blk,
 					last_blk, 1, bmap, &new_blk);
 		if (retval)
 			return retval;
+		/* FIXME-64 */
 		ext2fs_mark_block_bitmap(bmap, new_blk);
-		fs->group_desc[group].bg_inode_bitmap = new_blk;
+		ext2fs_inode_bitmap_loc_set(fs, group, new_blk);
 		if (flexbg_size) {
-			dgrp_t gr = ext2fs_group_of_blk(fs, new_blk);
+			dgrp_t gr = ext2fs_group_of_blk2(fs, new_blk);
 			fs->group_desc[gr].bg_free_blocks_count--;
-			fs->super->s_free_blocks_count--;
+			ext2fs_free_blocks_count_add(fs->super, -1);
 			fs->group_desc[gr].bg_flags &= ~EXT2_BG_BLOCK_UNINIT;
 			ext2fs_group_desc_csum_set(fs, gr);
 		}
@@ -182,17 +184,17 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
 	 */
 	if (flexbg_size) {
 		int prev_block = 0;
-		if (group && fs->group_desc[group-1].bg_inode_table)
-			prev_block = fs->group_desc[group-1].bg_inode_table;
+		if (group && ext2fs_inode_table_loc(fs, group - 1))
+			prev_block = ext2fs_inode_table_loc(fs, group - 1);
 		group_blk = flexbg_offset(fs, group, prev_block, bmap,
 						 flexbg_size * 2,
 						 fs->inode_blocks_per_group *
 						 rem_grps);
-		last_blk = ext2fs_group_last_block(fs, last_grp);
+		last_blk = ext2fs_group_last_block2(fs, last_grp);
 	}
 
-	if (!fs->group_desc[group].bg_inode_table) {
-		retval = ext2fs_get_free_blocks(fs, group_blk, last_blk,
+	if (!ext2fs_inode_table_loc(fs, group)) {
+		retval = ext2fs_get_free_blocks2(fs, group_blk, last_blk,
 						fs->inode_blocks_per_group,
 						bmap, &new_blk);
 		if (retval)
@@ -200,16 +202,17 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
 		for (j=0, blk = new_blk;
 		     j < fs->inode_blocks_per_group;
 		     j++, blk++) {
+			/* FIXME-64 */
 			ext2fs_mark_block_bitmap(bmap, blk);
 			if (flexbg_size) {
-				dgrp_t gr = ext2fs_group_of_blk(fs, blk);
+				dgrp_t gr = ext2fs_group_of_blk2(fs, blk);
 				fs->group_desc[gr].bg_free_blocks_count--;
-				fs->super->s_free_blocks_count--;
+				ext2fs_free_blocks_count_add(fs->super, -1);
 				fs->group_desc[gr].bg_flags &= ~EXT2_BG_BLOCK_UNINIT;
 				ext2fs_group_desc_csum_set(fs, gr);
 			}
 		}
-		fs->group_desc[group].bg_inode_table = new_blk;
+		ext2fs_inode_table_loc_set(fs, group, new_blk);
 	}
 	ext2fs_group_desc_csum_set(fs, group);
 	return 0;
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index 8985419..773b2d1 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -523,14 +523,16 @@ typedef struct ext2_icount *ext2_icount_t;
 					 EXT2_FEATURE_INCOMPAT_META_BG|\
 					 EXT3_FEATURE_INCOMPAT_RECOVER|\
 					 EXT3_FEATURE_INCOMPAT_EXTENTS|\
-					 EXT4_FEATURE_INCOMPAT_FLEX_BG)
+					 EXT4_FEATURE_INCOMPAT_FLEX_BG|\
+					 EXT4_FEATURE_INCOMPAT_64BIT)
 #else
 #define EXT2_LIB_FEATURE_INCOMPAT_SUPP	(EXT2_FEATURE_INCOMPAT_FILETYPE|\
 					 EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|\
 					 EXT2_FEATURE_INCOMPAT_META_BG|\
 					 EXT3_FEATURE_INCOMPAT_RECOVER|\
 					 EXT3_FEATURE_INCOMPAT_EXTENTS|\
-					 EXT4_FEATURE_INCOMPAT_FLEX_BG)
+					 EXT4_FEATURE_INCOMPAT_FLEX_BG|\
+					 EXT4_FEATURE_INCOMPAT_64BIT)
 #endif
 #define EXT2_LIB_FEATURE_RO_COMPAT_SUPP	(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
 					 EXT4_FEATURE_RO_COMPAT_HUGE_FILE|\
diff --git a/lib/ext2fs/initialize.c b/lib/ext2fs/initialize.c
index e9bfe49..93b3328 100644
--- a/lib/ext2fs/initialize.c
+++ b/lib/ext2fs/initialize.c
@@ -75,8 +75,8 @@ static unsigned int calc_reserved_gdt_blocks(ext2_filsys fs)
 	/* 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 (ext2fs_blocks_count(sb) < max_blocks / 1024)
+		max_blocks = ext2fs_blocks_count(sb) * 1024;
 	rsv_groups = ext2fs_div_ceil(max_blocks - sb->s_first_data_block, bpg);
 	rsv_gdb = ext2fs_div_ceil(rsv_groups, gdpb) - fs->desc_blocks;
 	if (rsv_gdb > EXT2_ADDR_PER_BLOCK(sb))
@@ -108,7 +108,7 @@ errcode_t ext2fs_initialize(const char *name, int flags,
 	char		*buf = 0;
 	char		c;
 
-	if (!param || !param->s_blocks_count)
+	if (!param || !ext2fs_blocks_count(param))
 		return EXT2_ET_INVALID_ARGUMENT;
 	
 	retval = ext2fs_get_mem(sizeof(struct struct_ext2_filsys), &fs);
@@ -200,9 +200,9 @@ errcode_t ext2fs_initialize(const char *name, int flags,
 		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) {
+	ext2fs_blocks_count_set(super, ext2fs_blocks_count(param));
+	ext2fs_r_blocks_count_set(super, ext2fs_r_blocks_count(param));
+	if (ext2fs_r_blocks_count(super) >= ext2fs_blocks_count(param)) {
 		retval = EXT2_ET_INVALID_ARGUMENT;
 		goto cleanup;
 	}
@@ -219,18 +219,27 @@ errcode_t ext2fs_initialize(const char *name, int flags,
 	}
 
 retry:
-	fs->group_desc_count = ext2fs_div_ceil(super->s_blocks_count -
-					       super->s_first_data_block,
-					       EXT2_BLOCKS_PER_GROUP(super));
+	fs->group_desc_count = (blk_t) ext2fs_div64_ceil(
+		ext2fs_blocks_count(super) - super->s_first_data_block,
+		EXT2_BLOCKS_PER_GROUP(super));
 	if (fs->group_desc_count == 0) {
 		retval = EXT2_ET_TOOSMALL;
 		goto cleanup;
 	}
+
+	if (super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
+		super->s_desc_size = EXT2_MIN_DESC_SIZE_64BIT;
+
 	fs->desc_blocks = ext2fs_div_ceil(fs->group_desc_count,
 					  EXT2_DESC_PER_BLOCK(super));
 
 	i = fs->blocksize >= 4096 ? 1 : 4096 / fs->blocksize;
-	set_field(s_inodes_count, super->s_blocks_count / i);
+
+	if (super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT &&
+	    (ext2fs_blocks_count(super) / i) > (1ULL << 32))
+		set_field(s_inodes_count, ~0U);
+	else
+		set_field(s_inodes_count, ext2fs_blocks_count(super) / i);
 
 	/*
 	 * Make sure we have at least EXT2_FIRST_INO + 1 inodes, so
@@ -250,7 +259,8 @@ retry:
 		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;
+			ext2fs_blocks_count_set(super,
+						ext2fs_blocks_count(param));
 			super->s_frags_per_group = super->s_blocks_per_group *
 				frags_per_block;
 			goto retry;
@@ -334,12 +344,14 @@ ipg_retry:
 	overhead = (int) (2 + fs->inode_blocks_per_group);
 	if (ext2fs_bg_has_super(fs, fs->group_desc_count - 1))
 		overhead += 1 + fs->desc_blocks + super->s_reserved_gdt_blocks;
-	rem = ((super->s_blocks_count - super->s_first_data_block) %
+	rem = ((ext2fs_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;
+		ext2fs_blocks_count_set(super, ext2fs_blocks_count(super) +
+					rem);
+
 		goto retry;
 	}
 
@@ -383,7 +395,7 @@ ipg_retry:
 	 * superblock and group descriptors (the inode tables and
 	 * bitmaps will be accounted for when allocated).
 	 */
-	super->s_free_blocks_count = 0;
+	ext2fs_free_blocks_count_set(super, 0);
 	csum_flag = EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
 					       EXT4_FEATURE_RO_COMPAT_GDT_CSUM);
 	for (i = 0; i < fs->group_desc_count; i++) {
@@ -405,7 +417,9 @@ ipg_retry:
 		if (fs->super->s_log_groups_per_flex)
 			numblocks += 2 + fs->inode_blocks_per_group;
 
-		super->s_free_blocks_count += numblocks;
+		ext2fs_free_blocks_count_set(super,
+					     ext2fs_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;
diff --git a/misc/mke2fs.c b/misc/mke2fs.c
index 7171990..de4d0a5 100644
--- a/misc/mke2fs.c
+++ b/misc/mke2fs.c
@@ -348,7 +348,7 @@ static void progress_close(struct progress_struct *progress)
 static void write_inode_tables(ext2_filsys fs, int lazy_flag)
 {
 	errcode_t	retval;
-	blk_t		blk;
+	blk64_t		blk;
 	dgrp_t		i;
 	int		num, ipb;
 	struct progress_struct progress;
@@ -362,7 +362,7 @@ static void write_inode_tables(ext2_filsys fs, int lazy_flag)
 	for (i = 0; i < fs->group_desc_count; i++) {
 		progress_update(&progress, i);
 		
-		blk = fs->group_desc[i].bg_inode_table;
+		blk = ext2fs_inode_table_loc(fs, i);
 		num = fs->inode_blocks_per_group;
 
 		if (lazy_flag) {
@@ -377,10 +377,10 @@ static void write_inode_tables(ext2_filsys fs, int lazy_flag)
 			fs->group_desc[i].bg_flags |= EXT2_BG_INODE_ZEROED;
 			ext2fs_group_desc_csum_set(fs, i);
 		}
-		retval = ext2fs_zero_blocks(fs, blk, num, &blk, &num);
+		retval = ext2fs_zero_blocks2(fs, blk, num, &blk, &num);
 		if (retval) {
 			fprintf(stderr, _("\nCould not write %d "
-				  "blocks in inode table starting at %u: %s\n"),
+				  "blocks in inode table starting at %ull: %s\n"),
 				num, blk, error_message(retval));
 			exit(1);
 		}
@@ -391,7 +391,7 @@ static void write_inode_tables(ext2_filsys fs, int lazy_flag)
 				sync();
 		}
 	}
-	ext2fs_zero_blocks(0, 0, 0, 0, 0);
+	ext2fs_zero_blocks2(0, 0, 0, 0, 0);
 	progress_close(&progress);
 }
 
@@ -511,7 +511,7 @@ static void zap_sector(ext2_filsys fs, int sect, int nsect)
 
 	if (sect == 0) {
 		/* Check for a BSD disklabel, and don't erase it if so */
-		retval = io_channel_read_blk(fs->io, 0, -512, buf);
+		retval = io_channel_read_blk64(fs->io, 0, -512, buf);
 		if (retval)
 			fprintf(stderr,
 				_("Warning: could not read block 0: %s\n"),
@@ -596,9 +596,9 @@ static void show_stats(ext2_filsys fs)
 	dgrp_t			i;
 	int			need, col_left;
 	
-	if (fs_param.s_blocks_count != s->s_blocks_count)
+	if (ext2fs_blocks_count(&fs_param) != ext2fs_blocks_count(s))
 		fprintf(stderr, _("warning: %u blocks unused.\n\n"),
-		       fs_param.s_blocks_count - s->s_blocks_count);
+		       ext2fs_blocks_count(&fs_param) - ext2fs_blocks_count(s));
 
 	memset(buf, 0, sizeof(buf));
 	strncpy(buf, s->s_volume_name, sizeof(s->s_volume_name));
@@ -612,11 +612,11 @@ static void show_stats(ext2_filsys fs)
 		s->s_log_block_size);
 	printf(_("Fragment size=%u (log=%u)\n"), fs->fragsize,
 		s->s_log_frag_size);
-	printf(_("%u inodes, %u blocks\n"), s->s_inodes_count,
-	       s->s_blocks_count);
-	printf(_("%u 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,
+	       ext2fs_blocks_count(s));
+	printf(_("%llu blocks (%2.2f%%) reserved for the super user\n"),
+		ext2fs_r_blocks_count(s),
+	       100.0 *  ext2fs_r_blocks_count(s) / ext2fs_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"),
@@ -756,7 +756,7 @@ static void parse_extended_opts(struct ext2_super_block *param,
 				r_usage++;
 				continue;
 			}
-			if (resize <= param->s_blocks_count) {
+			if (resize <= ext2fs_blocks_count(param)) {
 				fprintf(stderr, 
 					_("The resize maximum must be greater "
 					  "than the filesystem size.\n"));
@@ -769,8 +769,8 @@ static void parse_extended_opts(struct ext2_super_block *param,
 			if (!bpg)
 				bpg = blocksize * 8;
 			gdpb = EXT2_DESC_PER_BLOCK(param);
-			group_desc_count = 
-				ext2fs_div_ceil(param->s_blocks_count, bpg);
+			group_desc_count = (__u32) ext2fs_div64_ceil(
+				ext2fs_blocks_count(param), bpg);
 			desc_blocks = (group_desc_count +
 				       gdpb - 1) / gdpb;
 			rsv_groups = ext2fs_div_ceil(resize, bpg);
@@ -838,7 +838,8 @@ static __u32 ok_features[3] = {
 		EXT3_FEATURE_INCOMPAT_EXTENTS|
 		EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|
 		EXT2_FEATURE_INCOMPAT_META_BG|
-		EXT4_FEATURE_INCOMPAT_FLEX_BG,
+		EXT4_FEATURE_INCOMPAT_FLEX_BG|
+		EXT4_FEATURE_INCOMPAT_64BIT,
 	/* R/O compat */
 	EXT2_FEATURE_RO_COMPAT_LARGE_FILE|
 		EXT4_FEATURE_RO_COMPAT_HUGE_FILE|
@@ -969,9 +970,9 @@ static char **parse_fs_type(const char *fs_type,
 	}
 
 	meg = (1024 * 1024) / EXT2_BLOCK_SIZE(fs_param);
-	if (fs_param->s_blocks_count < 3 * meg)
+	if (ext2fs_blocks_count(fs_param) < 3 * meg)
 		size_type = "floppy";
-	else if (fs_param->s_blocks_count < 512 * meg)
+	else if (ext2fs_blocks_count(fs_param) < 512 * meg)
 		size_type = "small";
 	else
 		size_type = "default";
@@ -1074,7 +1075,7 @@ static void PRS(int argc, char *argv[])
 	char *		extended_opts = 0;
 	const char *	fs_type = 0;
 	const char *	usage_types = 0;
-	blk_t		dev_size;
+	blk64_t		dev_size;
 #ifdef __linux__
 	struct 		utsname ut;
 #endif
@@ -1385,9 +1386,9 @@ static void PRS(int argc, char *argv[])
 			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) {
+		ext2fs_blocks_count_set(&fs_param, parse_num_blocks(argv[optind++],
+				fs_param.s_log_block_size));
+		if (!ext2fs_blocks_count(&fs_param)) {
 			com_err(program_name, 0, _("invalid blocks count - %s"),
 				argv[optind - 1]);
 			exit(1);
@@ -1402,14 +1403,50 @@ static void PRS(int argc, char *argv[])
 
 	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;
+	fs_types = parse_fs_type(fs_type, usage_types, &fs_param, argv[0]);
+	if (!fs_types) {
+		fprintf(stderr, _("Failed to parse fs types list\n"));
+		exit(1);
+	}
+
+	/* Figure out what features should be enabled */
+
+	tmp = NULL;
+	if (fs_param.s_rev_level != EXT2_GOOD_OLD_REV) {
+		tmp = get_string_from_profile(fs_types, "base_features",
+		      "sparse_super,filetype,resize_inode,dir_index");
+		edit_feature(tmp, &fs_param.s_feature_compat);
+		free(tmp);
+
+		for (cpp = fs_types; *cpp; cpp++) {
+			tmp = NULL;
+			profile_get_string(profile, "fs_types", *cpp,
+					   "features", "", &tmp);
+			if (tmp && *tmp)
+				edit_feature(tmp, &fs_param.s_feature_compat);
+			if (tmp)
+				free(tmp);
+		}
+		tmp = get_string_from_profile(fs_types, "default_features",
+					      "");
+	}
+	edit_feature(fs_features ? fs_features : tmp,
+		     &fs_param.s_feature_compat);
+	if (tmp)
+		free(tmp);
+
+	if (noaction && ext2fs_blocks_count(&fs_param)) {
+		dev_size = ext2fs_blocks_count(&fs_param);
 		retval = 0;
 	} else {
 	retry:
-		retval = ext2fs_get_device_size(device_name,
-						EXT2_BLOCK_SIZE(&fs_param),
-						&dev_size);
+		retval = ext2fs_get_device_size2(device_name,
+						 EXT2_BLOCK_SIZE(&fs_param),
+						 &dev_size);
+		if (!(fs_param.s_feature_incompat &
+		      EXT4_FEATURE_INCOMPAT_64BIT) && dev_size >= (1ULL << 32))
+			retval = EFBIG;
+
 		if ((retval == EFBIG) &&
 		    (blocksize == 0) && 
 		    (fs_param.s_log_block_size == 0)) {
@@ -1431,7 +1468,7 @@ static void PRS(int argc, char *argv[])
 			_("while trying to determine filesystem size"));
 		exit(1);
 	}
-	if (!fs_param.s_blocks_count) {
+	if (!ext2fs_blocks_count(&fs_param)) {
 		if (retval == EXT2_ET_UNIMPLEMENTED) {
 			com_err(program_name, 0,
 				_("Couldn't determine device size; you "
@@ -1451,50 +1488,21 @@ static void PRS(int argc, char *argv[])
 				  ));
 				exit(1);
 			}
-			fs_param.s_blocks_count = 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);
+			ext2fs_blocks_count_set(&fs_param, dev_size);
+			if (sys_page_size > EXT2_BLOCK_SIZE(&fs_param)) {
+				blk64_t tmp = ext2fs_blocks_count(&fs_param);
+				tmp &= ~((sys_page_size /
+					  EXT2_BLOCK_SIZE(&fs_param))-1);
+				ext2fs_blocks_count_set(&fs_param, tmp);
+			}
 		}
 		
-	} else if (!force && (fs_param.s_blocks_count > dev_size)) {
+	} else if (!force && (ext2fs_blocks_count(&fs_param) > dev_size)) {
 		com_err(program_name, 0,
 			_("Filesystem larger than apparent device size."));
 		proceed_question();
 	}
 
-	fs_types = parse_fs_type(fs_type, usage_types, &fs_param, argv[0]);
-	if (!fs_types) {
-		fprintf(stderr, _("Failed to parse fs types list\n"));
-		exit(1);
-	}
-
-	/* Figure out what features should be enabled */
-
-	tmp = NULL;
-	if (fs_param.s_rev_level != EXT2_GOOD_OLD_REV) {
-		tmp = get_string_from_profile(fs_types, "base_features",
-		      "sparse_super,filetype,resize_inode,dir_index");
-		edit_feature(tmp, &fs_param.s_feature_compat);
-		free(tmp);
-
-		for (cpp = fs_types; *cpp; cpp++) {
-			tmp = NULL;
-			profile_get_string(profile, "fs_types", *cpp,
-					   "features", "", &tmp);
-			if (tmp && *tmp)
-				edit_feature(tmp, &fs_param.s_feature_compat);
-			if (tmp)
-				free(tmp);
-		}
-		tmp = get_string_from_profile(fs_types, "default_features",
-					      "");
-	}
-	edit_feature(fs_features ? fs_features : tmp,
-		     &fs_param.s_feature_compat);
-	if (tmp)
-		free(tmp);
-
 	if (fs_param.s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) {
 		fs_types[0] = strdup("journal");
 		fs_types[1] = 0;
@@ -1583,7 +1591,9 @@ static void PRS(int argc, char *argv[])
 		if ((blocksize < 0) && (use_bsize < (-blocksize)))
 			use_bsize = -blocksize;
 		blocksize = use_bsize;
-		fs_param.s_blocks_count /= blocksize / 1024;
+		ext2fs_blocks_count_set(&fs_param,
+					ext2fs_blocks_count(&fs_param) /
+					(blocksize / 1024));
 	}
 
 	if (inode_ratio == 0) {
@@ -1667,11 +1677,17 @@ static void PRS(int argc, char *argv[])
 	/* Make sure number of inodes specified will fit in 32 bits */
 	if (num_inodes == 0) {
 		unsigned long long n;
-		n = (unsigned long long) fs_param.s_blocks_count * blocksize / inode_ratio;
+		n = ext2fs_blocks_count(&fs_param) * blocksize / inode_ratio;
 		if (n > ~0U) {
-			com_err(program_name, 0,
-			    _("too many inodes (%llu), raise inode ratio?"), n);
-			exit(1);
+			if (fs_param.s_feature_incompat &
+			    EXT4_FEATURE_INCOMPAT_64BIT)
+				num_inodes = ~0U;
+			else {
+				com_err(program_name, 0,
+					_("too many inodes (%llu), raise"
+					  "inode ratio?"), n);
+				exit(1);
+			}
 		}
 	} else if (num_inodes > ~0U) {
 		com_err(program_name, 0,
@@ -1683,29 +1699,28 @@ static void PRS(int argc, char *argv[])
 	 * 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)
-			/ inode_ratio;
+		(ext2fs_blocks_count(&fs_param) * blocksize) / inode_ratio;
 
 	if ((((long long)fs_param.s_inodes_count) *
 	     (inode_size ? inode_size : EXT2_GOOD_OLD_INODE_SIZE)) >=
-	    (((long long)fs_param.s_blocks_count) * 
+	    ((ext2fs_blocks_count(&fs_param)) *
 	     EXT2_BLOCK_SIZE(&fs_param))) {
 		com_err(program_name, 0, _("inode_size (%u) * inodes_count "
 					  "(%u) too big for a\n\t"
-					  "filesystem with %lu blocks, "
+					  "filesystem with %llu blocks, "
 					  "specify higher inode_ratio (-i)\n\t"
 					  "or lower inode count (-N).\n"),
 			inode_size ? inode_size : EXT2_GOOD_OLD_INODE_SIZE,
 			fs_param.s_inodes_count, 
-			(unsigned long) fs_param.s_blocks_count);
+			(unsigned long long) ext2fs_blocks_count(&fs_param));
 		exit(1);
 	}
 
 	/*
 	 * Calculate number of blocks to reserve
 	 */
-	fs_param.s_r_blocks_count = (unsigned int) (reserved_ratio *
-					fs_param.s_blocks_count / 100.0);
+	ext2fs_r_blocks_count_set(&fs_param, reserved_ratio *
+				  ext2fs_blocks_count(&fs_param) / 100.0);
 }
 
 static int should_do_undo(const char *name)
@@ -1945,9 +1960,9 @@ int main (int argc, char *argv[])
 	} 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 long blocks = ext2fs_blocks_count(fs->super);
 		unsigned long start;
-		blk_t ret_blk;
+		blk64_t ret_blk;
 
 #ifdef ZAP_BOOTBLOCK
 		zap_sector(fs, 0, 2);
@@ -1962,7 +1977,7 @@ int main (int argc, char *argv[])
 		if (start > rsv)
 			start -= rsv;
 		if (start > 0)
-			retval = ext2fs_zero_blocks(fs, start, blocks - start,
+			retval = ext2fs_zero_blocks2(fs, start, blocks - start,
 						    &ret_blk, NULL);
 
 		if (retval) {
diff --git a/misc/util.c b/misc/util.c
index 7c99a2a..915d7b6 100644
--- a/misc/util.c
+++ b/misc/util.c
@@ -253,7 +253,7 @@ unsigned int figure_journal_size(int size, ext2_filsys fs)
 {
 	int j_blocks;
 
-	j_blocks = ext2fs_default_journal_size(fs->super->s_blocks_count);
+	j_blocks = ext2fs_default_journal_size(ext2fs_blocks_count(fs->super));
 	if (j_blocks < 0) {
 		fputs(_("\nFilesystem too small for a journal\n"), stderr);
 		return 0;
@@ -269,7 +269,7 @@ unsigned int figure_journal_size(int size, ext2_filsys fs)
 				j_blocks);
 			exit(1);
 		}
-		if ((unsigned) j_blocks > fs->super->s_free_blocks_count / 2) {
+		if ((unsigned) j_blocks > ext2fs_free_blocks_count(fs->super) / 2) {
 			fputs(_("\nJournal size too big for filesystem.\n"),
 			      stderr);
 			exit(1);

--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists