mkfs.minix misbehaves when attempting to create a large v2 or v3 filesystem. I finally traced it down to attempting to create too many inodes so that the first zone is past 65535 blocks in. This obviously doesn't work as the on-disk superblock says this is a 16 bit integer. I wrote a patch that catches this, clamps to the absolute v2/v3 limit (like it already does for v1), and sets the blocks per inode to a more reasonable ratio when exceeding half a gigabyte. Having a half-gig filesystem with most files being smaller than 3k isn't really reasonable. I suppose if you don't want to adjust inode sizes automatically you could take that part out, and it will just crab sooner. Given the non-attention in the code, I suspect nobody ever had cause to try such a big minix filesystem. Well I have my reasons involving some deeply embedded work where ext2 would place too much strain on the hardware. Note that 1) I'm not on the mailing list and 2) I'm on vacation for a week. Consider patch signed off. Have fun.
--- disk-utils/mkfs.minix.c.orig 2015-06-20 13:50:45.509325736 -0700 +++ disk-utils/mkfs.minix.c 2015-06-20 20:27:11.732436640 -0700 @@ -49,6 +49,9 @@ * 06.29.11 - Overall cleanups for util-linux and v3 support * Davidlohr Bueso <dave@xxxxxxx> * + * 06.20.15 - Do not infinite loop or crash on large devices + * Joshua Hudson <joshudson@xxxxxxxxx> + * * Usage: mkfs [-c | -l filename ] [-12v3] [-nXX] [-iXX] device [size-in-blocks] * * -c for readablility checking (SLOW!) @@ -504,9 +507,16 @@ super_set_nzones(); zones = get_nzones(); - /* some magic nrs: 1 inode / 3 blocks */ - if ( req_nr_inodes == 0 ) - inodes = BLOCKS/3; + /* some magic nrs: 1 inode / 3 blocks for smaller filesystems, + * for one inode / 16 blocks for large ones. mkfs will eventually + * crab about too far when getting close to the maximum size. */ + if ( req_nr_inodes == 0 ) + if (BLOCKS > 2048 * 1024) /* 2GB */ + inodes = BLOCKS/16; + else if (BLOCKS > 512 * 1024) /* 0.5GB */ + inodes = BLOCKS/8; + else + inodes = BLOCKS/3; else inodes = req_nr_inodes; /* Round up inode count to fill block size */ @@ -526,6 +536,12 @@ } super_set_map_blocks(inodes); + if (first_zone_data() >= 65536) + errx(MKFS_EX_ERROR, _("First data block at %jd, which is too far" + " (max 65535).\n" + "Try specifying fewer inodes by passing -i######.\n"), + first_zone_data()); + imaps = get_nimaps(); zmaps = get_nzmaps(); @@ -793,6 +809,8 @@ } else /* fs_version == 1 */ if (BLOCKS > MINIX_MAX_INODES) BLOCKS = MINIX_MAX_INODES; + if (BLOCKS > 4 + 65531 * BITS_PER_BLOCK) + BLOCKS = 4 + 65531 * BITS_PER_BLOCK; /* Utter maximum: Clip. */ setup_tables(); if (check) check_blocks();