121137Sdist /* 221137Sdist * Copyright (c) 1980 Regents of the University of California. 321137Sdist * All rights reserved. The Berkeley software License Agreement 421137Sdist * specifies the terms and conditions for redistribution. 521137Sdist */ 621137Sdist 713604Ssam #ifndef lint 8*32120Smckusick static char sccsid[] = "@(#)mkfs.c 6.4 (Berkeley) 09/10/87"; 921137Sdist #endif not lint 104234Smckusick 114234Smckusick /* 124234Smckusick * make file system for cylinder-group style file systems 134234Smckusick */ 144234Smckusick 154234Smckusick #ifndef STANDALONE 164234Smckusick #include <stdio.h> 174234Smckusick #include <a.out.h> 184234Smckusick #endif 194234Smckusick 206495Smckusick #include <sys/param.h> 216495Smckusick #include <sys/inode.h> 226495Smckusick #include <sys/fs.h> 2313604Ssam #include <sys/dir.h> 2430381Smckusick #include <sys/disklabel.h> 254234Smckusick 2630381Smckusick /* 2730381Smckusick * MAXBLKPG determines the maximum number of data blocks which are 2830381Smckusick * placed in a single cylinder group. This is currently a function 2930381Smckusick * of the block and fragment size of the file system. 3030381Smckusick */ 3130381Smckusick #define MAXBLKPG(fs) ((fs)->fs_fsize / sizeof(daddr_t)) 3230381Smckusick 335336Smckusic #define UMASK 0755 345346Smckusic #define MAXINOPB (MAXBSIZE / sizeof(struct dinode)) 355336Smckusic #define POWEROF2(num) (((num) & ((num) - 1)) == 0) 364234Smckusick 3730381Smckusick /* 3830381Smckusick * variables set up by front end. 3930381Smckusick */ 4030386Smckusick extern int Nflag; /* run mkfs without writing file system */ 4130386Smckusick extern int fssize; /* file system size */ 4230386Smckusick extern int ntracks; /* # tracks/cylinder */ 4330386Smckusick extern int nsectors; /* # sectors/track */ 4430386Smckusick extern int nphyssectors; /* # sectors/track including spares */ 4530386Smckusick extern int secpercyl; /* sectors per cylinder */ 4630386Smckusick extern int sectorsize; /* bytes/sector */ 4730386Smckusick extern int rpm; /* revolutions/minute of drive */ 4830386Smckusick extern int interleave; /* hardware sector interleave */ 4930386Smckusick extern int trackskew; /* sector 0 skew, per track */ 5030386Smckusick extern int headswitch; /* head switch time, usec */ 5130386Smckusick extern int trackseek; /* track-to-track seek, usec */ 5230386Smckusick extern int fsize; /* fragment size */ 5330386Smckusick extern int bsize; /* block size */ 5430386Smckusick extern int cpg; /* cylinders/cylinder group */ 55*32120Smckusick extern int cpgflg; /* cylinders/cylinder group flag was given */ 5630386Smckusick extern int minfree; /* free space threshold */ 5730386Smckusick extern int opt; /* optimization preference (space or time) */ 5830386Smckusick extern int density; /* number of bytes per inode */ 5930386Smckusick extern int maxcontig; /* max contiguous blocks to allocate */ 6030386Smckusick extern int rotdelay; /* rotational delay between blocks */ 6130691Skarels extern int bbsize; /* boot block size */ 6230691Skarels extern int sbsize; /* superblock size */ 6330381Smckusick 644234Smckusick union { 654234Smckusick struct fs fs; 665324Smckusic char pad[MAXBSIZE]; 674234Smckusick } fsun; 684234Smckusick #define sblock fsun.fs 694234Smckusick struct csum *fscs; 704234Smckusick 714234Smckusick union { 724234Smckusick struct cg cg; 735324Smckusic char pad[MAXBSIZE]; 744234Smckusick } cgun; 754234Smckusick #define acg cgun.cg 764234Smckusick 775336Smckusic struct dinode zino[MAXIPG]; 785336Smckusic 7930381Smckusick int fsi, fso; 805336Smckusic time_t utime; 814234Smckusick daddr_t alloc(); 824234Smckusick 8330381Smckusick mkfs(pp, fsys, fi, fo) 8430381Smckusick struct partition *pp; 8530381Smckusick char *fsys; 8630381Smckusick int fi, fo; 874234Smckusick { 88*32120Smckusick register long i, mincpc, mincpg, inospercg; 89*32120Smckusick long cylno, rpos, blk, j, warn = 0; 90*32120Smckusick long used, mincpgcnt, bpcg; 91*32120Smckusick long mapcramped, inodecramped; 924234Smckusick 935336Smckusic #ifndef STANDALONE 944234Smckusick time(&utime); 955336Smckusic #endif 9630381Smckusick fsi = fi; 9730381Smckusick fso = fo; 9812252Smckusick /* 9912252Smckusick * Validate the given file system size. 10012252Smckusick * Verify that its last block can actually be accessed. 10112252Smckusick */ 1025336Smckusic if (fssize <= 0) 1035336Smckusic printf("preposterous size %d\n", fssize), exit(1); 10430381Smckusick wtfs(fssize - 1, sectorsize, (char *)&sblock); 1055336Smckusic /* 1065336Smckusic * collect and verify the sector and track info 1075336Smckusic */ 10830381Smckusick sblock.fs_nsect = nsectors; 10930381Smckusick sblock.fs_ntrak = ntracks; 1105336Smckusic if (sblock.fs_ntrak <= 0) 1115336Smckusic printf("preposterous ntrak %d\n", sblock.fs_ntrak), exit(1); 1125336Smckusic if (sblock.fs_nsect <= 0) 1135336Smckusic printf("preposterous nsect %d\n", sblock.fs_nsect), exit(1); 1145336Smckusic /* 1155336Smckusic * collect and verify the block and fragment sizes 1165336Smckusic */ 11730381Smckusick sblock.fs_bsize = bsize; 11830381Smckusick sblock.fs_fsize = fsize; 1195336Smckusic if (!POWEROF2(sblock.fs_bsize)) { 1205336Smckusic printf("block size must be a power of 2, not %d\n", 1215336Smckusic sblock.fs_bsize); 1224234Smckusick exit(1); 1234234Smckusick } 1245336Smckusic if (!POWEROF2(sblock.fs_fsize)) { 1255336Smckusic printf("fragment size must be a power of 2, not %d\n", 1265336Smckusic sblock.fs_fsize); 1274234Smckusick exit(1); 1284234Smckusick } 12930381Smckusick if (sblock.fs_fsize < sectorsize) { 1305324Smckusic printf("fragment size %d is too small, minimum is %d\n", 13130381Smckusick sblock.fs_fsize, sectorsize); 1325324Smckusic exit(1); 1335324Smckusic } 1345324Smckusic if (sblock.fs_bsize < MINBSIZE) { 1355324Smckusic printf("block size %d is too small, minimum is %d\n", 1365324Smckusic sblock.fs_bsize, MINBSIZE); 1375324Smckusic exit(1); 1385324Smckusic } 1395336Smckusic if (sblock.fs_bsize < sblock.fs_fsize) { 1405336Smckusic printf("block size (%d) cannot be smaller than fragment size (%d)\n", 1415336Smckusic sblock.fs_bsize, sblock.fs_fsize); 1424234Smckusick exit(1); 1434234Smckusick } 1445955Smckusic sblock.fs_bmask = ~(sblock.fs_bsize - 1); 1455955Smckusic sblock.fs_fmask = ~(sblock.fs_fsize - 1); 1465955Smckusic for (sblock.fs_bshift = 0, i = sblock.fs_bsize; i > 1; i >>= 1) 1475955Smckusic sblock.fs_bshift++; 1485955Smckusic for (sblock.fs_fshift = 0, i = sblock.fs_fsize; i > 1; i >>= 1) 1495955Smckusic sblock.fs_fshift++; 1505955Smckusic sblock.fs_frag = numfrags(&sblock, sblock.fs_bsize); 15110076Smckusick for (sblock.fs_fragshift = 0, i = sblock.fs_frag; i > 1; i >>= 1) 15210076Smckusick sblock.fs_fragshift++; 1535336Smckusic if (sblock.fs_frag > MAXFRAG) { 1545336Smckusic printf("fragment size %d is too small, minimum with block size %d is %d\n", 1555336Smckusic sblock.fs_fsize, sblock.fs_bsize, 1565336Smckusic sblock.fs_bsize / MAXFRAG); 1575336Smckusic exit(1); 1584234Smckusick } 15910076Smckusick sblock.fs_nindir = sblock.fs_bsize / sizeof(daddr_t); 16010076Smckusick sblock.fs_inopb = sblock.fs_bsize / sizeof(struct dinode); 16130381Smckusick sblock.fs_nspf = sblock.fs_fsize / sectorsize; 16230381Smckusick for (sblock.fs_fsbtodb = 0, i = NSPF(&sblock); i > 1; i >>= 1) 16310076Smckusick sblock.fs_fsbtodb++; 1646532Smckusick sblock.fs_sblkno = 16530691Skarels roundup(howmany(bbsize + sbsize, sblock.fs_fsize), sblock.fs_frag); 1666532Smckusick sblock.fs_cblkno = (daddr_t)(sblock.fs_sblkno + 16730691Skarels roundup(howmany(sbsize, sblock.fs_fsize), sblock.fs_frag)); 1685362Smckusic sblock.fs_iblkno = sblock.fs_cblkno + sblock.fs_frag; 1696532Smckusick sblock.fs_cgoffset = roundup( 17030381Smckusick howmany(sblock.fs_nsect, NSPF(&sblock)), sblock.fs_frag); 1716532Smckusick for (sblock.fs_cgmask = 0xffffffff, i = sblock.fs_ntrak; i > 1; i >>= 1) 1726532Smckusick sblock.fs_cgmask <<= 1; 1736532Smckusick if (!POWEROF2(sblock.fs_ntrak)) 1746532Smckusick sblock.fs_cgmask <<= 1; 175*32120Smckusick /* 176*32120Smckusick * Validate specified/determined secpercyl 177*32120Smckusick * and calculate minimum cylinders per group. 178*32120Smckusick */ 179*32120Smckusick sblock.fs_spc = secpercyl; 1805399Smckusic for (sblock.fs_cpc = NSPB(&sblock), i = sblock.fs_spc; 1815399Smckusic sblock.fs_cpc > 1 && (i & 1) == 0; 1825399Smckusic sblock.fs_cpc >>= 1, i >>= 1) 1835399Smckusic /* void */; 184*32120Smckusick mincpc = sblock.fs_cpc; 185*32120Smckusick if (mincpc > MAXCPG) { 186*32120Smckusick printf("Maximum frag size with %d sectors per cylinder is %d\n", 187*32120Smckusick sblock.fs_spc, sblock.fs_fsize / (mincpc / MAXCPG)); 1885605Smckusic exit(1); 1895605Smckusic } 190*32120Smckusick bpcg = sblock.fs_spc * sectorsize; 191*32120Smckusick inospercg = roundup(bpcg / sizeof(struct dinode), INOPB(&sblock)); 192*32120Smckusick if (inospercg > MAXIPG) 193*32120Smckusick inospercg = MAXIPG; 194*32120Smckusick used = (sblock.fs_iblkno + inospercg / INOPF(&sblock)) * NSPF(&sblock); 195*32120Smckusick mincpgcnt = howmany(sblock.fs_cgoffset * (~sblock.fs_cgmask) + used, 196*32120Smckusick sblock.fs_spc); 197*32120Smckusick mincpg = roundup(mincpgcnt, mincpc); 198*32120Smckusick /* 199*32120Smckusick * Insure that cylinder group with mincpg has enough space 200*32120Smckusick * for block maps 201*32120Smckusick */ 202*32120Smckusick mapcramped = 0; 203*32120Smckusick while (mincpg * sblock.fs_spc > MAXBPG(&sblock) * NSPB(&sblock)) { 204*32120Smckusick mapcramped = 1; 205*32120Smckusick if (sblock.fs_bsize < MAXBSIZE) { 206*32120Smckusick sblock.fs_bsize <<= 1; 207*32120Smckusick if ((i & 1) == 0) { 208*32120Smckusick i >>= 1; 209*32120Smckusick } else { 210*32120Smckusick sblock.fs_cpc <<= 1; 211*32120Smckusick mincpc <<= 1; 212*32120Smckusick mincpg = roundup(mincpgcnt, mincpc); 213*32120Smckusick } 214*32120Smckusick sblock.fs_frag <<= 1; 215*32120Smckusick sblock.fs_fragshift += 1; 216*32120Smckusick if (sblock.fs_frag <= MAXFRAG) 217*32120Smckusick continue; 218*32120Smckusick } 219*32120Smckusick if (sblock.fs_fsize == sblock.fs_bsize) { 220*32120Smckusick printf("There is no block size that"); 221*32120Smckusick printf(" can support this disk\n"); 222*32120Smckusick exit(1); 223*32120Smckusick } 224*32120Smckusick sblock.fs_frag >>= 1; 225*32120Smckusick sblock.fs_fragshift -= 1; 226*32120Smckusick sblock.fs_fsize <<= 1; 227*32120Smckusick sblock.fs_nspf <<= 1; 228*32120Smckusick } 229*32120Smckusick /* 230*32120Smckusick * Insure that cylinder group with mincpg has enough space for inodes 231*32120Smckusick */ 232*32120Smckusick inodecramped = 0; 233*32120Smckusick used *= sectorsize; 234*32120Smckusick inospercg = (mincpg * bpcg - used) / density; 235*32120Smckusick while (inospercg > MAXIPG) { 236*32120Smckusick inodecramped = 1; 237*32120Smckusick if (mincpc == 1 || sblock.fs_frag == 1 || 238*32120Smckusick sblock.fs_bsize == MINBSIZE) 239*32120Smckusick break; 240*32120Smckusick printf("With a block size of %d %s %d\n", sblock.fs_bsize, 241*32120Smckusick "minimum bytes per inode is", 242*32120Smckusick (mincpg * bpcg - used) / MAXIPG + 1); 243*32120Smckusick sblock.fs_bsize >>= 1; 244*32120Smckusick sblock.fs_frag >>= 1; 245*32120Smckusick sblock.fs_fragshift -= 1; 246*32120Smckusick mincpc >>= 1; 247*32120Smckusick i = roundup(mincpgcnt, mincpc); 248*32120Smckusick if (i * sblock.fs_spc > MAXBPG(&sblock) * NSPB(&sblock)) { 249*32120Smckusick sblock.fs_bsize <<= 1; 250*32120Smckusick break; 251*32120Smckusick } 252*32120Smckusick mincpg = i; 253*32120Smckusick inospercg = (mincpg * bpcg - used) / density; 254*32120Smckusick } 255*32120Smckusick if (inodecramped) { 256*32120Smckusick if (inospercg > MAXIPG) { 257*32120Smckusick printf("Minimum bytes per inode is %d\n", 258*32120Smckusick (mincpg * bpcg - used) / MAXIPG + 1); 259*32120Smckusick } else if (!mapcramped) { 260*32120Smckusick printf("With %d bytes per inode, ", density); 261*32120Smckusick printf("minimum cylinders per group is %d\n", mincpg); 262*32120Smckusick } 263*32120Smckusick } 264*32120Smckusick if (mapcramped) { 265*32120Smckusick printf("With %d sectors per cylinder, ", sblock.fs_spc); 266*32120Smckusick printf("minimum cylinders per group is %d\n", mincpg); 267*32120Smckusick } 268*32120Smckusick if (inodecramped || mapcramped) { 269*32120Smckusick if (sblock.fs_bsize != bsize) 270*32120Smckusick printf("%s to be changed from %d to %d\n", 271*32120Smckusick "This requires the block size", 272*32120Smckusick bsize, sblock.fs_bsize); 273*32120Smckusick if (sblock.fs_fsize != fsize) 274*32120Smckusick printf("\t%s to be changed from %d to %d\n", 275*32120Smckusick "and the fragment size", 276*32120Smckusick bsize, sblock.fs_bsize); 277*32120Smckusick exit(1); 278*32120Smckusick } 2795336Smckusic /* 280*32120Smckusick * Calculate the number of cylinders per group 2814234Smckusick */ 28230381Smckusick sblock.fs_cpg = cpg; 283*32120Smckusick if (sblock.fs_cpg % mincpc != 0) { 28430381Smckusick printf("%s groups must have a multiple of %d cylinders\n", 285*32120Smckusick cpgflg ? "Cylinder" : "Warning: cylinder", mincpc); 286*32120Smckusick sblock.fs_cpg = roundup(sblock.fs_cpg, mincpc); 28730381Smckusick } 288*32120Smckusick /* 289*32120Smckusick * Must insure there is enough space to hold block map 290*32120Smckusick */ 29130381Smckusick sblock.fs_fpg = (sblock.fs_cpg * sblock.fs_spc) / NSPF(&sblock); 292*32120Smckusick while (sblock.fs_fpg > MAXBPG(&sblock) * sblock.fs_frag) { 293*32120Smckusick mapcramped = 1; 294*32120Smckusick sblock.fs_cpg -= mincpc; 2955336Smckusic sblock.fs_fpg = (sblock.fs_cpg * sblock.fs_spc) / NSPF(&sblock); 2964234Smckusick } 297*32120Smckusick /* 298*32120Smckusick * Must insure there is enough space for inodes 299*32120Smckusick */ 300*32120Smckusick inospercg = (sblock.fs_cpg * bpcg - used) / density; 301*32120Smckusick while (inospercg > MAXIPG) { 302*32120Smckusick inodecramped = 1; 303*32120Smckusick sblock.fs_cpg -= mincpc; 304*32120Smckusick sblock.fs_fpg = (sblock.fs_cpg * sblock.fs_spc) / NSPF(&sblock); 305*32120Smckusick inospercg = (sblock.fs_cpg * bpcg - used) / density; 306*32120Smckusick } 307*32120Smckusick if ((sblock.fs_cpg * sblock.fs_spc) % NSPB(&sblock) != 0) { 308*32120Smckusick printf("newfs: panic (fs_cpg * fs_spc) % NSPF != 0"); 309*32120Smckusick exit(2); 310*32120Smckusick } 311*32120Smckusick if (sblock.fs_cpg < mincpg) { 312*32120Smckusick printf("cylinder groups must have at least %d cylinders\n", 313*32120Smckusick mincpg); 3145336Smckusic exit(1); 31530381Smckusick } else if (sblock.fs_cpg > MAXCPG) { 3165336Smckusic printf("cylinder groups are limited to %d cylinders\n", MAXCPG); 3175336Smckusic exit(1); 318*32120Smckusick } else if (sblock.fs_cpg != cpg) { 319*32120Smckusick if (!cpgflg) 320*32120Smckusick printf("Warning: "); 321*32120Smckusick if (mapcramped && inodecramped) 322*32120Smckusick printf("Block size and bytes per inode restrict"); 323*32120Smckusick else if (mapcramped) 324*32120Smckusick printf("Block size restricts"); 325*32120Smckusick else 326*32120Smckusick printf("Bytes per inode restrict"); 327*32120Smckusick printf(" cylinders per group to %d.\n", sblock.fs_cpg); 328*32120Smckusick if (cpgflg) 329*32120Smckusick exit(1); 3305336Smckusic } 331*32120Smckusick sblock.fs_cgsize = fragroundup(&sblock, 332*32120Smckusick sizeof(struct cg) + howmany(sblock.fs_fpg, NBBY)); 3334234Smckusick /* 3345336Smckusic * Now have size for file system and nsect and ntrak. 3355336Smckusic * Determine number of cylinders and blocks in the file system. 3365336Smckusic */ 3375336Smckusic sblock.fs_size = fssize = dbtofsb(&sblock, fssize); 3385336Smckusic sblock.fs_ncyl = fssize * NSPF(&sblock) / sblock.fs_spc; 3395362Smckusic if (fssize * NSPF(&sblock) > sblock.fs_ncyl * sblock.fs_spc) { 3405362Smckusic sblock.fs_ncyl++; 3416532Smckusick warn = 1; 3425362Smckusic } 3435362Smckusic if (sblock.fs_ncyl < 1) { 3445362Smckusic printf("file systems must have at least one cylinder\n"); 3455336Smckusic exit(1); 3465336Smckusic } 3475336Smckusic /* 3485362Smckusic * determine feasability/values of rotational layout tables 3495362Smckusic */ 350*32120Smckusick sblock.fs_interleave = interleave; 351*32120Smckusick sblock.fs_trackskew = trackskew; 352*32120Smckusick sblock.fs_npsect = nphyssectors; 3535362Smckusic if (sblock.fs_ntrak == 1) { 3545362Smckusic sblock.fs_cpc = 0; 3555362Smckusic goto next; 3565362Smckusic } 3575362Smckusic if (sblock.fs_spc * sblock.fs_cpc > MAXBPC * NSPB(&sblock) || 3585362Smckusic sblock.fs_nsect > (1 << NBBY) * NSPB(&sblock)) { 3595362Smckusic printf("%s %s %d %s %d.%s", 3605362Smckusic "Warning: insufficient space in super block for\n", 3615362Smckusic "rotational layout tables with nsect", sblock.fs_nsect, 3625362Smckusic "and ntrak", sblock.fs_ntrak, 36318552Sbloom "\nFile system performance may be impaired.\n"); 3645362Smckusic sblock.fs_cpc = 0; 3655362Smckusic goto next; 3665362Smckusic } 3675362Smckusic /* 3685362Smckusic * calculate the available blocks for each rotational position 3695362Smckusic */ 3705362Smckusic for (cylno = 0; cylno < MAXCPG; cylno++) 3715362Smckusic for (rpos = 0; rpos < NRPOS; rpos++) 3725362Smckusic sblock.fs_postbl[cylno][rpos] = -1; 3735362Smckusic blk = sblock.fs_spc * sblock.fs_cpc / NSPF(&sblock); 3745362Smckusic for (i = 0; i < blk; i += sblock.fs_frag) 3755362Smckusic /* void */; 3765362Smckusic for (i -= sblock.fs_frag; i >= 0; i -= sblock.fs_frag) { 3775362Smckusic cylno = cbtocylno(&sblock, i); 3785362Smckusic rpos = cbtorpos(&sblock, i); 3795362Smckusic blk = i / sblock.fs_frag; 3805362Smckusic if (sblock.fs_postbl[cylno][rpos] == -1) 3815362Smckusic sblock.fs_rotbl[blk] = 0; 3825362Smckusic else 3835362Smckusic sblock.fs_rotbl[blk] = 3845362Smckusic sblock.fs_postbl[cylno][rpos] - blk; 3855362Smckusic sblock.fs_postbl[cylno][rpos] = blk; 3865362Smckusic } 3875362Smckusic next: 3885362Smckusic /* 3894234Smckusick * Compute/validate number of cylinder groups. 3904234Smckusick */ 3914234Smckusick sblock.fs_ncg = sblock.fs_ncyl / sblock.fs_cpg; 3924234Smckusick if (sblock.fs_ncyl % sblock.fs_cpg) 3934234Smckusick sblock.fs_ncg++; 3944234Smckusick /* 3954234Smckusick * Compute number of inode blocks per cylinder group. 3964234Smckusick */ 397*32120Smckusick sblock.fs_ipg = roundup(inospercg, INOPB(&sblock)); 398*32120Smckusick if (sblock.fs_ipg > MAXIPG) { 399*32120Smckusick printf("newfs: panic fs_ipg > MAXIPG"); 400*32120Smckusick exit(3); 401*32120Smckusick } 4025362Smckusic sblock.fs_dblkno = sblock.fs_iblkno + sblock.fs_ipg / INOPF(&sblock); 4036532Smckusick i = MIN(~sblock.fs_cgmask, sblock.fs_ncg - 1); 4046532Smckusick if (cgdmin(&sblock, i) - cgbase(&sblock, i) >= sblock.fs_fpg) { 4054234Smckusick printf("inode blocks/cyl group (%d) >= data blocks (%d)\n", 4066532Smckusick cgdmin(&sblock, i) - cgbase(&sblock, i) / sblock.fs_frag, 4075324Smckusic sblock.fs_fpg / sblock.fs_frag); 408*32120Smckusick printf("number of cylinders per cylinder group (%d) %s.\n", 409*32120Smckusick sblock.fs_ncg, "must be increased"); 4105324Smckusic exit(1); 4115324Smckusic } 4126532Smckusick j = sblock.fs_ncg - 1; 4136532Smckusick if ((i = fssize - j * sblock.fs_fpg) < sblock.fs_fpg && 4146532Smckusick cgdmin(&sblock, j) - cgbase(&sblock, j) > i) { 4156532Smckusick printf("Warning: inode blocks/cyl group (%d) >= data blocks (%d) in last\n", 4166532Smckusick (cgdmin(&sblock, j) - cgbase(&sblock, j)) / sblock.fs_frag, 4176532Smckusick i / sblock.fs_frag); 4186532Smckusick printf(" cylinder group. This implies %d sector(s) cannot be allocated.\n", 4196532Smckusick i * NSPF(&sblock)); 4206532Smckusick sblock.fs_ncg--; 4216532Smckusick sblock.fs_ncyl -= sblock.fs_ncyl % sblock.fs_cpg; 4226532Smckusick sblock.fs_size = fssize = sblock.fs_ncyl * sblock.fs_spc / 4236532Smckusick NSPF(&sblock); 4246532Smckusick warn = 0; 4256532Smckusick } 4266532Smckusick if (warn) { 4276532Smckusick printf("Warning: %d sector(s) in last cylinder unallocated\n", 4286532Smckusick sblock.fs_spc - 4296532Smckusick (fssize * NSPF(&sblock) - (sblock.fs_ncyl - 1) 4306532Smckusick * sblock.fs_spc)); 4316532Smckusick } 4325336Smckusic /* 4335336Smckusic * fill in remaining fields of the super block 4345336Smckusic */ 4355383Smckusic sblock.fs_csaddr = cgdmin(&sblock, 0); 4366532Smckusick sblock.fs_cssize = 4376532Smckusick fragroundup(&sblock, sblock.fs_ncg * sizeof(struct csum)); 43810076Smckusick i = sblock.fs_bsize / sizeof(struct csum); 43910076Smckusick sblock.fs_csmask = ~(i - 1); 44010076Smckusick for (sblock.fs_csshift = 0; i > 1; i >>= 1) 44110076Smckusick sblock.fs_csshift++; 44210076Smckusick i = sizeof(struct fs) + 44310076Smckusick howmany(sblock.fs_spc * sblock.fs_cpc, NSPB(&sblock)); 44410076Smckusick sblock.fs_sbsize = fragroundup(&sblock, i); 4456532Smckusick fscs = (struct csum *)calloc(1, sblock.fs_cssize); 4465362Smckusic sblock.fs_magic = FS_MAGIC; 44730381Smckusick sblock.fs_rotdelay = rotdelay; 44830381Smckusick sblock.fs_minfree = minfree; 44930381Smckusick sblock.fs_maxcontig = maxcontig; 45030386Smckusick sblock.fs_headswitch = headswitch; 45130386Smckusick sblock.fs_trkseek = trackseek; 4528259Smckusick sblock.fs_maxbpg = MAXBLKPG(&sblock); 45330381Smckusick sblock.fs_rps = rpm / 60; 45430381Smckusick sblock.fs_optim = opt; 4555336Smckusic sblock.fs_cgrotor = 0; 4565336Smckusic sblock.fs_cstotal.cs_ndir = 0; 4575336Smckusic sblock.fs_cstotal.cs_nbfree = 0; 4585336Smckusic sblock.fs_cstotal.cs_nifree = 0; 4595336Smckusic sblock.fs_cstotal.cs_nffree = 0; 4604234Smckusick sblock.fs_fmod = 0; 4614234Smckusick sblock.fs_ronly = 0; 4624234Smckusick /* 4635336Smckusic * Dump out summary information about file system. 4644234Smckusick */ 4654234Smckusick printf("%s:\t%d sectors in %d cylinders of %d tracks, %d sectors\n", 4665336Smckusic fsys, sblock.fs_size * NSPF(&sblock), sblock.fs_ncyl, 4675324Smckusic sblock.fs_ntrak, sblock.fs_nsect); 4684234Smckusick printf("\t%.1fMb in %d cyl groups (%d c/g, %.2fMb/g, %d i/g)\n", 4695324Smckusic (float)sblock.fs_size * sblock.fs_fsize * 1e-6, sblock.fs_ncg, 4705324Smckusic sblock.fs_cpg, (float)sblock.fs_fpg * sblock.fs_fsize * 1e-6, 4715324Smckusic sblock.fs_ipg); 4724234Smckusick /* 4734234Smckusick * Now build the cylinders group blocks and 4745336Smckusic * then print out indices of cylinder groups. 4754234Smckusick */ 4766532Smckusick printf("super-block backups (for fsck -b#) at:"); 4776532Smckusick for (cylno = 0; cylno < sblock.fs_ncg; cylno++) { 4785362Smckusic initcg(cylno); 479*32120Smckusick if (cylno % 9 == 0) 4806532Smckusick printf("\n"); 4816532Smckusick printf(" %d,", fsbtodb(&sblock, cgsblock(&sblock, cylno))); 4826532Smckusick } 48311525Ssam printf("\n"); 48416944Smckusick if (Nflag) 48516944Smckusick exit(0); 4864234Smckusick /* 4875336Smckusic * Now construct the initial file system, 4884234Smckusick * then write out the super-block. 4894234Smckusick */ 4905336Smckusic fsinit(); 4914234Smckusick sblock.fs_time = utime; 49230691Skarels wtfs(SBOFF / sectorsize, sbsize, (char *)&sblock); 4935324Smckusic for (i = 0; i < sblock.fs_cssize; i += sblock.fs_bsize) 4945955Smckusic wtfs(fsbtodb(&sblock, sblock.fs_csaddr + numfrags(&sblock, i)), 4956532Smckusick sblock.fs_cssize - i < sblock.fs_bsize ? 4966532Smckusick sblock.fs_cssize - i : sblock.fs_bsize, 4976532Smckusick ((char *)fscs) + i); 4985336Smckusic /* 4995336Smckusic * Write out the duplicate super blocks 5005336Smckusic */ 5018295Smckusick for (cylno = 0; cylno < sblock.fs_ncg; cylno++) 5026532Smckusick wtfs(fsbtodb(&sblock, cgsblock(&sblock, cylno)), 50330691Skarels sbsize, (char *)&sblock); 50430381Smckusick /* 50530381Smckusick * Update information about this partion in pack 50630381Smckusick * label, to that it may be updated on disk. 50730381Smckusick */ 50830381Smckusick pp->p_fstype = FS_BSDFFS; 50930381Smckusick pp->p_fsize = sblock.fs_fsize; 51030381Smckusick pp->p_frag = sblock.fs_frag; 51130381Smckusick pp->p_cpg = sblock.fs_cpg; 5124234Smckusick } 5134234Smckusick 5144234Smckusick /* 5154234Smckusick * Initialize a cylinder group. 5164234Smckusick */ 5175362Smckusic initcg(cylno) 5185362Smckusic int cylno; 5194234Smckusick { 5206532Smckusick daddr_t cbase, d, dlower, dupper, dmax; 5214234Smckusick long i, j, s; 5224234Smckusick register struct csum *cs; 5234234Smckusick 5244234Smckusick /* 5254234Smckusick * Determine block bounds for cylinder group. 5264234Smckusick * Allow space for super block summary information in first 5274234Smckusick * cylinder group. 5284234Smckusick */ 5295383Smckusic cbase = cgbase(&sblock, cylno); 5304234Smckusick dmax = cbase + sblock.fs_fpg; 5314234Smckusick if (dmax > sblock.fs_size) 5324234Smckusick dmax = sblock.fs_size; 5336532Smckusick dlower = cgsblock(&sblock, cylno) - cbase; 5346532Smckusick dupper = cgdmin(&sblock, cylno) - cbase; 5355362Smckusic cs = fscs + cylno; 5364234Smckusick acg.cg_time = utime; 5374234Smckusick acg.cg_magic = CG_MAGIC; 5385362Smckusic acg.cg_cgx = cylno; 5398139Smckusick if (cylno == sblock.fs_ncg - 1) 5408139Smckusick acg.cg_ncyl = sblock.fs_ncyl % sblock.fs_cpg; 5418139Smckusick else 5428139Smckusick acg.cg_ncyl = sblock.fs_cpg; 5434234Smckusick acg.cg_niblk = sblock.fs_ipg; 5444234Smckusick acg.cg_ndblk = dmax - cbase; 5454788Smckusic acg.cg_cs.cs_ndir = 0; 5464788Smckusic acg.cg_cs.cs_nffree = 0; 5474788Smckusic acg.cg_cs.cs_nbfree = 0; 5484788Smckusic acg.cg_cs.cs_nifree = 0; 5496532Smckusick acg.cg_rotor = 0; 5506532Smckusick acg.cg_frotor = 0; 5514257Smckusic acg.cg_irotor = 0; 5525324Smckusic for (i = 0; i < sblock.fs_frag; i++) { 5534465Smckusic acg.cg_frsum[i] = 0; 5544465Smckusic } 5554465Smckusic for (i = 0; i < sblock.fs_ipg; ) { 5565324Smckusic for (j = INOPB(&sblock); j > 0; j--) { 5574234Smckusick clrbit(acg.cg_iused, i); 5584234Smckusick i++; 5594234Smckusick } 5605324Smckusic acg.cg_cs.cs_nifree += INOPB(&sblock); 5614234Smckusick } 5625362Smckusic if (cylno == 0) 5635336Smckusic for (i = 0; i < ROOTINO; i++) { 5645336Smckusic setbit(acg.cg_iused, i); 5655336Smckusic acg.cg_cs.cs_nifree--; 5665336Smckusic } 5674234Smckusick while (i < MAXIPG) { 5684234Smckusick clrbit(acg.cg_iused, i); 5694234Smckusick i++; 5704234Smckusick } 57116944Smckusick wtfs(fsbtodb(&sblock, cgimin(&sblock, cylno)), 57216944Smckusick sblock.fs_ipg * sizeof (struct dinode), (char *)zino); 5735370Smckusic for (i = 0; i < MAXCPG; i++) { 5745370Smckusic acg.cg_btot[i] = 0; 5754234Smckusick for (j = 0; j < NRPOS; j++) 5764234Smckusick acg.cg_b[i][j] = 0; 5775370Smckusic } 5785362Smckusic if (cylno == 0) { 5796532Smckusick /* 5806532Smckusick * reserve space for summary info and Boot block 5816532Smckusick */ 5826532Smckusick dupper += howmany(sblock.fs_cssize, sblock.fs_fsize); 5836532Smckusick for (d = 0; d < dlower; d += sblock.fs_frag) 5846532Smckusick clrblock(&sblock, acg.cg_free, d/sblock.fs_frag); 5856532Smckusick } else { 5866532Smckusick for (d = 0; d < dlower; d += sblock.fs_frag) { 5876532Smckusick setblock(&sblock, acg.cg_free, d/sblock.fs_frag); 5886532Smckusick acg.cg_cs.cs_nbfree++; 5896532Smckusick acg.cg_btot[cbtocylno(&sblock, d)]++; 5906532Smckusick acg.cg_b[cbtocylno(&sblock, d)][cbtorpos(&sblock, d)]++; 5916532Smckusick } 5926532Smckusick sblock.fs_dsize += dlower; 5934234Smckusick } 5946532Smckusick sblock.fs_dsize += acg.cg_ndblk - dupper; 5956532Smckusick for (; d < dupper; d += sblock.fs_frag) 5965324Smckusic clrblock(&sblock, acg.cg_free, d/sblock.fs_frag); 5976532Smckusick if (d > dupper) { 5986532Smckusick acg.cg_frsum[d - dupper]++; 5996532Smckusick for (i = d - 1; i >= dupper; i--) { 6006532Smckusick setbit(acg.cg_free, i); 6016532Smckusick acg.cg_cs.cs_nffree++; 6026532Smckusick } 6036532Smckusick } 6046532Smckusick while ((d + sblock.fs_frag) <= dmax - cbase) { 6055324Smckusic setblock(&sblock, acg.cg_free, d/sblock.fs_frag); 6064788Smckusic acg.cg_cs.cs_nbfree++; 6075370Smckusic acg.cg_btot[cbtocylno(&sblock, d)]++; 6085362Smckusic acg.cg_b[cbtocylno(&sblock, d)][cbtorpos(&sblock, d)]++; 6095324Smckusic d += sblock.fs_frag; 6104234Smckusick } 6116532Smckusick if (d < dmax - cbase) { 6125362Smckusic acg.cg_frsum[dmax - cbase - d]++; 6134251Smckusic for (; d < dmax - cbase; d++) { 6144251Smckusic setbit(acg.cg_free, d); 6154788Smckusic acg.cg_cs.cs_nffree++; 6164251Smckusic } 6178139Smckusick for (; d % sblock.fs_frag != 0; d++) 6188139Smckusick clrbit(acg.cg_free, d); 6196532Smckusick } 6208139Smckusick for (d /= sblock.fs_frag; d < MAXBPG(&sblock); d ++) 6218139Smckusick clrblock(&sblock, acg.cg_free, d); 6224788Smckusic sblock.fs_cstotal.cs_ndir += acg.cg_cs.cs_ndir; 6234788Smckusic sblock.fs_cstotal.cs_nffree += acg.cg_cs.cs_nffree; 6244788Smckusic sblock.fs_cstotal.cs_nbfree += acg.cg_cs.cs_nbfree; 6254788Smckusic sblock.fs_cstotal.cs_nifree += acg.cg_cs.cs_nifree; 6264788Smckusic *cs = acg.cg_cs; 6275383Smckusic wtfs(fsbtodb(&sblock, cgtod(&sblock, cylno)), 6285324Smckusic sblock.fs_bsize, (char *)&acg); 6294234Smckusick } 6304234Smckusick 6315336Smckusic /* 6325336Smckusic * initialize the file system 6335336Smckusic */ 6345336Smckusic struct inode node; 63530381Smckusick 63630381Smckusick #ifdef LOSTDIR 6375336Smckusic #define PREDEFDIR 3 63830381Smckusick #else 63930381Smckusick #define PREDEFDIR 2 64030381Smckusick #endif 64130381Smckusick 6425934Smckusic struct direct root_dir[] = { 6435934Smckusic { ROOTINO, sizeof(struct direct), 1, "." }, 6445934Smckusic { ROOTINO, sizeof(struct direct), 2, ".." }, 64530381Smckusick #ifdef LOSTDIR 6465934Smckusic { LOSTFOUNDINO, sizeof(struct direct), 10, "lost+found" }, 64730381Smckusick #endif 6485336Smckusic }; 64930381Smckusick #ifdef LOSTDIR 6505934Smckusic struct direct lost_found_dir[] = { 6515934Smckusic { LOSTFOUNDINO, sizeof(struct direct), 1, "." }, 6525934Smckusic { ROOTINO, sizeof(struct direct), 2, ".." }, 6535934Smckusic { 0, DIRBLKSIZ, 0, 0 }, 6545336Smckusic }; 65530381Smckusick #endif 6565934Smckusic char buf[MAXBSIZE]; 6575336Smckusic 6585336Smckusic fsinit() 6594234Smckusick { 6605934Smckusic int i; 6615934Smckusic 6624234Smckusick /* 6635336Smckusic * initialize the node 6644234Smckusick */ 6655336Smckusic node.i_atime = utime; 6665336Smckusic node.i_mtime = utime; 6675336Smckusic node.i_ctime = utime; 66830381Smckusick #ifdef LOSTDIR 6694234Smckusick /* 6705336Smckusic * create the lost+found directory 6714234Smckusick */ 6725934Smckusic (void)makedir(lost_found_dir, 2); 6735934Smckusic for (i = DIRBLKSIZ; i < sblock.fs_bsize; i += DIRBLKSIZ) 6745934Smckusic bcopy(&lost_found_dir[2], &buf[i], DIRSIZ(&lost_found_dir[2])); 6755336Smckusic node.i_number = LOSTFOUNDINO; 6765336Smckusic node.i_mode = IFDIR | UMASK; 6775336Smckusic node.i_nlink = 2; 6785336Smckusic node.i_size = sblock.fs_bsize; 6795336Smckusic node.i_db[0] = alloc(node.i_size, node.i_mode); 68014323Smckusick node.i_blocks = btodb(fragroundup(&sblock, node.i_size)); 6815934Smckusic wtfs(fsbtodb(&sblock, node.i_db[0]), node.i_size, buf); 6825336Smckusic iput(&node); 68330381Smckusick #endif 6845336Smckusic /* 6855336Smckusic * create the root directory 6865336Smckusic */ 6875336Smckusic node.i_number = ROOTINO; 6885336Smckusic node.i_mode = IFDIR | UMASK; 6895336Smckusic node.i_nlink = PREDEFDIR; 6905934Smckusic node.i_size = makedir(root_dir, PREDEFDIR); 6915336Smckusic node.i_db[0] = alloc(sblock.fs_fsize, node.i_mode); 69214323Smckusick node.i_blocks = btodb(fragroundup(&sblock, node.i_size)); 6935934Smckusic wtfs(fsbtodb(&sblock, node.i_db[0]), sblock.fs_fsize, buf); 6945336Smckusic iput(&node); 6954234Smckusick } 6964234Smckusick 6975336Smckusic /* 6985934Smckusic * construct a set of directory entries in "buf". 6995934Smckusic * return size of directory. 7005934Smckusic */ 7015934Smckusic makedir(protodir, entries) 7025934Smckusic register struct direct *protodir; 7035934Smckusic int entries; 7045934Smckusic { 7055934Smckusic char *cp; 7065934Smckusic int i, spcleft; 7075934Smckusic 7085934Smckusic spcleft = DIRBLKSIZ; 7095934Smckusic for (cp = buf, i = 0; i < entries - 1; i++) { 7105934Smckusic protodir[i].d_reclen = DIRSIZ(&protodir[i]); 7115934Smckusic bcopy(&protodir[i], cp, protodir[i].d_reclen); 7125934Smckusic cp += protodir[i].d_reclen; 7135934Smckusic spcleft -= protodir[i].d_reclen; 7145934Smckusic } 7155934Smckusic protodir[i].d_reclen = spcleft; 7165934Smckusic bcopy(&protodir[i], cp, DIRSIZ(&protodir[i])); 71723848Smckusick return (DIRBLKSIZ); 7185934Smckusic } 7195934Smckusic 7205934Smckusic /* 7215336Smckusic * allocate a block or frag 7225336Smckusic */ 7234234Smckusick daddr_t 7244427Smckusic alloc(size, mode) 7254427Smckusic int size; 7264427Smckusic int mode; 7274234Smckusick { 7285362Smckusic int i, frag; 7294234Smckusick daddr_t d; 7304234Smckusick 7315955Smckusic rdfs(fsbtodb(&sblock, cgtod(&sblock, 0)), sblock.fs_cgsize, 7325955Smckusic (char *)&acg); 7336532Smckusick if (acg.cg_magic != CG_MAGIC) { 7346532Smckusick printf("cg 0: bad magic number\n"); 7356532Smckusick return (0); 7366532Smckusick } 7374788Smckusic if (acg.cg_cs.cs_nbfree == 0) { 7384234Smckusick printf("first cylinder group ran out of space\n"); 7394234Smckusick return (0); 7404234Smckusick } 7415324Smckusic for (d = 0; d < acg.cg_ndblk; d += sblock.fs_frag) 7425324Smckusic if (isblock(&sblock, acg.cg_free, d / sblock.fs_frag)) 7434234Smckusick goto goth; 7444234Smckusick printf("internal error: can't find block in cyl 0\n"); 7454234Smckusick return (0); 7464234Smckusick goth: 7475324Smckusic clrblock(&sblock, acg.cg_free, d / sblock.fs_frag); 7484788Smckusic acg.cg_cs.cs_nbfree--; 7494788Smckusic sblock.fs_cstotal.cs_nbfree--; 7504234Smckusick fscs[0].cs_nbfree--; 7514427Smckusic if (mode & IFDIR) { 7524788Smckusic acg.cg_cs.cs_ndir++; 7534788Smckusic sblock.fs_cstotal.cs_ndir++; 7544427Smckusic fscs[0].cs_ndir++; 7554427Smckusic } 7565370Smckusic acg.cg_btot[cbtocylno(&sblock, d)]--; 7575362Smckusic acg.cg_b[cbtocylno(&sblock, d)][cbtorpos(&sblock, d)]--; 7585324Smckusic if (size != sblock.fs_bsize) { 7595324Smckusic frag = howmany(size, sblock.fs_fsize); 7605324Smckusic fscs[0].cs_nffree += sblock.fs_frag - frag; 7615324Smckusic sblock.fs_cstotal.cs_nffree += sblock.fs_frag - frag; 7625324Smckusic acg.cg_cs.cs_nffree += sblock.fs_frag - frag; 7635324Smckusic acg.cg_frsum[sblock.fs_frag - frag]++; 7645324Smckusic for (i = frag; i < sblock.fs_frag; i++) 7656532Smckusick setbit(acg.cg_free, d + i); 7664234Smckusick } 7675955Smckusic wtfs(fsbtodb(&sblock, cgtod(&sblock, 0)), sblock.fs_cgsize, 7685955Smckusic (char *)&acg); 7694234Smckusick return (d); 7704234Smckusick } 7714234Smckusick 7725336Smckusic /* 7735336Smckusic * Allocate an inode on the disk 7745336Smckusic */ 7755336Smckusic iput(ip) 7765336Smckusic register struct inode *ip; 7774234Smckusick { 7785336Smckusic struct dinode buf[MAXINOPB]; 7795336Smckusic daddr_t d; 7805336Smckusic int c; 7814234Smckusick 7825383Smckusic c = itog(&sblock, ip->i_number); 7835955Smckusic rdfs(fsbtodb(&sblock, cgtod(&sblock, 0)), sblock.fs_cgsize, 7845955Smckusic (char *)&acg); 7856532Smckusick if (acg.cg_magic != CG_MAGIC) { 7866532Smckusick printf("cg 0: bad magic number\n"); 7876532Smckusick exit(1); 7886532Smckusick } 7895336Smckusic acg.cg_cs.cs_nifree--; 7905336Smckusic setbit(acg.cg_iused, ip->i_number); 7915955Smckusic wtfs(fsbtodb(&sblock, cgtod(&sblock, 0)), sblock.fs_cgsize, 7925955Smckusic (char *)&acg); 7935336Smckusic sblock.fs_cstotal.cs_nifree--; 7945336Smckusic fscs[0].cs_nifree--; 7955336Smckusic if(ip->i_number >= sblock.fs_ipg * sblock.fs_ncg) { 7965336Smckusic printf("fsinit: inode value out of range (%d).\n", 7975336Smckusic ip->i_number); 7985336Smckusic exit(1); 7995336Smckusic } 8005383Smckusic d = fsbtodb(&sblock, itod(&sblock, ip->i_number)); 8015336Smckusic rdfs(d, sblock.fs_bsize, buf); 8025383Smckusic buf[itoo(&sblock, ip->i_number)].di_ic = ip->i_ic; 8035336Smckusic wtfs(d, sblock.fs_bsize, buf); 8044234Smckusick } 8054234Smckusick 8065336Smckusic /* 8075336Smckusic * read a block from the file system 8085336Smckusic */ 8095336Smckusic rdfs(bno, size, bf) 8105336Smckusic daddr_t bno; 8114427Smckusic int size; 8125336Smckusic char *bf; 8134234Smckusick { 8145336Smckusic int n; 8154234Smckusick 81630381Smckusick if (lseek(fsi, bno * sectorsize, 0) < 0) { 8175346Smckusic printf("seek error: %ld\n", bno); 8185346Smckusic perror("rdfs"); 8195346Smckusic exit(1); 8205346Smckusic } 8215336Smckusic n = read(fsi, bf, size); 8225336Smckusic if(n != size) { 8235336Smckusic printf("read error: %ld\n", bno); 8245346Smckusic perror("rdfs"); 8255336Smckusic exit(1); 8264234Smckusick } 8274234Smckusick } 8284234Smckusick 8295336Smckusic /* 8305336Smckusic * write a block to the file system 8315336Smckusic */ 8325336Smckusic wtfs(bno, size, bf) 8335336Smckusic daddr_t bno; 8345336Smckusic int size; 8355336Smckusic char *bf; 8364234Smckusick { 8375336Smckusic int n; 8384234Smckusick 83916944Smckusick if (Nflag) 84016944Smckusick return; 84130381Smckusick if (lseek(fso, bno * sectorsize, 0) < 0) { 8425346Smckusic printf("seek error: %ld\n", bno); 8435346Smckusic perror("wtfs"); 8445346Smckusic exit(1); 8455346Smckusic } 8465336Smckusic n = write(fso, bf, size); 8475336Smckusic if(n != size) { 8485336Smckusic printf("write error: %D\n", bno); 8495346Smckusic perror("wtfs"); 8504234Smckusick exit(1); 8514234Smckusick } 8524234Smckusick } 8535324Smckusic 8545324Smckusic /* 8555336Smckusic * check if a block is available 8565324Smckusic */ 8575324Smckusic isblock(fs, cp, h) 8585324Smckusic struct fs *fs; 8595324Smckusic unsigned char *cp; 8605324Smckusic int h; 8615324Smckusic { 8625324Smckusic unsigned char mask; 8635324Smckusic 8645324Smckusic switch (fs->fs_frag) { 8655324Smckusic case 8: 8665324Smckusic return (cp[h] == 0xff); 8675324Smckusic case 4: 8685324Smckusic mask = 0x0f << ((h & 0x1) << 2); 8695324Smckusic return ((cp[h >> 1] & mask) == mask); 8705324Smckusic case 2: 8715324Smckusic mask = 0x03 << ((h & 0x3) << 1); 8725324Smckusic return ((cp[h >> 2] & mask) == mask); 8735324Smckusic case 1: 8745324Smckusic mask = 0x01 << (h & 0x7); 8755324Smckusic return ((cp[h >> 3] & mask) == mask); 8765324Smckusic default: 8778140Smckusick #ifdef STANDALONE 8788140Smckusick printf("isblock bad fs_frag %d\n", fs->fs_frag); 8798140Smckusick #else 8805324Smckusic fprintf(stderr, "isblock bad fs_frag %d\n", fs->fs_frag); 8818140Smckusick #endif 8825324Smckusic return; 8835324Smckusic } 8845324Smckusic } 8855324Smckusic 8865336Smckusic /* 8875336Smckusic * take a block out of the map 8885336Smckusic */ 8895324Smckusic clrblock(fs, cp, h) 8905324Smckusic struct fs *fs; 8915324Smckusic unsigned char *cp; 8925324Smckusic int h; 8935324Smckusic { 8945324Smckusic switch ((fs)->fs_frag) { 8955324Smckusic case 8: 8965324Smckusic cp[h] = 0; 8975324Smckusic return; 8985324Smckusic case 4: 8995324Smckusic cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2)); 9005324Smckusic return; 9015324Smckusic case 2: 9025324Smckusic cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1)); 9035324Smckusic return; 9045324Smckusic case 1: 9055324Smckusic cp[h >> 3] &= ~(0x01 << (h & 0x7)); 9065324Smckusic return; 9075324Smckusic default: 9088140Smckusick #ifdef STANDALONE 9098140Smckusick printf("clrblock bad fs_frag %d\n", fs->fs_frag); 9108140Smckusick #else 9115324Smckusic fprintf(stderr, "clrblock bad fs_frag %d\n", fs->fs_frag); 9128140Smckusick #endif 9135324Smckusic return; 9145324Smckusic } 9155324Smckusic } 9165324Smckusic 9175336Smckusic /* 9185336Smckusic * put a block into the map 9195336Smckusic */ 9205324Smckusic setblock(fs, cp, h) 9215324Smckusic struct fs *fs; 9225324Smckusic unsigned char *cp; 9235324Smckusic int h; 9245324Smckusic { 9255324Smckusic switch (fs->fs_frag) { 9265324Smckusic case 8: 9275324Smckusic cp[h] = 0xff; 9285324Smckusic return; 9295324Smckusic case 4: 9305324Smckusic cp[h >> 1] |= (0x0f << ((h & 0x1) << 2)); 9315324Smckusic return; 9325324Smckusic case 2: 9335324Smckusic cp[h >> 2] |= (0x03 << ((h & 0x3) << 1)); 9345324Smckusic return; 9355324Smckusic case 1: 9365324Smckusic cp[h >> 3] |= (0x01 << (h & 0x7)); 9375324Smckusic return; 9385324Smckusic default: 9398140Smckusick #ifdef STANDALONE 9408140Smckusick printf("setblock bad fs_frag %d\n", fs->fs_frag); 9418140Smckusick #else 9425324Smckusic fprintf(stderr, "setblock bad fs_frag %d\n", fs->fs_frag); 9438140Smckusick #endif 9445324Smckusic return; 9455324Smckusic } 9465324Smckusic } 947