+ unsigned long inodes;
+ unsigned norm_firstzone;
+ unsigned sb_zmaps;
+ unsigned i;
+
+ /* memset(G.superblock_buffer, 0, BLOCK_SIZE); */
+ /* memset(G.boot_block_buffer, 0, 512); */
+ SB_MAGIC = G.magic;
+ SB_ZONE_SIZE = 0;
+ SB_MAXSIZE = version2 ? 0x7fffffff : (7 + 512 + 512 * 512) * 1024;
+ if (version2)
+ SB.s_zones = G.total_blocks;
+ else
+ SB.s_nzones = G.total_blocks;
+
+ /* some magic nrs: 1 inode / 3 blocks */
+ if (G.req_nr_inodes == 0)
+ inodes = G.total_blocks / 3;
+ else
+ inodes = G.req_nr_inodes;
+ /* Round up inode count to fill block size */
+ if (version2)
+ inodes = (inodes + MINIX2_INODES_PER_BLOCK - 1) &
+ ~(MINIX2_INODES_PER_BLOCK - 1);
+ else
+ inodes = (inodes + MINIX1_INODES_PER_BLOCK - 1) &
+ ~(MINIX1_INODES_PER_BLOCK - 1);
+ if (inodes > 65535)
+ inodes = 65535;
+ SB_INODES = inodes;
+ SB_IMAPS = div_roundup(SB_INODES + 1, BITS_PER_BLOCK);
+
+ /* Real bad hack but overwise mkfs.minix can be thrown
+ * in infinite loop...
+ * try:
+ * dd if=/dev/zero of=test.fs count=10 bs=1024
+ * mkfs.minix -i 200 test.fs
+ */
+ /* This code is not insane: NORM_FIRSTZONE is not a constant,
+ * it is calculated from SB_INODES, SB_IMAPS and SB_ZMAPS */
+ i = 999;
+ SB_ZMAPS = 0;
+ do {
+ norm_firstzone = NORM_FIRSTZONE;
+ sb_zmaps = div_roundup(G.total_blocks - norm_firstzone + 1, BITS_PER_BLOCK);
+ if (SB_ZMAPS == sb_zmaps) goto got_it;
+ SB_ZMAPS = sb_zmaps;
+ /* new SB_ZMAPS, need to recalc NORM_FIRSTZONE */
+ } while (--i);
+ bb_error_msg_and_die("incompatible size/inode count, try different -i N");
+ got_it:
+
+ SB_FIRSTZONE = norm_firstzone;
+ G.inode_map = xmalloc(SB_IMAPS * BLOCK_SIZE);
+ G.zone_map = xmalloc(SB_ZMAPS * BLOCK_SIZE);
+ memset(G.inode_map, 0xff, SB_IMAPS * BLOCK_SIZE);
+ memset(G.zone_map, 0xff, SB_ZMAPS * BLOCK_SIZE);
+ for (i = SB_FIRSTZONE; i < SB_ZONES; i++)
+ unmark_zone(i);
+ for (i = MINIX_ROOT_INO; i <= SB_INODES; i++)
+ unmark_inode(i);
+ G.inode_buffer = xzalloc(INODE_BUFFER_SIZE);
+ printf("%ld inodes\n", (long)SB_INODES);
+ printf("%ld blocks\n", (long)SB_ZONES);
+ printf("Firstdatazone=%ld (%ld)\n", (long)SB_FIRSTZONE, (long)norm_firstzone);
+ printf("Zonesize=%d\n", BLOCK_SIZE << SB_ZONE_SIZE);
+ printf("Maxsize=%ld\n", (long)SB_MAXSIZE);
+}
+
+int mkfs_minix_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int mkfs_minix_main(int argc UNUSED_PARAM, char **argv)
+{
+ unsigned opt;