--- busybox.orig/util-linux/mkfs_ext2.c	Mon Oct 19 16:06:18 2009
+++ busybox/util-linux/mkfs_ext2.c	Mon Oct 19 17:18:18 2009
@@ -20,12 +20,67 @@
 #define	ENABLE_FEATURE_MKFS_EXT2_DIR_INDEX 1
 
 // from e2fsprogs
-#define s_reserved_gdt_blocks s_padding1
-#define s_mkfs_time           s_reserved[0]
-#define s_flags               s_reserved[22]
+#define s_reserved_gdt_blocks	s_padding1
+#define s_mkfs_time		s_reserved[0]
+#define s_flags			s_reserved[22]
 #define EXT2_HASH_HALF_MD4     1
 #define EXT2_FLAGS_SIGNED_HASH 0x0001
 
+/*
+ * Permanent part of an large inode on the disk
+ */
+struct ext2_inode_large {
+	__u16	i_mode;		/* File mode */
+	__u16	i_uid;		/* Low 16 bits of Owner Uid */
+	__u32	i_size;		/* Size in bytes */
+	__u32	i_atime;	/* Access time */
+	__u32	i_ctime;	/* Inode Change time */
+	__u32	i_mtime;	/* Modification time */
+	__u32	i_dtime;	/* Deletion Time */
+	__u16	i_gid;		/* Low 16 bits of Group Id */
+	__u16	i_links_count;	/* Links count */
+	__u32	i_blocks;	/* Blocks count */
+	__u32	i_flags;	/* File flags */
+	union {
+		struct {
+			__u32	l_i_version; /* was l_i_reserved1 */
+		} linux1;
+		struct {
+			__u32  h_i_translator;
+		} hurd1;
+	} osd1;				/* OS dependent 1 */
+	__u32	i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
+	__u32	i_generation;	/* File version (for NFS) */
+	__u32	i_file_acl;	/* File ACL */
+	__u32	i_dir_acl;	/* Directory ACL */
+	__u32	i_faddr;	/* Fragment address */
+	union {
+		struct {
+			__u16	l_i_blocks_hi;
+			__u16	l_i_file_acl_high;
+			__u16	l_i_uid_high;	/* these 2 fields    */
+			__u16	l_i_gid_high;	/* were reserved2[0] */
+			__u32	l_i_reserved2;
+		} linux2;
+		struct {
+			__u8	h_i_frag;	/* Fragment number */
+			__u8	h_i_fsize;	/* Fragment size */
+			__u16	h_i_mode_high;
+			__u16	h_i_uid_high;
+			__u16	h_i_gid_high;
+			__u32	h_i_author;
+		} hurd2;
+	} osd2;				/* OS dependent 2 */
+	__u16	i_extra_isize;
+	__u16	i_pad1;
+	__u32	i_ctime_extra;	/* extra Change time (nsec << 2 | epoch) */
+	__u32	i_mtime_extra;	/* extra Modification time (nsec << 2 | epoch) */
+	__u32	i_atime_extra;	/* extra Access time (nsec << 2 | epoch) */
+	__u32	i_crtime;	/* File creation time */
+	__u32	i_crtime_extra;	/* extra File creation time (nsec << 2 | epoch)*/
+	__u32	i_version_hi;	/* high 32 bits for 64-bit version */
+};
+
 // whiteout: for writable overlays
 //#define LINUX_S_IFWHT                  0160000
 //#define EXT2_FEATURE_INCOMPAT_WHITEOUT 0x0020
@@ -174,6 +229,7 @@
 	unsigned i, pos, n;
 	unsigned bs, bpi;
 	unsigned blocksize, blocksize_log2;
+	unsigned inodesize;
 	unsigned reserved_percent = 5;
 	unsigned long long kilobytes;
 	uint32_t nblocks, nblocks_full;
@@ -221,16 +277,23 @@
 	}
 
 	bytes_per_inode = 16384;
-	if (kilobytes < 512*1024)
+	blocksize = 4096;
+	inodesize = 256;
+	if (kilobytes < 512*1024) {
 		bytes_per_inode = 4096;
-	if (kilobytes < 3*1024)
+		blocksize = 1024;
+		inodesize = 128;
+	}
+	if (kilobytes < 3*1024) {
 		bytes_per_inode = 8192;
+		blocksize = 1024;
+		inodesize = 128;
+	}
 	if (opts & OPT_i)
 		bytes_per_inode = bpi;
 
 	// Determine block size
 	// block size is a multiple of 1024
-	blocksize = 1024;
 	if (kilobytes >= 512*1024) // mke2fs 1.41.9 compat
 		blocksize = 4096;
 	if (EXT2_MAX_BLOCK_SIZE > 4096) {
@@ -326,10 +389,10 @@
 //difference in sizeof(*inode) sometimes
 //results in slightly bigger inodes_per_group here
 //compared to standard mke2fs:
-		inodes_per_group = (div_roundup(inodes_per_group * sizeof(*inode), blocksize) * blocksize) / sizeof(*inode);
+		inodes_per_group = (div_roundup(inodes_per_group * inodesize, blocksize) * blocksize) / inodesize;
 		// make sure the number of inodes per group is a multiple of 8
 		inodes_per_group &= ~7;
-		inode_table_blocks = div_roundup(inodes_per_group * sizeof(*inode), blocksize);
+		inode_table_blocks = div_roundup(inodes_per_group * inodesize, blocksize);
 
 		// to be useful, lost+found should occupy at least 2 blocks (but not exceeding 16*1024 bytes),
 		// and at most EXT2_NDIR_BLOCKS. So reserve these blocks right now
@@ -421,7 +484,19 @@
 //incompatibility:
 //on images > 0.5GB, standard mke2fs uses 256 byte inodes.
 //we always use 128 byte ones:
-	STORE_LE(sb->s_inode_size, sizeof(*inode));
+	STORE_LE(sb->s_inode_size, inodesize);
+	if (inodesize >= sizeof(struct ext2_inode_large)) {
+		int extra_isize = sizeof(struct ext2_inode_large) - EXT2_GOOD_OLD_INODE_SIZE;
+		extra_isize = extra_isize & 0xFFFF;
+		extra_isize = extra_isize | (extra_isize << 16);
+//uint16_t *eis = (uint16_t *)(&s_reserved[21])
+//#define s_min_extra_isize	((uint16_t *)&s_reserved[21])[0]
+//#define s_want_extra_isize	((uint16_t *)&s_reserved[21])[1]
+//		STORE_LE(sb->s_min_extra_isize, extra_isize);
+//		STORE_LE(sb->s_want_extra_isize, extra_isize);
+		STORE_LE(sb->s_reserved[21], extra_isize);
+	}
+	//
 	STORE_LE(sb->s_first_ino, EXT2_GOOD_OLD_FIRST_INO);
 	STORE_LE(sb->s_log_block_size, blocksize_log2 - EXT2_MIN_BLOCK_LOG_SIZE);
 	STORE_LE(sb->s_log_frag_size, blocksize_log2 - EXT2_MIN_BLOCK_LOG_SIZE);
@@ -571,8 +646,8 @@
 	// dump root dir inode
 	STORE_LE(inode->i_links_count, 3); // "/.", "/..", "/lost+found/.." point to this inode
 	STORE_LE(inode->i_block[0], FETCH_LE32(gd[0].bg_inode_table) + inode_table_blocks);
-	PUT(((uint64_t)FETCH_LE32(gd[0].bg_inode_table) * blocksize) + (EXT2_ROOT_INO-1) * sizeof(*inode),
-				buf, sizeof(*inode));
+	PUT(((uint64_t)FETCH_LE32(gd[0].bg_inode_table) * blocksize) + (EXT2_ROOT_INO-1) * inodesize,
+				buf, inodesize);
 
 	// dump lost+found dir inode
 	STORE_LE(inode->i_links_count, 2); // both "/lost+found" and "/lost+found/." point to this inode
@@ -582,8 +657,8 @@
 	for (i = 0; i < lost_and_found_blocks; ++i)
 		STORE_LE(inode->i_block[i], i + n); // use next block
 //bb_info_msg("LAST BLOCK USED[%u]", i + n);
-	PUT(((uint64_t)FETCH_LE32(gd[0].bg_inode_table) * blocksize) + (EXT2_GOOD_OLD_FIRST_INO-1) * sizeof(*inode),
-				buf, sizeof(*inode));
+	PUT(((uint64_t)FETCH_LE32(gd[0].bg_inode_table) * blocksize) + (EXT2_GOOD_OLD_FIRST_INO-1) * inodesize,
+				buf, inodesize);
 
 	// zero the blocks for "/lost+found"
 	memset(buf, 0, blocksize);
