+ if (sblock.fs_fsize < sectorsize) {
+ printf("fragment size %d is too small, minimum is %d\n",
+ sblock.fs_fsize, sectorsize);
+ exit(18);
+ }
+ if (sblock.fs_bsize < MINBSIZE) {
+ printf("block size %d is too small, minimum is %d\n",
+ sblock.fs_bsize, MINBSIZE);
+ exit(19);
+ }
+ if (sblock.fs_bsize < sblock.fs_fsize) {
+ printf("block size (%d) cannot be smaller than fragment size (%d)\n",
+ sblock.fs_bsize, sblock.fs_fsize);
+ exit(20);
+ }
+ sblock.fs_bmask = ~(sblock.fs_bsize - 1);
+ sblock.fs_fmask = ~(sblock.fs_fsize - 1);
+ sblock.fs_qbmask = ~sblock.fs_bmask;
+ sblock.fs_qfmask = ~sblock.fs_fmask;
+ for (sblock.fs_bshift = 0, i = sblock.fs_bsize; i > 1; i >>= 1)
+ sblock.fs_bshift++;
+ for (sblock.fs_fshift = 0, i = sblock.fs_fsize; i > 1; i >>= 1)
+ sblock.fs_fshift++;
+ sblock.fs_frag = numfrags(&sblock, sblock.fs_bsize);
+ for (sblock.fs_fragshift = 0, i = sblock.fs_frag; i > 1; i >>= 1)
+ sblock.fs_fragshift++;
+ if (sblock.fs_frag > MAXFRAG) {
+ printf("fragment size %d is too small, minimum with block size %d is %d\n",
+ sblock.fs_fsize, sblock.fs_bsize,
+ sblock.fs_bsize / MAXFRAG);
+ exit(21);
+ }
+ sblock.fs_nrpos = nrpos;
+ sblock.fs_nindir = sblock.fs_bsize / sizeof(daddr_t);
+ sblock.fs_inopb = sblock.fs_bsize / sizeof(struct dinode);
+ sblock.fs_nspf = sblock.fs_fsize / sectorsize;
+ for (sblock.fs_fsbtodb = 0, i = NSPF(&sblock); i > 1; i >>= 1)
+ sblock.fs_fsbtodb++;
+ sblock.fs_sblkno =
+ roundup(howmany(bbsize + sbsize, sblock.fs_fsize), sblock.fs_frag);
+ sblock.fs_cblkno = (daddr_t)(sblock.fs_sblkno +
+ roundup(howmany(sbsize, sblock.fs_fsize), sblock.fs_frag));
+ sblock.fs_iblkno = sblock.fs_cblkno + sblock.fs_frag;
+ sblock.fs_cgoffset = roundup(
+ howmany(sblock.fs_nsect, NSPF(&sblock)), sblock.fs_frag);
+ for (sblock.fs_cgmask = 0xffffffff, i = sblock.fs_ntrak; i > 1; i >>= 1)
+ sblock.fs_cgmask <<= 1;
+ if (!POWEROF2(sblock.fs_ntrak))
+ sblock.fs_cgmask <<= 1;
+ sblock.fs_maxfilesize = sblock.fs_bsize * NDADDR - 1;
+ for (sizepb = sblock.fs_bsize, i = 0; i < NIADDR; i++) {
+ sizepb *= NINDIR(&sblock);
+ sblock.fs_maxfilesize += sizepb;
+ }
+ /*
+ * Validate specified/determined secpercyl
+ * and calculate minimum cylinders per group.
+ */
+ sblock.fs_spc = secpercyl;
+ for (sblock.fs_cpc = NSPB(&sblock), i = sblock.fs_spc;
+ sblock.fs_cpc > 1 && (i & 1) == 0;
+ sblock.fs_cpc >>= 1, i >>= 1)
+ /* void */;
+ mincpc = sblock.fs_cpc;
+ bpcg = sblock.fs_spc * sectorsize;
+ inospercg = roundup(bpcg / sizeof(struct dinode), INOPB(&sblock));
+ if (inospercg > MAXIPG(&sblock))
+ inospercg = MAXIPG(&sblock);
+ used = (sblock.fs_iblkno + inospercg / INOPF(&sblock)) * NSPF(&sblock);
+ mincpgcnt = howmany(sblock.fs_cgoffset * (~sblock.fs_cgmask) + used,
+ sblock.fs_spc);
+ mincpg = roundup(mincpgcnt, mincpc);
+ /*
+ * Ensure that cylinder group with mincpg has enough space
+ * for block maps.
+ */
+ sblock.fs_cpg = mincpg;
+ sblock.fs_ipg = inospercg;
+ if (maxcontig > 1)
+ sblock.fs_contigsumsize = MIN(maxcontig, FS_MAXCONTIG);
+ mapcramped = 0;
+ while (CGSIZE(&sblock) > sblock.fs_bsize) {
+ mapcramped = 1;
+ if (sblock.fs_bsize < MAXBSIZE) {
+ sblock.fs_bsize <<= 1;
+ if ((i & 1) == 0) {
+ i >>= 1;
+ } else {
+ sblock.fs_cpc <<= 1;
+ mincpc <<= 1;
+ mincpg = roundup(mincpgcnt, mincpc);
+ sblock.fs_cpg = mincpg;
+ }
+ sblock.fs_frag <<= 1;
+ sblock.fs_fragshift += 1;
+ if (sblock.fs_frag <= MAXFRAG)
+ continue;