X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/3352e84ae9eeb59b131bc55d3ac48df8509b2183..c10ca4d6c7863eeb0e998c5fdea5f23e93e1b90b:/usr/src/sbin/newfs/mkfs.c diff --git a/usr/src/sbin/newfs/mkfs.c b/usr/src/sbin/newfs/mkfs.c index a94892701f..81e78a50bf 100644 --- a/usr/src/sbin/newfs/mkfs.c +++ b/usr/src/sbin/newfs/mkfs.c @@ -1,4 +1,4 @@ -static char *sccsid = "@(#)mkfs.c 1.19 (Berkeley) %G%"; +static char *sccsid = "@(#)mkfs.c 2.6 (Berkeley) %G%"; /* * make file system for cylinder-group style file systems @@ -6,15 +6,87 @@ static char *sccsid = "@(#)mkfs.c 1.19 (Berkeley) %G%"; * usage: mkfs special size [ nsect ntrak bsize fsize cpg ] */ +/* + * The following constants set the defaults used for the number + * of sectors (fs_nsect), and number of tracks (fs_ntrak). + */ +#define DFLNSECT 32 +#define DFLNTRAK 16 + +/* + * The following two constants set the default block and fragment sizes. + * Both constants must be a power of 2 and meet the following constraints: + * MINBSIZE <= DESBLKSIZE <= MAXBSIZE + * DEV_BSIZE <= DESFRAGSIZE <= DESBLKSIZE + * DESBLKSIZE / DESFRAGSIZE <= 8 + */ +#define DESBLKSIZE 8192 +#define DESFRAGSIZE 1024 + +/* + * Cylinder groups may have up to MAXCPG cylinders. The actual + * number used depends upon how much information can be stored + * on a single cylinder. The default is to used 16 cylinders + * per group. + */ +#define DESCPG 16 /* desired fs_cpg */ + +/* + * MINFREE gives the minimum acceptable percentage of file system + * blocks which may be free. If the freelist drops below this level + * only the superuser may continue to allocate blocks. This may + * be set to 0 if no reserve of free blocks is deemed necessary, + * however throughput drops by fifty percent if the file system + * is run at between 90% and 100% full; thus the default value of + * fs_minfree is 10%. + */ +#define MINFREE 10 + +/* + * ROTDELAY gives the minimum number of milliseconds to initiate + * another disk transfer on the same cylinder. It is used in + * determining the rotationally optimal layout for disk blocks + * within a file; the default of fs_rotdelay is 2ms. + */ +#define ROTDELAY 2 + +/* + * MAXCONTIG sets the default for the maximum number of blocks + * that may be allocated sequentially. Since UNIX drivers are + * not capable of scheduling multi-block transfers, this defaults + * to 1 (ie no contiguous blocks are allocated). + */ +#define MAXCONTIG 1 + +/* + * MAXBLKPG determines the maximum number of data blocks which are + * placed in a single cylinder group. This is currently a function + * of the block and fragment size of the file system. + */ +#define MAXBLKPG(fs) ((fs)->fs_fsize / sizeof(daddr_t)) + +/* + * Each file system has a number of inodes statically allocated. + * We allocate one inode slot per NBPI bytes, expecting this + * to be far more than we will ever need. + */ +#define NBPI 2048 + #ifndef STANDALONE #include #include #endif +#ifndef SIMFS +#include +#include +#include +#else #include "../h/param.h" #include "../h/inode.h" #include "../h/fs.h" -#include +#endif +#include #define UMASK 0755 #define MAXINOPB (MAXBSIZE / sizeof(struct dinode)) @@ -45,7 +117,7 @@ main(argc, argv) int argc; char *argv[]; { - long cylno, rpos, blk, i, inos, fssize; + long cylno, rpos, blk, i, j, inos, fssize, warn = 0; #ifndef STANDALONE argc--, argv++; @@ -107,11 +179,11 @@ main(argc, argv) if (argc > 4) sblock.fs_bsize = atoi(argv[4]); else - sblock.fs_bsize = MAXBSIZE; + sblock.fs_bsize = DESBLKSIZE; if (argc > 5) sblock.fs_fsize = atoi(argv[5]); else - sblock.fs_fsize = MAX(sblock.fs_bsize / DESFRAG, DEV_BSIZE); + sblock.fs_fsize = DESFRAGSIZE; if (!POWEROF2(sblock.fs_bsize)) { printf("block size must be a power of 2, not %d\n", sblock.fs_bsize); @@ -150,11 +222,18 @@ main(argc, argv) sblock.fs_bsize / MAXFRAG); exit(1); } - sblock.fs_bblkno = BBLOCK; - sblock.fs_sblkno = SBLOCK; - sblock.fs_cblkno = (daddr_t) + 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, sblock.fs_fsize / DEV_BSIZE), + 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; for (sblock.fs_cpc = NSPB(&sblock), i = sblock.fs_spc; sblock.fs_cpc > 1 && (i & 1) == 0; sblock.fs_cpc >>= 1, i >>= 1) @@ -201,10 +280,8 @@ main(argc, argv) sblock.fs_size = fssize = dbtofsb(&sblock, fssize); sblock.fs_ncyl = fssize * NSPF(&sblock) / sblock.fs_spc; if (fssize * NSPF(&sblock) > sblock.fs_ncyl * sblock.fs_spc) { - printf("Warning: %d sector(s) in last cylinder unallocated\n", - sblock.fs_spc - - (fssize * NSPF(&sblock) - sblock.fs_ncyl * sblock.fs_spc)); sblock.fs_ncyl++; + warn = 1; } if (sblock.fs_ncyl < 1) { printf("file systems must have at least one cylinder\n"); @@ -302,24 +379,47 @@ next: if (sblock.fs_ipg > MAXIPG) sblock.fs_ipg = MAXIPG; sblock.fs_dblkno = sblock.fs_iblkno + sblock.fs_ipg / INOPF(&sblock); - if (cgdmin(&sblock, 0) >= sblock.fs_fpg) { + i = MIN(~sblock.fs_cgmask, sblock.fs_ncg - 1); + if (cgdmin(&sblock, i) - cgbase(&sblock, i) >= sblock.fs_fpg) { printf("inode blocks/cyl group (%d) >= data blocks (%d)\n", - cgdmin(&sblock, 0) / sblock.fs_frag, + cgdmin(&sblock, i) - cgbase(&sblock, i) / sblock.fs_frag, sblock.fs_fpg / sblock.fs_frag); - printf("number of cylinder per cylinder group must be increased\n"); + printf("number of cylinders per cylinder group must be increased\n"); exit(1); } + j = sblock.fs_ncg - 1; + if ((i = fssize - j * sblock.fs_fpg) < sblock.fs_fpg && + cgdmin(&sblock, j) - cgbase(&sblock, j) > i) { + printf("Warning: inode blocks/cyl group (%d) >= data blocks (%d) in last\n", + (cgdmin(&sblock, j) - cgbase(&sblock, j)) / sblock.fs_frag, + i / sblock.fs_frag); + printf(" cylinder group. This implies %d sector(s) cannot be allocated.\n", + i * NSPF(&sblock)); + sblock.fs_ncg--; + sblock.fs_ncyl -= sblock.fs_ncyl % sblock.fs_cpg; + sblock.fs_size = fssize = sblock.fs_ncyl * sblock.fs_spc / + NSPF(&sblock); + warn = 0; + } + if (warn) { + printf("Warning: %d sector(s) in last cylinder unallocated\n", + sblock.fs_spc - + (fssize * NSPF(&sblock) - (sblock.fs_ncyl - 1) + * sblock.fs_spc)); + } /* * fill in remaining fields of the super block */ sblock.fs_csaddr = cgdmin(&sblock, 0); - sblock.fs_cssize = sblock.fs_ncg * sizeof(struct csum); - fscs = (struct csum *) - calloc(1, blkroundup(&sblock, sblock.fs_cssize)); + sblock.fs_cssize = + fragroundup(&sblock, sblock.fs_ncg * sizeof(struct csum)); + fscs = (struct csum *)calloc(1, sblock.fs_cssize); sblock.fs_magic = FS_MAGIC; sblock.fs_rotdelay = ROTDELAY; sblock.fs_minfree = MINFREE; - sblock.fs_rps = HZ; /* assume disk speed == HZ */ + sblock.fs_maxcontig = MAXCONTIG; + sblock.fs_maxbpg = MAXBLKPG(&sblock); + sblock.fs_rps = 60; /* assume disk speed == 60 HZ */ sblock.fs_cgrotor = 0; sblock.fs_cstotal.cs_ndir = 0; sblock.fs_cstotal.cs_nbfree = 0; @@ -341,14 +441,16 @@ next: * Now build the cylinders group blocks and * then print out indices of cylinder groups. */ - for (cylno = 0; cylno < sblock.fs_ncg; cylno++) + printf("super-block backups (for fsck -b#) at:"); + for (cylno = 0; cylno < sblock.fs_ncg; cylno++) { initcg(cylno); - if (sblock.fs_ncg == 1) - printf("Warning: no super-block backups with only one cylinder group\n"); - else - printf("\tsuper-block backups (for fsck -b#) at %d+k*%d (%d .. %d)\n", - SBLOCK, cgsblock(&sblock, 1) - SBLOCK, cgsblock(&sblock, 1), - cgsblock(&sblock, sblock.fs_ncg - 1)); + if (cylno % 10 == 0) + printf("\n"); + printf(" %d,", fsbtodb(&sblock, cgsblock(&sblock, cylno))); + } + printf("\n%s\n%s\n", + "WRITE THESE NUMBERS DOWN!!!", + "fsck depends on them to recover this file system."); /* * Now construct the initial file system, * then write out the super-block. @@ -358,12 +460,15 @@ next: wtfs(SBLOCK, SBSIZE, (char *)&sblock); for (i = 0; i < sblock.fs_cssize; i += sblock.fs_bsize) wtfs(fsbtodb(&sblock, sblock.fs_csaddr + numfrags(&sblock, i)), - sblock.fs_bsize, ((char *)fscs) + i); + sblock.fs_cssize - i < sblock.fs_bsize ? + sblock.fs_cssize - i : sblock.fs_bsize, + ((char *)fscs) + i); /* * Write out the duplicate super blocks */ - for (cylno = 1; cylno < sblock.fs_ncg; cylno++) - wtfs(cgsblock(&sblock, cylno), SBSIZE, (char *)&sblock); + for (cylno = 0; cylno < sblock.fs_ncg; cylno++) + wtfs(fsbtodb(&sblock, cgsblock(&sblock, cylno)), + SBSIZE, (char *)&sblock); #ifndef STANDALONE exit(0); #endif @@ -375,7 +480,7 @@ next: initcg(cylno) int cylno; { - daddr_t cbase, d, dmin, dmax; + daddr_t cbase, d, dlower, dupper, dmax; long i, j, s; register struct csum *cs; @@ -388,21 +493,24 @@ initcg(cylno) dmax = cbase + sblock.fs_fpg; if (dmax > sblock.fs_size) dmax = sblock.fs_size; - dmin = sblock.fs_dblkno; - d = cbase; + dlower = cgsblock(&sblock, cylno) - cbase; + dupper = cgdmin(&sblock, cylno) - cbase; cs = fscs + cylno; acg.cg_time = utime; acg.cg_magic = CG_MAGIC; acg.cg_cgx = cylno; - acg.cg_ncyl = sblock.fs_cpg; + if (cylno == sblock.fs_ncg - 1) + acg.cg_ncyl = sblock.fs_ncyl % sblock.fs_cpg; + else + acg.cg_ncyl = sblock.fs_cpg; acg.cg_niblk = sblock.fs_ipg; acg.cg_ndblk = dmax - cbase; acg.cg_cs.cs_ndir = 0; acg.cg_cs.cs_nffree = 0; acg.cg_cs.cs_nbfree = 0; acg.cg_cs.cs_nifree = 0; - acg.cg_rotor = dmin; - acg.cg_frotor = dmin; + acg.cg_rotor = 0; + acg.cg_frotor = 0; acg.cg_irotor = 0; for (i = 0; i < sblock.fs_frag; i++) { acg.cg_frsum[i] = 0; @@ -433,27 +541,49 @@ initcg(cylno) acg.cg_b[i][j] = 0; } if (cylno == 0) { - dmin += howmany(sblock.fs_cssize, sblock.fs_bsize) * - sblock.fs_frag; + /* + * reserve space for summary info and Boot block + */ + dupper += howmany(sblock.fs_cssize, sblock.fs_fsize); + for (d = 0; d < dlower; d += sblock.fs_frag) + clrblock(&sblock, acg.cg_free, d/sblock.fs_frag); + } else { + for (d = 0; d < dlower; d += sblock.fs_frag) { + setblock(&sblock, acg.cg_free, d/sblock.fs_frag); + acg.cg_cs.cs_nbfree++; + acg.cg_btot[cbtocylno(&sblock, d)]++; + acg.cg_b[cbtocylno(&sblock, d)][cbtorpos(&sblock, d)]++; + } + sblock.fs_dsize += dlower; } - for (d = 0; d < dmin; d += sblock.fs_frag) + sblock.fs_dsize += acg.cg_ndblk - dupper; + for (; d < dupper; d += sblock.fs_frag) clrblock(&sblock, acg.cg_free, d/sblock.fs_frag); - while ((d+sblock.fs_frag) <= dmax - cbase) { + if (d > dupper) { + acg.cg_frsum[d - dupper]++; + for (i = d - 1; i >= dupper; i--) { + setbit(acg.cg_free, i); + acg.cg_cs.cs_nffree++; + } + } + while ((d + sblock.fs_frag) <= dmax - cbase) { setblock(&sblock, acg.cg_free, d/sblock.fs_frag); acg.cg_cs.cs_nbfree++; acg.cg_btot[cbtocylno(&sblock, d)]++; acg.cg_b[cbtocylno(&sblock, d)][cbtorpos(&sblock, d)]++; d += sblock.fs_frag; } - if (d < dmax - cbase) + if (d < dmax - cbase) { acg.cg_frsum[dmax - cbase - d]++; for (; d < dmax - cbase; d++) { setbit(acg.cg_free, d); acg.cg_cs.cs_nffree++; } - for (; d < MAXBPG(&sblock); d++) - clrbit(acg.cg_free, d); - sblock.fs_dsize += acg.cg_ndblk - dmin; + for (; d % sblock.fs_frag != 0; d++) + clrbit(acg.cg_free, d); + } + for (d /= sblock.fs_frag; d < MAXBPG(&sblock); d ++) + clrblock(&sblock, acg.cg_free, d); sblock.fs_cstotal.cs_ndir += acg.cg_cs.cs_ndir; sblock.fs_cstotal.cs_nffree += acg.cg_cs.cs_nffree; sblock.fs_cstotal.cs_nbfree += acg.cg_cs.cs_nbfree; @@ -552,6 +682,10 @@ alloc(size, mode) rdfs(fsbtodb(&sblock, cgtod(&sblock, 0)), sblock.fs_cgsize, (char *)&acg); + if (acg.cg_magic != CG_MAGIC) { + printf("cg 0: bad magic number\n"); + return (0); + } if (acg.cg_cs.cs_nbfree == 0) { printf("first cylinder group ran out of space\n"); return (0); @@ -580,7 +714,7 @@ goth: acg.cg_cs.cs_nffree += sblock.fs_frag - frag; acg.cg_frsum[sblock.fs_frag - frag]++; for (i = frag; i < sblock.fs_frag; i++) - setbit(acg.cg_free, d+i); + setbit(acg.cg_free, d + i); } wtfs(fsbtodb(&sblock, cgtod(&sblock, 0)), sblock.fs_cgsize, (char *)&acg); @@ -600,6 +734,10 @@ iput(ip) c = itog(&sblock, ip->i_number); rdfs(fsbtodb(&sblock, cgtod(&sblock, 0)), sblock.fs_cgsize, (char *)&acg); + if (acg.cg_magic != CG_MAGIC) { + printf("cg 0: bad magic number\n"); + exit(1); + } acg.cg_cs.cs_nifree--; setbit(acg.cg_iused, ip->i_number); wtfs(fsbtodb(&sblock, cgtod(&sblock, 0)), sblock.fs_cgsize, @@ -664,6 +802,7 @@ wtfs(bno, size, bf) } } +#ifndef STANDALONE /* * copy a block */ @@ -673,6 +812,7 @@ bcopy(from, to, size) { asm(" movc3 12(ap),*4(ap),*8(ap)"); } +#endif /* * check if a block is available @@ -697,7 +837,11 @@ isblock(fs, cp, h) mask = 0x01 << (h & 0x7); return ((cp[h >> 3] & mask) == mask); default: +#ifdef STANDALONE + printf("isblock bad fs_frag %d\n", fs->fs_frag); +#else fprintf(stderr, "isblock bad fs_frag %d\n", fs->fs_frag); +#endif return; } } @@ -724,7 +868,11 @@ clrblock(fs, cp, h) cp[h >> 3] &= ~(0x01 << (h & 0x7)); return; default: +#ifdef STANDALONE + printf("clrblock bad fs_frag %d\n", fs->fs_frag); +#else fprintf(stderr, "clrblock bad fs_frag %d\n", fs->fs_frag); +#endif return; } } @@ -751,7 +899,11 @@ setblock(fs, cp, h) cp[h >> 3] |= (0x01 << (h & 0x7)); return; default: +#ifdef STANDALONE + printf("setblock bad fs_frag %d\n", fs->fs_frag); +#else fprintf(stderr, "setblock bad fs_frag %d\n", fs->fs_frag); +#endif return; } }