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  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20180504070923.45140-7-c17828@cray.com>
Date:   Fri,  4 May 2018 10:09:22 +0300
From:   c17828 <artem.blagodarenko@...il.com>
To:     linux-ext4@...r.kernel.org
Cc:     adilger.kernel@...ger.ca,
        Artem Blagodarenko <artem.blagodarenko@...il.com>
Subject: [PATCH v4 6/7] ext2fs: add EXT4_FEATURE_INCOMPAT_64INODE support

From: Artem Blagodarenko <artem.blagodarenko@...il.com>

Inodes count and free inodes count should be 64 bit long.
This patch also changes s_inodes_count* to 64 bit

Lustre-bug: https://jira.hpdd.intel.com/browse/LU-9309
Signed-off-by: Artem Blagodarenko <artem.blagodarenko@...il.com>
---
 debugfs/debugfs.c           |  2 +-
 debugfs/set_fields.c        |  3 ++-
 e2fsck/dirinfo.c            | 28 ++++++++++++++--------------
 e2fsck/e2fsck.h             | 22 +++++++++++-----------
 e2fsck/pass2.c              | 11 ++++++++---
 e2fsck/pass3.c              |  2 +-
 e2fsck/problem.c            |  5 +++++
 e2fsck/problem.h            |  5 ++++-
 e2fsck/super.c              |  1 +
 lib/e2p/feature.c           |  2 ++
 lib/ext2fs/ext2_fs.h        | 15 +++++++++++++--
 lib/ext2fs/ext2fs.h         | 14 ++++++++++----
 lib/ext2fs/swapfs.c         |  6 ++++++
 lib/ext2fs/tst_super_size.c |  8 +++++++-
 misc/fuse2fs.c              |  8 ++++----
 misc/mke2fs.c               | 22 ++++++++++++++--------
 misc/tune2fs.c              |  3 ++-
 17 files changed, 105 insertions(+), 52 deletions(-)

diff --git a/debugfs/debugfs.c b/debugfs/debugfs.c
index 4a533b53..a80cf668 100644
--- a/debugfs/debugfs.c
+++ b/debugfs/debugfs.c
@@ -829,7 +829,7 @@ void internal_dump_inode(FILE *out, const char *prefix,
 	else if (LINUX_S_ISFIFO(inode->i_mode)) i_type = "FIFO";
 	else if (LINUX_S_ISSOCK(inode->i_mode)) i_type = "socket";
 	else i_type = "bad type";
-	fprintf(out, "%sInode: %u   Type: %s    ", prefix, inode_num, i_type);
+	fprintf(out, "%sInode: %lu   Type: %s    ", prefix, inode_num, i_type);
 	fprintf(out, "%sMode:  0%03o   Flags: 0x%x\n",
 		prefix, inode->i_mode & 07777, inode->i_flags);
 	if (is_large_inode && large_inode->i_extra_isize >= 24) {
diff --git a/debugfs/set_fields.c b/debugfs/set_fields.c
index 8dfbba9c..bfab7ff8 100644
--- a/debugfs/set_fields.c
+++ b/debugfs/set_fields.c
@@ -79,7 +79,8 @@ static errcode_t parse_mmp_clear(struct field_set_info *info, char *field,
 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
 
 static struct field_set_info super_fields[] = {
-	{ "inodes_count", &set_sb.s_inodes_count, NULL, 4, parse_uint },
+	{ "inodes_count", &set_sb.s_inodes_count, &set_sb.s_inodes_count_hi,
+		4, parse_uint },
 	{ "blocks_count", &set_sb.s_blocks_count, &set_sb.s_blocks_count_hi,
 		4, parse_uint },
 	{ "r_blocks_count", &set_sb.s_r_blocks_count,
diff --git a/e2fsck/dirinfo.c b/e2fsck/dirinfo.c
index b29f7e92..e8f1f26d 100644
--- a/e2fsck/dirinfo.c
+++ b/e2fsck/dirinfo.c
@@ -35,8 +35,8 @@ struct dir_info_iter {
 };
 
 struct dir_info_ent {
-	ext2_ino_t		dotdot;	/* Parent according to '..' */
-	ext2_ino_t		parent; /* Parent according to treewalk */
+	ext2_ino64_t		dotdot;	/* Parent according to '..' */
+	ext2_ino64_t		parent; /* Parent according to treewalk */
 };
 
 
@@ -201,7 +201,7 @@ void e2fsck_add_dir_info(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent)
  * get_dir_info() --- given an inode number, try to find the directory
  * information entry for it.
  */
-static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino)
+static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino64_t ino)
 {
 	struct dir_info_db	*db = ctx->dir_info;
 	int			low, high, mid;
@@ -210,7 +210,7 @@ static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino)
 		return 0;
 
 #ifdef DIRINFO_DEBUG
-	printf("e2fsck_get_dir_info %d...", ino);
+	printf("e2fsck_get_dir_info %ld...", ino);
 #endif
 
 #ifdef CONFIG_TDB
@@ -220,7 +220,7 @@ static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino)
 		struct dir_info_ent	*buf;
 
 		key.dptr = (unsigned char *) &ino;
-		key.dsize = sizeof(ext2_ino_t);
+		key.dsize = sizeof(ext2_ino64_t);
 
 		data = tdb_fetch(db->tdb, key);
 		if (!data.dptr) {
@@ -235,7 +235,7 @@ static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino)
 		ret_dir_info.dotdot = buf->dotdot;
 		ret_dir_info.parent = buf->parent;
 #ifdef DIRINFO_DEBUG
-		printf("(%d,%d,%d)\n", ino, buf->dotdot, buf->parent);
+		printf("(%ld,%d,%d)\n", ino, buf->dotdot, buf->parent);
 #endif
 		free(data.dptr);
 		return &ret_dir_info;
@@ -422,8 +422,8 @@ struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, struct dir_info_iter *iter)
  * This function only sets the parent pointer, and requires that
  * dirinfo structure has already been created.
  */
-int e2fsck_dir_info_set_parent(e2fsck_t ctx, ext2_ino_t ino,
-			       ext2_ino_t parent)
+int e2fsck_dir_info_set_parent(e2fsck_t ctx, ext2_ino64_t ino,
+			       ext2_ino64_t parent)
 {
 	struct dir_info *p;
 
@@ -439,8 +439,8 @@ int e2fsck_dir_info_set_parent(e2fsck_t ctx, ext2_ino_t ino,
  * This function only sets the dot dot pointer, and requires that
  * dirinfo structure has already been created.
  */
-int e2fsck_dir_info_set_dotdot(e2fsck_t ctx, ext2_ino_t ino,
-			       ext2_ino_t dotdot)
+int e2fsck_dir_info_set_dotdot(e2fsck_t ctx, ext2_ino64_t ino,
+			       ext2_ino64_t dotdot)
 {
 	struct dir_info *p;
 
@@ -456,8 +456,8 @@ int e2fsck_dir_info_set_dotdot(e2fsck_t ctx, ext2_ino_t ino,
  * This function only sets the parent pointer, and requires that
  * dirinfo structure has already been created.
  */
-int e2fsck_dir_info_get_parent(e2fsck_t ctx, ext2_ino_t ino,
-			       ext2_ino_t *parent)
+int e2fsck_dir_info_get_parent(e2fsck_t ctx, ext2_ino64_t ino,
+			       ext2_ino64_t *parent)
 {
 	struct dir_info *p;
 
@@ -472,8 +472,8 @@ int e2fsck_dir_info_get_parent(e2fsck_t ctx, ext2_ino_t ino,
  * This function only sets the dot dot pointer, and requires that
  * dirinfo structure has already been created.
  */
-int e2fsck_dir_info_get_dotdot(e2fsck_t ctx, ext2_ino_t ino,
-			       ext2_ino_t *dotdot)
+int e2fsck_dir_info_get_dotdot(e2fsck_t ctx, ext2_ino64_t ino,
+			       ext2_ino64_t *dotdot)
 {
 	struct dir_info *p;
 
diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h
index 9eee4bc2..2e038fbe 100644
--- a/e2fsck/e2fsck.h
+++ b/e2fsck/e2fsck.h
@@ -93,9 +93,9 @@
  * directory information.
  */
 struct dir_info {
-	ext2_ino_t		ino;	/* Inode number */
-	ext2_ino_t		dotdot;	/* Parent according to '..' */
-	ext2_ino_t		parent; /* Parent according to treewalk */
+	ext2_ino64_t		ino;	/* Inode number */
+	ext2_ino64_t		dotdot;	/* Parent according to '..' */
+	ext2_ino64_t		parent; /* Parent according to treewalk */
 };
 
 
@@ -460,14 +460,14 @@ extern struct dir_info_iter *e2fsck_dir_info_iter_begin(e2fsck_t ctx);
 extern struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx,
 					     struct dir_info_iter *);
 extern void e2fsck_dir_info_iter_end(e2fsck_t ctx, struct dir_info_iter *);
-extern int e2fsck_dir_info_set_parent(e2fsck_t ctx, ext2_ino_t ino,
-				      ext2_ino_t parent);
-extern int e2fsck_dir_info_set_dotdot(e2fsck_t ctx, ext2_ino_t ino,
-				      ext2_ino_t dotdot);
-extern int e2fsck_dir_info_get_parent(e2fsck_t ctx, ext2_ino_t ino,
-				      ext2_ino_t *parent);
-extern int e2fsck_dir_info_get_dotdot(e2fsck_t ctx, ext2_ino_t ino,
-				      ext2_ino_t *dotdot);
+extern int e2fsck_dir_info_set_parent(e2fsck_t ctx, ext2_ino64_t ino,
+				      ext2_ino64_t parent);
+extern int e2fsck_dir_info_set_dotdot(e2fsck_t ctx, ext2_ino64_t ino,
+				      ext2_ino64_t dotdot);
+extern int e2fsck_dir_info_get_parent(e2fsck_t ctx, ext2_ino64_t ino,
+				      ext2_ino64_t *parent);
+extern int e2fsck_dir_info_get_dotdot(e2fsck_t ctx, ext2_ino64_t ino,
+				      ext2_ino64_t *dotdot);
 
 /* dx_dirinfo.c */
 extern void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks);
diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c
index a8ccc465..ef0b97c0 100644
--- a/e2fsck/pass2.c
+++ b/e2fsck/pass2.c
@@ -179,7 +179,12 @@ void e2fsck_pass2(e2fsck_t ctx)
 
 	if (ext2fs_has_feature_dir_index(fs->super))
 		ext2fs_dblist_sort2(fs->dblist, special_dir_block_cmp);
-
+	if (ext2fs_has_feature_inode64(ctx->fs->super) &&
+	    !ext2fs_has_feature_dirdata(ctx->fs->super)) {
+		if (fix_problem(ctx, PR_2_FIX_DIRDATA_FEATURE, &cd.pctx))
+			ctx->fs->super->s_feature_incompat |=
+				EXT4_FEATURE_INCOMPAT_DIRDATA;
+	}
 	check_dir_func = cd.ra_entries ? check_dir_block2 : check_dir_block;
 	cd.pctx.errcode = ext2fs_dblist_iterate2(fs->dblist, check_dir_func,
 						 &cd);
@@ -995,8 +1000,8 @@ static int check_dir_block(ext2_filsys fs,
 	int			dot_state;
 	unsigned int		rec_len;
 	blk64_t			block_nr = db->blk;
-	ext2_ino_t 		ino = db->ino;
-	ext2_ino_t 		subdir_parent;
+	ext2_ino64_t		ino = db->ino;
+	ext2_ino64_t		subdir_parent;
 	__u16			links;
 	struct check_dir_struct	*cd;
 	char			*buf, *ibuf;
diff --git a/e2fsck/pass3.c b/e2fsck/pass3.c
index 4a777213..b6bee3f8 100644
--- a/e2fsck/pass3.c
+++ b/e2fsck/pass3.c
@@ -284,7 +284,7 @@ static int check_directory(e2fsck_t ctx, ext2_ino_t dir,
 			   struct problem_context *pctx)
 {
 	ext2_filsys 	fs = ctx->fs;
-	ext2_ino_t	ino = dir, parent;
+	ext2_ino64_t	ino = dir, parent;
 	int		loop_pass = 0, parent_count = 0;
 
 	while (1) {
diff --git a/e2fsck/problem.c b/e2fsck/problem.c
index 2a86d528..d8620b93 100644
--- a/e2fsck/problem.c
+++ b/e2fsck/problem.c
@@ -1676,6 +1676,11 @@ static struct e2fsck_problem problem_table[] = {
 	  N_("@E dirdata length set incorrectly.\n"),
 	  PROMPT_CLEAR, PR_PREEN_OK },
 
+	/* dirdata feature is needed for inode64 */
+	{ PR_2_FIX_DIRDATA_FEATURE,
+	  N_("@E ino64 feature without dirdata.\n"),
+	  PROMPT_FIX, PR_PREEN_OK },
+
 	/* Pass 3 errors */
 
 	/* Pass 3: Checking directory connectivity */
diff --git a/e2fsck/problem.h b/e2fsck/problem.h
index 05214840..c847063e 100644
--- a/e2fsck/problem.h
+++ b/e2fsck/problem.h
@@ -13,7 +13,7 @@ typedef __u32 problem_t;
 
 struct problem_context {
 	errcode_t	errcode;
-	ext2_ino_t ino, ino2, dir;
+	ext2_ino64_t ino, ino2, dir;
 	struct ext2_inode *inode;
 	struct ext2_dir_entry *dirent;
 	blk64_t	blk, blk2;
@@ -1007,6 +1007,9 @@ struct problem_context {
 /* Entry dirdata length set incorrectly */
 #define PR_2_CLEAR_DIRDATA		0x020051
 
+/* inode64 feature without dirdata */
+#define PR_2_FIX_DIRDATA_FEATURE	0x020052
+
 /*
  * Pass 3 errors
  */
diff --git a/e2fsck/super.c b/e2fsck/super.c
index 20d6190c..37e5dbfc 100644
--- a/e2fsck/super.c
+++ b/e2fsck/super.c
@@ -1048,6 +1048,7 @@ int check_backup_super_block(e2fsck_t ctx)
 		    SUPER_DIFFERENT(s_blocks_count) ||
 		    SUPER_DIFFERENT(s_blocks_count_hi) ||
 		    SUPER_DIFFERENT(s_inodes_count) ||
+		    SUPER_DIFFERENT(s_inodes_count_hi) ||
 		    memcmp(fs->super->s_uuid, backup_sb->s_uuid,
 			   sizeof(fs->super->s_uuid)))
 			ret = 1;
diff --git a/lib/e2p/feature.c b/lib/e2p/feature.c
index b7f6c1d2..fd77dedd 100644
--- a/lib/e2p/feature.c
+++ b/lib/e2p/feature.c
@@ -105,6 +105,8 @@ static struct feature feature_list[] = {
 			"inline_data"},
 	{       E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_ENCRYPT,
 			"encrypt"},
+	{	E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_INODE64,
+			"inode64"},
 	{	0, 0, 0 },
 };
 
diff --git a/lib/ext2fs/ext2_fs.h b/lib/ext2fs/ext2_fs.h
index 4681a216..9ce48321 100644
--- a/lib/ext2fs/ext2_fs.h
+++ b/lib/ext2fs/ext2_fs.h
@@ -737,7 +737,13 @@ struct ext2_super_block {
 	__le32	s_lpf_ino;		/* Location of the lost+found inode */
 	__le32  s_prj_quota_inum;	/* inode for tracking project quota */
 	__le32	s_checksum_seed;	/* crc32c(orig_uuid) if csum_seed set */
-	__le32	s_reserved[98];		/* Padding to the end of the block */
+	__le32	s_inodes_count_hi;	/* high part of inode count */
+	__le32	s_free_inodes_count_hi;	/* Free inodes count */
+	__le32	s_prj_quota_inum_hi;	/* high part of project quota inode */
+	__le32  s_last_orphan_hi;       /* high part of last orphan */
+	__le32  s_first_error_ino_hi;   /* high part of first error ino */
+	__le32  s_last_error_ino_hi;    /* high part of last error ino */
+	__le32	s_reserved[92];		/* Padding to the end of the block */
 	__u32	s_checksum;		/* crc32c(superblock) */
 };
 
@@ -827,6 +833,8 @@ struct ext2_super_block {
 #define EXT4_FEATURE_INCOMPAT_LARGEDIR		0x4000 /* >2GB or 3-lvl htree */
 #define EXT4_FEATURE_INCOMPAT_INLINE_DATA	0x8000 /* data in inode */
 #define EXT4_FEATURE_INCOMPAT_ENCRYPT		0x10000
+#define EXT4_FEATURE_INCOMPAT_INODE64		0x20000
+
 
 #define EXT4_FEATURE_COMPAT_FUNCS(name, ver, flagname) \
 static inline int ext2fs_has_feature_##name(struct ext2_super_block *sb) \
@@ -918,13 +926,16 @@ EXT4_FEATURE_INCOMPAT_FUNCS(csum_seed,		4, CSUM_SEED)
 EXT4_FEATURE_INCOMPAT_FUNCS(largedir,		4, LARGEDIR)
 EXT4_FEATURE_INCOMPAT_FUNCS(inline_data,	4, INLINE_DATA)
 EXT4_FEATURE_INCOMPAT_FUNCS(encrypt,		4, ENCRYPT)
+EXT4_FEATURE_INCOMPAT_FUNCS(inode64,		4, INODE64)
+
 
 #define EXT2_FEATURE_COMPAT_SUPP	0
 #define EXT2_FEATURE_INCOMPAT_SUPP    (EXT2_FEATURE_INCOMPAT_FILETYPE| \
 				       EXT4_FEATURE_INCOMPAT_MMP| \
 				       EXT4_FEATURE_INCOMPAT_LARGEDIR| \
 				       EXT4_FEATURE_INCOMPAT_EA_INODE| \
-				       EXT4_FEATURE_INCOMPAT_DIRDATA)
+				       EXT4_FEATURE_INCOMPAT_DIRDATA \
+				       EXT4_FEATURE_INCOMPAT_INODE64)
 #define EXT2_FEATURE_RO_COMPAT_SUPP	(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
 					 EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
 					 EXT4_FEATURE_RO_COMPAT_DIR_NLINK| \
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index 2a546acc..246cd52a 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -74,6 +74,7 @@ extern "C" {
 #endif /* EXT2_FLAT_INCLUDES */
 
 typedef __u32 __bitwise		ext2_ino_t;
+typedef __u64 __bitwise		ext2_ino64_t;
 typedef __u32 __bitwise		blk_t;
 typedef __u64 __bitwise		blk64_t;
 typedef __u32 __bitwise		dgrp_t;
@@ -601,6 +602,7 @@ typedef struct ext2_icount *ext2_icount_t;
 					 EXT4_FEATURE_INCOMPAT_FLEX_BG|\
 					 EXT4_FEATURE_INCOMPAT_EA_INODE|\
 					 EXT4_FEATURE_INCOMPAT_DIRDATA|\
+					 EXT4_FEATURE_INCOMPAT_INODE64|\
 					 EXT4_LIB_INCOMPAT_MMP|\
 					 EXT4_FEATURE_INCOMPAT_64BIT|\
 					 EXT4_FEATURE_INCOMPAT_INLINE_DATA|\
@@ -2062,14 +2064,18 @@ ext2fs_const_inode(const struct ext2_inode_large * large_inode)
  * ext2fs_get_last_error_ino
  */
 #define EXT2FS_SB_VALUES(name) \
-static inline unsigned long ext2fs_get_##name(struct ext2_super_block *sb) \
+static inline ext2_ino64_t ext2fs_get_##name(struct ext2_super_block *sb) \
 { \
-	unsigned long value = sb->s_##name; \
-	return value; \
+	ext2_ino64_t inodes_count = sb->s_##name; \
+	if (ext2fs_has_feature_inode64(sb)) \
+		inodes_count |= (ext2_ino64_t)sb->s_##name##_hi << 32; \
+	return inodes_count; \
 } \
 static inline void ext2fs_set_##name(struct ext2_super_block *sb,\
-				   unsigned long val) \
+				   ext2_ino64_t val) \
 { \
+	if (ext2fs_has_feature_inode64(sb)) \
+		sb->s_##name##_hi = (__u32)(val >> 32); \
 	sb->s_##name = val; \
 }
 EXT2FS_SB_VALUES(inodes_count)
diff --git a/lib/ext2fs/swapfs.c b/lib/ext2fs/swapfs.c
index c1da8509..4d98286e 100644
--- a/lib/ext2fs/swapfs.c
+++ b/lib/ext2fs/swapfs.c
@@ -83,6 +83,12 @@ void ext2fs_swap_super(struct ext2_super_block * sb)
 	sb->s_usr_quota_inum = ext2fs_swab32(sb->s_usr_quota_inum);
 	sb->s_grp_quota_inum = ext2fs_swab32(sb->s_grp_quota_inum);
 	sb->s_overhead_blocks = ext2fs_swab32(sb->s_overhead_blocks);
+	sb->s_inodes_count_hi = ext2fs_swab32(sb->s_inodes_count_hi);
+	sb->s_free_inodes_count_hi = ext2fs_swab32(sb->s_free_inodes_count_hi);
+	sb->s_last_orphan_hi = ext2fs_swab32(sb->s_last_orphan_hi);
+	sb->s_prj_quota_inum_hi = ext2fs_swab32(sb->s_prj_quota_inum_hi);
+	sb->s_first_error_ino_hi = ext2fs_swab32(sb->s_first_error_ino_hi);
+	sb->s_last_error_ino_hi = ext2fs_swab32(sb->s_last_error_ino_hi);
 	sb->s_checksum = ext2fs_swab32(sb->s_checksum);
 
 	for (i=0; i < 4; i++)
diff --git a/lib/ext2fs/tst_super_size.c b/lib/ext2fs/tst_super_size.c
index 0adac411..137081dd 100644
--- a/lib/ext2fs/tst_super_size.c
+++ b/lib/ext2fs/tst_super_size.c
@@ -142,7 +142,13 @@ int main(int argc, char **argv)
 	check_field(s_lpf_ino, 4);
 	check_field(s_prj_quota_inum, 4);
 	check_field(s_checksum_seed, 4);
-	check_field(s_reserved, 98 * 4);
+	check_field(s_inodes_count_hi, 4);
+	check_field(s_free_inodes_count_hi, 4);
+	check_field(s_prj_quota_inum_hi, 4);
+	check_field(s_last_orphan_hi, 4);
+	check_field(s_first_error_ino_hi, 4);
+	check_field(s_last_error_ino_hi, 4);
+	check_field(s_reserved, 92 * 4);
 	check_field(s_checksum, 4);
 	do_field("Superblock end", 0, 0, cur_offset, 1024);
 #endif
diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c
index 24023400..47f48bdf 100644
--- a/misc/fuse2fs.c
+++ b/misc/fuse2fs.c
@@ -299,7 +299,7 @@ out:
 #define FUSE2FS_FILE_MAGIC	(0xEF53DEAFUL)
 struct fuse2fs_file_handle {
 	unsigned long magic;
-	ext2_ino_t ino;
+	ext2_ino64_t ino;
 	int open_flags;
 };
 
@@ -328,7 +328,7 @@ struct fuse2fs {
 	return translate_error(global_fs, 0, EXT2_ET_BAD_MAGIC); \
 } while (0)
 
-static int __translate_error(ext2_filsys fs, errcode_t err, ext2_ino_t ino,
+static int __translate_error(ext2_filsys fs, errcode_t err, ext2_ino64_t ino,
 			     const char *file, int line);
 #define translate_error(fs, ino, err) __translate_error((fs), (err), (ino), \
 			__FILE__, __LINE__)
@@ -3866,7 +3866,7 @@ out:
 	return ret;
 }
 
-static int __translate_error(ext2_filsys fs, errcode_t err, ext2_ino_t ino,
+static int __translate_error(ext2_filsys fs, errcode_t err, ext2_ino64_t ino,
 			     const char *file, int line)
 {
 	struct timespec now;
@@ -3940,7 +3940,7 @@ no_translation:
 		return ret;
 
 	if (ino)
-		fprintf(ff->err_fp, "FUSE2FS (%s): %s (inode #%d) at %s:%d.\n",
+		fprintf(ff->err_fp, "FUSE2FS (%s): %s (inode #%ld) at %s:%d.\n",
 			fs->device_name ? fs->device_name : "???",
 			error_message(err), ino, file, line);
 	else
diff --git a/misc/mke2fs.c b/misc/mke2fs.c
index 8edb7546..2878aadc 100644
--- a/misc/mke2fs.c
+++ b/misc/mke2fs.c
@@ -1089,7 +1089,8 @@ static __u32 ok_features[3] = {
 		EXT4_FEATURE_INCOMPAT_INLINE_DATA|
 		EXT4_FEATURE_INCOMPAT_ENCRYPT |
 		EXT4_FEATURE_INCOMPAT_CSUM_SEED |
-		EXT4_FEATURE_INCOMPAT_LARGEDIR,
+		EXT4_FEATURE_INCOMPAT_LARGEDIR|
+		EXT4_FEATURE_INCOMPAT_INODE64,
 	/* R/O compat */
 	EXT2_FEATURE_RO_COMPAT_LARGE_FILE|
 		EXT4_FEATURE_RO_COMPAT_HUGE_FILE|
@@ -2457,13 +2458,15 @@ profile_error:
 	if (num_inodes == 0) {
 		unsigned long long n;
 		n = ext2fs_blocks_count(&fs_param) * blocksize / inode_ratio;
-		if (n > MAX_32_NUM) {
-			if (ext2fs_has_feature_64bit(&fs_param))
+		if (n > MAX_32_NUM && !ext2fs_has_feature_inode64(&fs_param)) {
+			if (ext2fs_has_feature_64bit(&fs_param)) {
 				num_inodes = MAX_32_NUM;
+			}
 			else {
 				com_err(program_name, 0,
-					_("too many inodes (%llu), raise "
-					  "inode ratio?"), n);
+					_("too many inodes (%llu), raise inode"
+					"ratio or enable dirdata and inode64?"),
+					num_inodes);
 				exit(1);
 			}
 		}
@@ -2476,10 +2479,13 @@ profile_error:
 	/*
 	 * Calculate number of inodes based on the inode ratio
 	 */
-	fs_param.s_inodes_count = num_inodes ? num_inodes :
-		(ext2fs_blocks_count(&fs_param) * blocksize) / inode_ratio;
+	if (num_inodes == 0)
+		num_inodes = (ext2fs_blocks_count(&fs_param) * blocksize) /
+			inode_ratio;
+
+	ext2fs_set_inodes_count(&fs_param, num_inodes);
 
-	if ((((unsigned long long)fs_param.s_inodes_count) *
+	if ((ext2fs_get_inodes_count(&fs_param) *
 	     (inode_size ? inode_size : EXT2_GOOD_OLD_INODE_SIZE)) >=
 	    ((ext2fs_blocks_count(&fs_param)) *
 	     EXT2_BLOCK_SIZE(&fs_param))) {
diff --git a/misc/tune2fs.c b/misc/tune2fs.c
index 421c1d98..3538ab9c 100644
--- a/misc/tune2fs.c
+++ b/misc/tune2fs.c
@@ -161,7 +161,8 @@ static __u32 ok_features[3] = {
 		EXT4_FEATURE_INCOMPAT_64BIT |
 		EXT4_FEATURE_INCOMPAT_ENCRYPT |
 		EXT4_FEATURE_INCOMPAT_CSUM_SEED |
-		EXT4_FEATURE_INCOMPAT_LARGEDIR,
+		EXT4_FEATURE_INCOMPAT_LARGEDIR |
+		EXT4_FEATURE_INCOMPAT_INODE64,
 	/* R/O compat */
 	EXT2_FEATURE_RO_COMPAT_LARGE_FILE |
 		EXT4_FEATURE_RO_COMPAT_HUGE_FILE|
-- 
2.14.3 (Apple Git-98)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ