1*21137Sdist /* 2*21137Sdist * Copyright (c) 1980 Regents of the University of California. 3*21137Sdist * All rights reserved. The Berkeley software License Agreement 4*21137Sdist * specifies the terms and conditions for redistribution. 5*21137Sdist */ 6*21137Sdist 713604Ssam #ifndef lint 8*21137Sdist char copyright[] = 9*21137Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 10*21137Sdist All rights reserved.\n"; 11*21137Sdist #endif not lint 124234Smckusick 13*21137Sdist #ifndef lint 14*21137Sdist static char sccsid[] = "@(#)mkfs.c 5.1 (Berkeley) 05/28/85"; 15*21137Sdist #endif not lint 16*21137Sdist 174234Smckusick /* 184234Smckusick * make file system for cylinder-group style file systems 194234Smckusick * 2016944Smckusick * usage: mkfs -N special size [ nsect ntrak bsize fsize cpg minfree rps nbpi ] 214234Smckusick */ 224234Smckusick 238259Smckusick /* 248259Smckusick * The following constants set the defaults used for the number 258259Smckusick * of sectors (fs_nsect), and number of tracks (fs_ntrak). 268259Smckusick */ 278259Smckusick #define DFLNSECT 32 288259Smckusick #define DFLNTRAK 16 298259Smckusick 308259Smckusick /* 318259Smckusick * The following two constants set the default block and fragment sizes. 328259Smckusick * Both constants must be a power of 2 and meet the following constraints: 338259Smckusick * MINBSIZE <= DESBLKSIZE <= MAXBSIZE 348259Smckusick * DEV_BSIZE <= DESFRAGSIZE <= DESBLKSIZE 358259Smckusick * DESBLKSIZE / DESFRAGSIZE <= 8 368259Smckusick */ 378259Smckusick #define DESBLKSIZE 8192 388259Smckusick #define DESFRAGSIZE 1024 398259Smckusick 408259Smckusick /* 418259Smckusick * Cylinder groups may have up to MAXCPG cylinders. The actual 428259Smckusick * number used depends upon how much information can be stored 438259Smckusick * on a single cylinder. The default is to used 16 cylinders 448259Smckusick * per group. 458259Smckusick */ 468259Smckusick #define DESCPG 16 /* desired fs_cpg */ 478259Smckusick 488259Smckusick /* 498259Smckusick * MINFREE gives the minimum acceptable percentage of file system 508259Smckusick * blocks which may be free. If the freelist drops below this level 518259Smckusick * only the superuser may continue to allocate blocks. This may 528259Smckusick * be set to 0 if no reserve of free blocks is deemed necessary, 538259Smckusick * however throughput drops by fifty percent if the file system 548259Smckusick * is run at between 90% and 100% full; thus the default value of 558259Smckusick * fs_minfree is 10%. 568259Smckusick */ 578259Smckusick #define MINFREE 10 588259Smckusick 598259Smckusick /* 608259Smckusick * ROTDELAY gives the minimum number of milliseconds to initiate 618259Smckusick * another disk transfer on the same cylinder. It is used in 628259Smckusick * determining the rotationally optimal layout for disk blocks 6313781Smckusick * within a file; the default of fs_rotdelay is 4ms. 648259Smckusick */ 6513781Smckusick #define ROTDELAY 4 668259Smckusick 678259Smckusick /* 688259Smckusick * MAXCONTIG sets the default for the maximum number of blocks 698259Smckusick * that may be allocated sequentially. Since UNIX drivers are 708259Smckusick * not capable of scheduling multi-block transfers, this defaults 718259Smckusick * to 1 (ie no contiguous blocks are allocated). 728259Smckusick */ 738259Smckusick #define MAXCONTIG 1 748259Smckusick 758259Smckusick /* 768259Smckusick * MAXBLKPG determines the maximum number of data blocks which are 778259Smckusick * placed in a single cylinder group. This is currently a function 788259Smckusick * of the block and fragment size of the file system. 798259Smckusick */ 808259Smckusick #define MAXBLKPG(fs) ((fs)->fs_fsize / sizeof(daddr_t)) 818259Smckusick 828259Smckusick /* 838259Smckusick * Each file system has a number of inodes statically allocated. 848259Smckusick * We allocate one inode slot per NBPI bytes, expecting this 858259Smckusick * to be far more than we will ever need. 868259Smckusick */ 878259Smckusick #define NBPI 2048 888259Smckusick 8911068Ssam /* 9011068Ssam * Disks are assumed to rotate at 60HZ, unless otherwise specified. 9111068Ssam */ 9211068Ssam #define DEFHZ 60 9311068Ssam 944234Smckusick #ifndef STANDALONE 954234Smckusick #include <stdio.h> 964234Smckusick #include <a.out.h> 974234Smckusick #endif 984234Smckusick 996495Smckusick #include <sys/param.h> 1006495Smckusick #include <sys/inode.h> 1016495Smckusick #include <sys/fs.h> 10213604Ssam #include <sys/dir.h> 1034234Smckusick 1045336Smckusic #define UMASK 0755 1055346Smckusic #define MAXINOPB (MAXBSIZE / sizeof(struct dinode)) 1065336Smckusic #define POWEROF2(num) (((num) & ((num) - 1)) == 0) 1074234Smckusick 1084234Smckusick union { 1094234Smckusick struct fs fs; 1105324Smckusic char pad[MAXBSIZE]; 1114234Smckusick } fsun; 1124234Smckusick #define sblock fsun.fs 1134234Smckusick struct csum *fscs; 1144234Smckusick 1154234Smckusick union { 1164234Smckusick struct cg cg; 1175324Smckusic char pad[MAXBSIZE]; 1184234Smckusick } cgun; 1194234Smckusick #define acg cgun.cg 1204234Smckusick 1215336Smckusic struct dinode zino[MAXIPG]; 1225336Smckusic 1234234Smckusick char *fsys; 1245336Smckusic time_t utime; 1255336Smckusic int fsi; 1265336Smckusic int fso; 12716944Smckusick int Nflag; 1284234Smckusick daddr_t alloc(); 1294234Smckusick 1304234Smckusick main(argc, argv) 1315324Smckusic int argc; 1325324Smckusic char *argv[]; 1334234Smckusick { 1346532Smckusick long cylno, rpos, blk, i, j, inos, fssize, warn = 0; 1354234Smckusick 1365336Smckusic #ifndef STANDALONE 1374234Smckusick argc--, argv++; 13816944Smckusick if (argv[0][0] == '-') { 13916944Smckusick switch (argv[0][1]) { 14016944Smckusick case 'N': 14116944Smckusick Nflag++; 14216944Smckusick break; 14316944Smckusick default: 14416944Smckusick printf("%s: unknown flag\n", &argv[0][1]); 14516944Smckusick argc = 1; /* force usage message */ 14616944Smckusick break; 14716944Smckusick } 14816944Smckusick argc--, argv++; 14916944Smckusick } 1504234Smckusick time(&utime); 1515336Smckusic if (argc < 2) { 15216944Smckusick printf("usage: mkfs -N special size [ nsect ntrak bsize fsize cpg minfree rps nbpi ]\n"); 1534234Smckusick exit(1); 1544234Smckusick } 1554234Smckusick fsys = argv[0]; 1565336Smckusic fssize = atoi(argv[1]); 15716944Smckusick if (!Nflag) { 15816944Smckusick fso = creat(fsys, 0666); 15916944Smckusick if(fso < 0) { 16016944Smckusick printf("%s: cannot create\n", fsys); 16116944Smckusick exit(1); 16216944Smckusick } 1635336Smckusic } 1645336Smckusic fsi = open(fsys, 0); 1655336Smckusic if(fsi < 0) { 1665336Smckusic printf("%s: cannot open\n", fsys); 1675336Smckusic exit(1); 1685336Smckusic } 1694234Smckusick #else 1704234Smckusick { 1714234Smckusick static char protos[60]; 1725336Smckusic char fsbuf[100]; 1734234Smckusick 1744234Smckusick printf("file sys size: "); 1754234Smckusick gets(protos); 1765336Smckusic fssize = atoi(protos); 1774234Smckusick do { 1784234Smckusick printf("file system: "); 1794234Smckusick gets(fsbuf); 1804234Smckusick fso = open(fsbuf, 1); 1814234Smckusick fsi = open(fsbuf, 0); 1824234Smckusick } while (fso < 0 || fsi < 0); 1834234Smckusick } 1844234Smckusick argc = 0; 1855336Smckusic #endif 18612252Smckusick /* 18712252Smckusick * Validate the given file system size. 18812252Smckusick * Verify that its last block can actually be accessed. 18912252Smckusick */ 1905336Smckusic if (fssize <= 0) 1915336Smckusic printf("preposterous size %d\n", fssize), exit(1); 19212252Smckusick wtfs(fssize - 1, DEV_BSIZE, (char *)&sblock); 1935336Smckusic /* 1945336Smckusic * collect and verify the sector and track info 1955336Smckusic */ 1965336Smckusic if (argc > 2) 1975336Smckusic sblock.fs_nsect = atoi(argv[2]); 1985336Smckusic else 1995336Smckusic sblock.fs_nsect = DFLNSECT; 2005336Smckusic if (argc > 3) 2015336Smckusic sblock.fs_ntrak = atoi(argv[3]); 2025336Smckusic else 2035336Smckusic sblock.fs_ntrak = DFLNTRAK; 2045336Smckusic if (sblock.fs_ntrak <= 0) 2055336Smckusic printf("preposterous ntrak %d\n", sblock.fs_ntrak), exit(1); 2065336Smckusic if (sblock.fs_nsect <= 0) 2075336Smckusic printf("preposterous nsect %d\n", sblock.fs_nsect), exit(1); 2085336Smckusic sblock.fs_spc = sblock.fs_ntrak * sblock.fs_nsect; 2095336Smckusic /* 2105336Smckusic * collect and verify the block and fragment sizes 2115336Smckusic */ 2125336Smckusic if (argc > 4) 2135336Smckusic sblock.fs_bsize = atoi(argv[4]); 2145336Smckusic else 2158259Smckusick sblock.fs_bsize = DESBLKSIZE; 2165336Smckusic if (argc > 5) 2175336Smckusic sblock.fs_fsize = atoi(argv[5]); 2185336Smckusic else 2198259Smckusick sblock.fs_fsize = DESFRAGSIZE; 2205336Smckusic if (!POWEROF2(sblock.fs_bsize)) { 2215336Smckusic printf("block size must be a power of 2, not %d\n", 2225336Smckusic sblock.fs_bsize); 2234234Smckusick exit(1); 2244234Smckusick } 2255336Smckusic if (!POWEROF2(sblock.fs_fsize)) { 2265336Smckusic printf("fragment size must be a power of 2, not %d\n", 2275336Smckusic sblock.fs_fsize); 2284234Smckusick exit(1); 2294234Smckusick } 2305324Smckusic if (sblock.fs_fsize < DEV_BSIZE) { 2315324Smckusic printf("fragment size %d is too small, minimum is %d\n", 2325324Smckusic sblock.fs_fsize, DEV_BSIZE); 2335324Smckusic exit(1); 2345324Smckusic } 2355324Smckusic if (sblock.fs_bsize < MINBSIZE) { 2365324Smckusic printf("block size %d is too small, minimum is %d\n", 2375324Smckusic sblock.fs_bsize, MINBSIZE); 2385324Smckusic exit(1); 2395324Smckusic } 2405336Smckusic if (sblock.fs_bsize < sblock.fs_fsize) { 2415336Smckusic printf("block size (%d) cannot be smaller than fragment size (%d)\n", 2425336Smckusic sblock.fs_bsize, sblock.fs_fsize); 2434234Smckusick exit(1); 2444234Smckusick } 2455955Smckusic sblock.fs_bmask = ~(sblock.fs_bsize - 1); 2465955Smckusic sblock.fs_fmask = ~(sblock.fs_fsize - 1); 2475955Smckusic for (sblock.fs_bshift = 0, i = sblock.fs_bsize; i > 1; i >>= 1) 2485955Smckusic sblock.fs_bshift++; 2495955Smckusic for (sblock.fs_fshift = 0, i = sblock.fs_fsize; i > 1; i >>= 1) 2505955Smckusic sblock.fs_fshift++; 2515955Smckusic sblock.fs_frag = numfrags(&sblock, sblock.fs_bsize); 25210076Smckusick for (sblock.fs_fragshift = 0, i = sblock.fs_frag; i > 1; i >>= 1) 25310076Smckusick sblock.fs_fragshift++; 2545336Smckusic if (sblock.fs_frag > MAXFRAG) { 2555336Smckusic printf("fragment size %d is too small, minimum with block size %d is %d\n", 2565336Smckusic sblock.fs_fsize, sblock.fs_bsize, 2575336Smckusic sblock.fs_bsize / MAXFRAG); 2585336Smckusic exit(1); 2594234Smckusick } 26010076Smckusick sblock.fs_nindir = sblock.fs_bsize / sizeof(daddr_t); 26110076Smckusick sblock.fs_inopb = sblock.fs_bsize / sizeof(struct dinode); 26210076Smckusick sblock.fs_nspf = sblock.fs_fsize / DEV_BSIZE; 26310076Smckusick for (sblock.fs_fsbtodb = 0, i = sblock.fs_nspf; i > 1; i >>= 1) 26410076Smckusick sblock.fs_fsbtodb++; 2656532Smckusick sblock.fs_sblkno = 2665362Smckusic roundup(howmany(BBSIZE + SBSIZE, sblock.fs_fsize), sblock.fs_frag); 2676532Smckusick sblock.fs_cblkno = (daddr_t)(sblock.fs_sblkno + 2686532Smckusick roundup(howmany(SBSIZE, sblock.fs_fsize), sblock.fs_frag)); 2695362Smckusic sblock.fs_iblkno = sblock.fs_cblkno + sblock.fs_frag; 2706532Smckusick sblock.fs_cgoffset = roundup( 2716532Smckusick howmany(sblock.fs_nsect, sblock.fs_fsize / DEV_BSIZE), 2726532Smckusick sblock.fs_frag); 2736532Smckusick for (sblock.fs_cgmask = 0xffffffff, i = sblock.fs_ntrak; i > 1; i >>= 1) 2746532Smckusick sblock.fs_cgmask <<= 1; 2756532Smckusick if (!POWEROF2(sblock.fs_ntrak)) 2766532Smckusick sblock.fs_cgmask <<= 1; 2775399Smckusic for (sblock.fs_cpc = NSPB(&sblock), i = sblock.fs_spc; 2785399Smckusic sblock.fs_cpc > 1 && (i & 1) == 0; 2795399Smckusic sblock.fs_cpc >>= 1, i >>= 1) 2805399Smckusic /* void */; 2815605Smckusic if (sblock.fs_cpc > MAXCPG) { 2825605Smckusic printf("maximum block size with nsect %d and ntrak %d is %d\n", 2835605Smckusic sblock.fs_nsect, sblock.fs_ntrak, 2845605Smckusic sblock.fs_bsize / (sblock.fs_cpc / MAXCPG)); 2855605Smckusic exit(1); 2865605Smckusic } 2875336Smckusic /* 2885336Smckusic * collect and verify the number of cylinders per group 2894234Smckusick */ 2905336Smckusic if (argc > 6) { 2915336Smckusic sblock.fs_cpg = atoi(argv[6]); 2925336Smckusic sblock.fs_fpg = (sblock.fs_cpg * sblock.fs_spc) / NSPF(&sblock); 2934234Smckusick } else { 2945399Smckusic sblock.fs_cpg = MAX(sblock.fs_cpc, DESCPG); 2955336Smckusic sblock.fs_fpg = (sblock.fs_cpg * sblock.fs_spc) / NSPF(&sblock); 2965605Smckusic while (sblock.fs_fpg / sblock.fs_frag > MAXBPG(&sblock) && 2975605Smckusic sblock.fs_cpg > sblock.fs_cpc) { 2985605Smckusic sblock.fs_cpg -= sblock.fs_cpc; 2995336Smckusic sblock.fs_fpg = 3005336Smckusic (sblock.fs_cpg * sblock.fs_spc) / NSPF(&sblock); 3015336Smckusic } 3024234Smckusick } 3035336Smckusic if (sblock.fs_cpg < 1) { 3045336Smckusic printf("cylinder groups must have at least 1 cylinder\n"); 3055336Smckusic exit(1); 3065336Smckusic } 3075336Smckusic if (sblock.fs_cpg > MAXCPG) { 3085336Smckusic printf("cylinder groups are limited to %d cylinders\n", MAXCPG); 3095336Smckusic exit(1); 3105336Smckusic } 3115399Smckusic if (sblock.fs_cpg % sblock.fs_cpc != 0) { 3125399Smckusic printf("cylinder groups must have a multiple of %d cylinders\n", 3135399Smckusic sblock.fs_cpc); 3145399Smckusic exit(1); 3155399Smckusic } 3164234Smckusick /* 3175336Smckusic * Now have size for file system and nsect and ntrak. 3185336Smckusic * Determine number of cylinders and blocks in the file system. 3195336Smckusic */ 3205336Smckusic sblock.fs_size = fssize = dbtofsb(&sblock, fssize); 3215336Smckusic sblock.fs_ncyl = fssize * NSPF(&sblock) / sblock.fs_spc; 3225362Smckusic if (fssize * NSPF(&sblock) > sblock.fs_ncyl * sblock.fs_spc) { 3235362Smckusic sblock.fs_ncyl++; 3246532Smckusick warn = 1; 3255362Smckusic } 3265362Smckusic if (sblock.fs_ncyl < 1) { 3275362Smckusic printf("file systems must have at least one cylinder\n"); 3285336Smckusic exit(1); 3295336Smckusic } 3305336Smckusic /* 3315362Smckusic * determine feasability/values of rotational layout tables 3325362Smckusic */ 3335362Smckusic if (sblock.fs_ntrak == 1) { 3345362Smckusic sblock.fs_cpc = 0; 3355362Smckusic goto next; 3365362Smckusic } 3375362Smckusic if (sblock.fs_spc * sblock.fs_cpc > MAXBPC * NSPB(&sblock) || 3385362Smckusic sblock.fs_nsect > (1 << NBBY) * NSPB(&sblock)) { 3395362Smckusic printf("%s %s %d %s %d.%s", 3405362Smckusic "Warning: insufficient space in super block for\n", 3415362Smckusic "rotational layout tables with nsect", sblock.fs_nsect, 3425362Smckusic "and ntrak", sblock.fs_ntrak, 34318552Sbloom "\nFile system performance may be impaired.\n"); 3445362Smckusic sblock.fs_cpc = 0; 3455362Smckusic goto next; 3465362Smckusic } 3475362Smckusic /* 3485362Smckusic * calculate the available blocks for each rotational position 3495362Smckusic */ 3505362Smckusic for (cylno = 0; cylno < MAXCPG; cylno++) 3515362Smckusic for (rpos = 0; rpos < NRPOS; rpos++) 3525362Smckusic sblock.fs_postbl[cylno][rpos] = -1; 3535362Smckusic blk = sblock.fs_spc * sblock.fs_cpc / NSPF(&sblock); 3545362Smckusic for (i = 0; i < blk; i += sblock.fs_frag) 3555362Smckusic /* void */; 3565362Smckusic for (i -= sblock.fs_frag; i >= 0; i -= sblock.fs_frag) { 3575362Smckusic cylno = cbtocylno(&sblock, i); 3585362Smckusic rpos = cbtorpos(&sblock, i); 3595362Smckusic blk = i / sblock.fs_frag; 3605362Smckusic if (sblock.fs_postbl[cylno][rpos] == -1) 3615362Smckusic sblock.fs_rotbl[blk] = 0; 3625362Smckusic else 3635362Smckusic sblock.fs_rotbl[blk] = 3645362Smckusic sblock.fs_postbl[cylno][rpos] - blk; 3655362Smckusic sblock.fs_postbl[cylno][rpos] = blk; 3665362Smckusic } 3675362Smckusic next: 3685362Smckusic /* 3695336Smckusic * Validate specified/determined cpg. 3705336Smckusic */ 3715336Smckusic if (sblock.fs_spc > MAXBPG(&sblock) * NSPB(&sblock)) { 3725336Smckusic printf("too many sectors per cylinder (%d sectors)\n", 3735336Smckusic sblock.fs_spc); 3745336Smckusic while(sblock.fs_spc > MAXBPG(&sblock) * NSPB(&sblock)) { 3755336Smckusic sblock.fs_bsize <<= 1; 3765336Smckusic if (sblock.fs_frag < MAXFRAG) 3775336Smckusic sblock.fs_frag <<= 1; 3785336Smckusic else 3795336Smckusic sblock.fs_fsize <<= 1; 3805336Smckusic } 3815336Smckusic printf("nsect %d, and ntrak %d, requires block size of %d,\n", 3825336Smckusic sblock.fs_nsect, sblock.fs_ntrak, sblock.fs_bsize); 3835336Smckusic printf("\tand fragment size of %d\n", sblock.fs_fsize); 3845336Smckusic exit(1); 3855336Smckusic } 3865336Smckusic if (sblock.fs_fpg > MAXBPG(&sblock) * sblock.fs_frag) { 3875336Smckusic printf("cylinder group too large (%d cylinders); ", 3885336Smckusic sblock.fs_cpg); 3895362Smckusic printf("max: %d cylinders per group\n", 3905336Smckusic MAXBPG(&sblock) * sblock.fs_frag / 3915336Smckusic (sblock.fs_fpg / sblock.fs_cpg)); 3925336Smckusic exit(1); 3935336Smckusic } 3945955Smckusic sblock.fs_cgsize = fragroundup(&sblock, 3955955Smckusic sizeof(struct cg) + howmany(sblock.fs_fpg, NBBY)); 3965336Smckusic /* 3974234Smckusick * Compute/validate number of cylinder groups. 3984234Smckusick */ 3994234Smckusick sblock.fs_ncg = sblock.fs_ncyl / sblock.fs_cpg; 4004234Smckusick if (sblock.fs_ncyl % sblock.fs_cpg) 4014234Smckusick sblock.fs_ncg++; 4025336Smckusic if ((sblock.fs_spc * sblock.fs_cpg) % NSPF(&sblock)) { 4034234Smckusick printf("mkfs: nsect %d, ntrak %d, cpg %d is not tolerable\n", 4044234Smckusick sblock.fs_nsect, sblock.fs_ntrak, sblock.fs_cpg); 4054234Smckusick printf("as this would would have cyl groups whose size\n"); 4065324Smckusic printf("is not a multiple of %d; choke!\n", sblock.fs_fsize); 4074234Smckusick exit(1); 4084234Smckusick } 4094234Smckusick /* 4104234Smckusick * Compute number of inode blocks per cylinder group. 4114234Smckusick * Start with one inode per NBPI bytes; adjust as necessary. 4124234Smckusick */ 41312437Smckusick inos = MAX(NBPI, sblock.fs_fsize); 41412437Smckusick if (argc > 9) { 41512437Smckusick i = atoi(argv[9]); 41612437Smckusick if (i <= 0) 41712437Smckusick printf("%s: bogus nbpi reset to %d\n", argv[9], inos); 41812437Smckusick else 41912437Smckusick inos = i; 42012437Smckusick } 4215362Smckusic i = sblock.fs_iblkno + MAXIPG / INOPF(&sblock); 42212437Smckusick inos = (fssize - sblock.fs_ncg * i) * sblock.fs_fsize / inos / 42312437Smckusick INOPB(&sblock); 4245336Smckusic if (inos <= 0) 4255336Smckusic inos = 1; 4265336Smckusic sblock.fs_ipg = ((inos / sblock.fs_ncg) + 1) * INOPB(&sblock); 4274234Smckusick if (sblock.fs_ipg > MAXIPG) 4284234Smckusick sblock.fs_ipg = MAXIPG; 4295362Smckusic sblock.fs_dblkno = sblock.fs_iblkno + sblock.fs_ipg / INOPF(&sblock); 4306532Smckusick i = MIN(~sblock.fs_cgmask, sblock.fs_ncg - 1); 4316532Smckusick if (cgdmin(&sblock, i) - cgbase(&sblock, i) >= sblock.fs_fpg) { 4324234Smckusick printf("inode blocks/cyl group (%d) >= data blocks (%d)\n", 4336532Smckusick cgdmin(&sblock, i) - cgbase(&sblock, i) / sblock.fs_frag, 4345324Smckusic sblock.fs_fpg / sblock.fs_frag); 4356532Smckusick printf("number of cylinders per cylinder group must be increased\n"); 4365324Smckusic exit(1); 4375324Smckusic } 4386532Smckusick j = sblock.fs_ncg - 1; 4396532Smckusick if ((i = fssize - j * sblock.fs_fpg) < sblock.fs_fpg && 4406532Smckusick cgdmin(&sblock, j) - cgbase(&sblock, j) > i) { 4416532Smckusick printf("Warning: inode blocks/cyl group (%d) >= data blocks (%d) in last\n", 4426532Smckusick (cgdmin(&sblock, j) - cgbase(&sblock, j)) / sblock.fs_frag, 4436532Smckusick i / sblock.fs_frag); 4446532Smckusick printf(" cylinder group. This implies %d sector(s) cannot be allocated.\n", 4456532Smckusick i * NSPF(&sblock)); 4466532Smckusick sblock.fs_ncg--; 4476532Smckusick sblock.fs_ncyl -= sblock.fs_ncyl % sblock.fs_cpg; 4486532Smckusick sblock.fs_size = fssize = sblock.fs_ncyl * sblock.fs_spc / 4496532Smckusick NSPF(&sblock); 4506532Smckusick warn = 0; 4516532Smckusick } 4526532Smckusick if (warn) { 4536532Smckusick printf("Warning: %d sector(s) in last cylinder unallocated\n", 4546532Smckusick sblock.fs_spc - 4556532Smckusick (fssize * NSPF(&sblock) - (sblock.fs_ncyl - 1) 4566532Smckusick * sblock.fs_spc)); 4576532Smckusick } 4585336Smckusic /* 4595336Smckusic * fill in remaining fields of the super block 4605336Smckusic */ 4615383Smckusic sblock.fs_csaddr = cgdmin(&sblock, 0); 4626532Smckusick sblock.fs_cssize = 4636532Smckusick fragroundup(&sblock, sblock.fs_ncg * sizeof(struct csum)); 46410076Smckusick i = sblock.fs_bsize / sizeof(struct csum); 46510076Smckusick sblock.fs_csmask = ~(i - 1); 46610076Smckusick for (sblock.fs_csshift = 0; i > 1; i >>= 1) 46710076Smckusick sblock.fs_csshift++; 46810076Smckusick i = sizeof(struct fs) + 46910076Smckusick howmany(sblock.fs_spc * sblock.fs_cpc, NSPB(&sblock)); 47010076Smckusick sblock.fs_sbsize = fragroundup(&sblock, i); 4716532Smckusick fscs = (struct csum *)calloc(1, sblock.fs_cssize); 4725362Smckusic sblock.fs_magic = FS_MAGIC; 4735336Smckusic sblock.fs_rotdelay = ROTDELAY; 47411068Ssam if (argc > 7) { 47511068Ssam sblock.fs_minfree = atoi(argv[7]); 47611068Ssam if (sblock.fs_minfree < 0 || sblock.fs_minfree > 99) { 47711068Ssam printf("%s: bogus minfree reset to %d%%\n", argv[7], 47811068Ssam MINFREE); 47911068Ssam sblock.fs_minfree = MINFREE; 48011068Ssam } 48111068Ssam } else 48211068Ssam sblock.fs_minfree = MINFREE; 4838259Smckusick sblock.fs_maxcontig = MAXCONTIG; 4848259Smckusick sblock.fs_maxbpg = MAXBLKPG(&sblock); 48511068Ssam if (argc > 8) 48611068Ssam sblock.fs_rps = atoi(argv[8]); 48711068Ssam else 48811068Ssam sblock.fs_rps = DEFHZ; 4895336Smckusic sblock.fs_cgrotor = 0; 4905336Smckusic sblock.fs_cstotal.cs_ndir = 0; 4915336Smckusic sblock.fs_cstotal.cs_nbfree = 0; 4925336Smckusic sblock.fs_cstotal.cs_nifree = 0; 4935336Smckusic sblock.fs_cstotal.cs_nffree = 0; 4944234Smckusick sblock.fs_fmod = 0; 4954234Smckusick sblock.fs_ronly = 0; 4964234Smckusick /* 4975336Smckusic * Dump out summary information about file system. 4984234Smckusick */ 4994234Smckusick printf("%s:\t%d sectors in %d cylinders of %d tracks, %d sectors\n", 5005336Smckusic fsys, sblock.fs_size * NSPF(&sblock), sblock.fs_ncyl, 5015324Smckusic sblock.fs_ntrak, sblock.fs_nsect); 5024234Smckusick printf("\t%.1fMb in %d cyl groups (%d c/g, %.2fMb/g, %d i/g)\n", 5035324Smckusic (float)sblock.fs_size * sblock.fs_fsize * 1e-6, sblock.fs_ncg, 5045324Smckusic sblock.fs_cpg, (float)sblock.fs_fpg * sblock.fs_fsize * 1e-6, 5055324Smckusic sblock.fs_ipg); 5064234Smckusick /* 5074234Smckusick * Now build the cylinders group blocks and 5085336Smckusic * then print out indices of cylinder groups. 5094234Smckusick */ 5106532Smckusick printf("super-block backups (for fsck -b#) at:"); 5116532Smckusick for (cylno = 0; cylno < sblock.fs_ncg; cylno++) { 5125362Smckusic initcg(cylno); 5136532Smckusick if (cylno % 10 == 0) 5146532Smckusick printf("\n"); 5156532Smckusick printf(" %d,", fsbtodb(&sblock, cgsblock(&sblock, cylno))); 5166532Smckusick } 51711525Ssam printf("\n"); 51816944Smckusick if (Nflag) 51916944Smckusick exit(0); 5204234Smckusick /* 5215336Smckusic * Now construct the initial file system, 5224234Smckusick * then write out the super-block. 5234234Smckusick */ 5245336Smckusic fsinit(); 5254234Smckusick sblock.fs_time = utime; 5265336Smckusic wtfs(SBLOCK, SBSIZE, (char *)&sblock); 5275324Smckusic for (i = 0; i < sblock.fs_cssize; i += sblock.fs_bsize) 5285955Smckusic wtfs(fsbtodb(&sblock, sblock.fs_csaddr + numfrags(&sblock, i)), 5296532Smckusick sblock.fs_cssize - i < sblock.fs_bsize ? 5306532Smckusick sblock.fs_cssize - i : sblock.fs_bsize, 5316532Smckusick ((char *)fscs) + i); 5325336Smckusic /* 5335336Smckusic * Write out the duplicate super blocks 5345336Smckusic */ 5358295Smckusick for (cylno = 0; cylno < sblock.fs_ncg; cylno++) 5366532Smckusick wtfs(fsbtodb(&sblock, cgsblock(&sblock, cylno)), 5376532Smckusick SBSIZE, (char *)&sblock); 5384234Smckusick #ifndef STANDALONE 5395336Smckusic exit(0); 5404234Smckusick #endif 5414234Smckusick } 5424234Smckusick 5434234Smckusick /* 5444234Smckusick * Initialize a cylinder group. 5454234Smckusick */ 5465362Smckusic initcg(cylno) 5475362Smckusic int cylno; 5484234Smckusick { 5496532Smckusick daddr_t cbase, d, dlower, dupper, dmax; 5504234Smckusick long i, j, s; 5514234Smckusick register struct csum *cs; 5524234Smckusick 5534234Smckusick /* 5544234Smckusick * Determine block bounds for cylinder group. 5554234Smckusick * Allow space for super block summary information in first 5564234Smckusick * cylinder group. 5574234Smckusick */ 5585383Smckusic cbase = cgbase(&sblock, cylno); 5594234Smckusick dmax = cbase + sblock.fs_fpg; 5604234Smckusick if (dmax > sblock.fs_size) 5614234Smckusick dmax = sblock.fs_size; 5626532Smckusick dlower = cgsblock(&sblock, cylno) - cbase; 5636532Smckusick dupper = cgdmin(&sblock, cylno) - cbase; 5645362Smckusic cs = fscs + cylno; 5654234Smckusick acg.cg_time = utime; 5664234Smckusick acg.cg_magic = CG_MAGIC; 5675362Smckusic acg.cg_cgx = cylno; 5688139Smckusick if (cylno == sblock.fs_ncg - 1) 5698139Smckusick acg.cg_ncyl = sblock.fs_ncyl % sblock.fs_cpg; 5708139Smckusick else 5718139Smckusick acg.cg_ncyl = sblock.fs_cpg; 5724234Smckusick acg.cg_niblk = sblock.fs_ipg; 5734234Smckusick acg.cg_ndblk = dmax - cbase; 5744788Smckusic acg.cg_cs.cs_ndir = 0; 5754788Smckusic acg.cg_cs.cs_nffree = 0; 5764788Smckusic acg.cg_cs.cs_nbfree = 0; 5774788Smckusic acg.cg_cs.cs_nifree = 0; 5786532Smckusick acg.cg_rotor = 0; 5796532Smckusick acg.cg_frotor = 0; 5804257Smckusic acg.cg_irotor = 0; 5815324Smckusic for (i = 0; i < sblock.fs_frag; i++) { 5824465Smckusic acg.cg_frsum[i] = 0; 5834465Smckusic } 5844465Smckusic for (i = 0; i < sblock.fs_ipg; ) { 5855324Smckusic for (j = INOPB(&sblock); j > 0; j--) { 5864234Smckusick clrbit(acg.cg_iused, i); 5874234Smckusick i++; 5884234Smckusick } 5895324Smckusic acg.cg_cs.cs_nifree += INOPB(&sblock); 5904234Smckusick } 5915362Smckusic if (cylno == 0) 5925336Smckusic for (i = 0; i < ROOTINO; i++) { 5935336Smckusic setbit(acg.cg_iused, i); 5945336Smckusic acg.cg_cs.cs_nifree--; 5955336Smckusic } 5964234Smckusick while (i < MAXIPG) { 5974234Smckusick clrbit(acg.cg_iused, i); 5984234Smckusick i++; 5994234Smckusick } 60016944Smckusick wtfs(fsbtodb(&sblock, cgimin(&sblock, cylno)), 60116944Smckusick sblock.fs_ipg * sizeof (struct dinode), (char *)zino); 6025370Smckusic for (i = 0; i < MAXCPG; i++) { 6035370Smckusic acg.cg_btot[i] = 0; 6044234Smckusick for (j = 0; j < NRPOS; j++) 6054234Smckusick acg.cg_b[i][j] = 0; 6065370Smckusic } 6075362Smckusic if (cylno == 0) { 6086532Smckusick /* 6096532Smckusick * reserve space for summary info and Boot block 6106532Smckusick */ 6116532Smckusick dupper += howmany(sblock.fs_cssize, sblock.fs_fsize); 6126532Smckusick for (d = 0; d < dlower; d += sblock.fs_frag) 6136532Smckusick clrblock(&sblock, acg.cg_free, d/sblock.fs_frag); 6146532Smckusick } else { 6156532Smckusick for (d = 0; d < dlower; d += sblock.fs_frag) { 6166532Smckusick setblock(&sblock, acg.cg_free, d/sblock.fs_frag); 6176532Smckusick acg.cg_cs.cs_nbfree++; 6186532Smckusick acg.cg_btot[cbtocylno(&sblock, d)]++; 6196532Smckusick acg.cg_b[cbtocylno(&sblock, d)][cbtorpos(&sblock, d)]++; 6206532Smckusick } 6216532Smckusick sblock.fs_dsize += dlower; 6224234Smckusick } 6236532Smckusick sblock.fs_dsize += acg.cg_ndblk - dupper; 6246532Smckusick for (; d < dupper; d += sblock.fs_frag) 6255324Smckusic clrblock(&sblock, acg.cg_free, d/sblock.fs_frag); 6266532Smckusick if (d > dupper) { 6276532Smckusick acg.cg_frsum[d - dupper]++; 6286532Smckusick for (i = d - 1; i >= dupper; i--) { 6296532Smckusick setbit(acg.cg_free, i); 6306532Smckusick acg.cg_cs.cs_nffree++; 6316532Smckusick } 6326532Smckusick } 6336532Smckusick while ((d + sblock.fs_frag) <= dmax - cbase) { 6345324Smckusic setblock(&sblock, acg.cg_free, d/sblock.fs_frag); 6354788Smckusic acg.cg_cs.cs_nbfree++; 6365370Smckusic acg.cg_btot[cbtocylno(&sblock, d)]++; 6375362Smckusic acg.cg_b[cbtocylno(&sblock, d)][cbtorpos(&sblock, d)]++; 6385324Smckusic d += sblock.fs_frag; 6394234Smckusick } 6406532Smckusick if (d < dmax - cbase) { 6415362Smckusic acg.cg_frsum[dmax - cbase - d]++; 6424251Smckusic for (; d < dmax - cbase; d++) { 6434251Smckusic setbit(acg.cg_free, d); 6444788Smckusic acg.cg_cs.cs_nffree++; 6454251Smckusic } 6468139Smckusick for (; d % sblock.fs_frag != 0; d++) 6478139Smckusick clrbit(acg.cg_free, d); 6486532Smckusick } 6498139Smckusick for (d /= sblock.fs_frag; d < MAXBPG(&sblock); d ++) 6508139Smckusick clrblock(&sblock, acg.cg_free, d); 6514788Smckusic sblock.fs_cstotal.cs_ndir += acg.cg_cs.cs_ndir; 6524788Smckusic sblock.fs_cstotal.cs_nffree += acg.cg_cs.cs_nffree; 6534788Smckusic sblock.fs_cstotal.cs_nbfree += acg.cg_cs.cs_nbfree; 6544788Smckusic sblock.fs_cstotal.cs_nifree += acg.cg_cs.cs_nifree; 6554788Smckusic *cs = acg.cg_cs; 6565383Smckusic wtfs(fsbtodb(&sblock, cgtod(&sblock, cylno)), 6575324Smckusic sblock.fs_bsize, (char *)&acg); 6584234Smckusick } 6594234Smckusick 6605336Smckusic /* 6615336Smckusic * initialize the file system 6625336Smckusic */ 6635336Smckusic struct inode node; 6645336Smckusic #define PREDEFDIR 3 6655934Smckusic struct direct root_dir[] = { 6665934Smckusic { ROOTINO, sizeof(struct direct), 1, "." }, 6675934Smckusic { ROOTINO, sizeof(struct direct), 2, ".." }, 6685934Smckusic { LOSTFOUNDINO, sizeof(struct direct), 10, "lost+found" }, 6695336Smckusic }; 6705934Smckusic struct direct lost_found_dir[] = { 6715934Smckusic { LOSTFOUNDINO, sizeof(struct direct), 1, "." }, 6725934Smckusic { ROOTINO, sizeof(struct direct), 2, ".." }, 6735934Smckusic { 0, DIRBLKSIZ, 0, 0 }, 6745336Smckusic }; 6755934Smckusic char buf[MAXBSIZE]; 6765336Smckusic 6775336Smckusic fsinit() 6784234Smckusick { 6795934Smckusic int i; 6805934Smckusic 6814234Smckusick /* 6825336Smckusic * initialize the node 6834234Smckusick */ 6845336Smckusic node.i_atime = utime; 6855336Smckusic node.i_mtime = utime; 6865336Smckusic node.i_ctime = utime; 6874234Smckusick /* 6885336Smckusic * create the lost+found directory 6894234Smckusick */ 6905934Smckusic (void)makedir(lost_found_dir, 2); 6915934Smckusic for (i = DIRBLKSIZ; i < sblock.fs_bsize; i += DIRBLKSIZ) 6925934Smckusic bcopy(&lost_found_dir[2], &buf[i], DIRSIZ(&lost_found_dir[2])); 6935336Smckusic node.i_number = LOSTFOUNDINO; 6945336Smckusic node.i_mode = IFDIR | UMASK; 6955336Smckusic node.i_nlink = 2; 6965336Smckusic node.i_size = sblock.fs_bsize; 6975336Smckusic node.i_db[0] = alloc(node.i_size, node.i_mode); 69814323Smckusick node.i_blocks = btodb(fragroundup(&sblock, node.i_size)); 6995934Smckusic wtfs(fsbtodb(&sblock, node.i_db[0]), node.i_size, buf); 7005336Smckusic iput(&node); 7015336Smckusic /* 7025336Smckusic * create the root directory 7035336Smckusic */ 7045336Smckusic node.i_number = ROOTINO; 7055336Smckusic node.i_mode = IFDIR | UMASK; 7065336Smckusic node.i_nlink = PREDEFDIR; 7075934Smckusic node.i_size = makedir(root_dir, PREDEFDIR); 7085336Smckusic node.i_db[0] = alloc(sblock.fs_fsize, node.i_mode); 70914323Smckusick node.i_blocks = btodb(fragroundup(&sblock, node.i_size)); 7105934Smckusic wtfs(fsbtodb(&sblock, node.i_db[0]), sblock.fs_fsize, buf); 7115336Smckusic iput(&node); 7124234Smckusick } 7134234Smckusick 7145336Smckusic /* 7155934Smckusic * construct a set of directory entries in "buf". 7165934Smckusic * return size of directory. 7175934Smckusic */ 7185934Smckusic makedir(protodir, entries) 7195934Smckusic register struct direct *protodir; 7205934Smckusic int entries; 7215934Smckusic { 7225934Smckusic char *cp; 7235934Smckusic int i, spcleft; 7245934Smckusic 7255934Smckusic spcleft = DIRBLKSIZ; 7265934Smckusic for (cp = buf, i = 0; i < entries - 1; i++) { 7275934Smckusic protodir[i].d_reclen = DIRSIZ(&protodir[i]); 7285934Smckusic bcopy(&protodir[i], cp, protodir[i].d_reclen); 7295934Smckusic cp += protodir[i].d_reclen; 7305934Smckusic spcleft -= protodir[i].d_reclen; 7315934Smckusic } 7325934Smckusic protodir[i].d_reclen = spcleft; 7335934Smckusic bcopy(&protodir[i], cp, DIRSIZ(&protodir[i])); 7345934Smckusic cp += DIRSIZ(&protodir[i]); 7355934Smckusic return (cp - buf); 7365934Smckusic } 7375934Smckusic 7385934Smckusic /* 7395336Smckusic * allocate a block or frag 7405336Smckusic */ 7414234Smckusick daddr_t 7424427Smckusic alloc(size, mode) 7434427Smckusic int size; 7444427Smckusic int mode; 7454234Smckusick { 7465362Smckusic int i, frag; 7474234Smckusick daddr_t d; 7484234Smckusick 7495955Smckusic rdfs(fsbtodb(&sblock, cgtod(&sblock, 0)), sblock.fs_cgsize, 7505955Smckusic (char *)&acg); 7516532Smckusick if (acg.cg_magic != CG_MAGIC) { 7526532Smckusick printf("cg 0: bad magic number\n"); 7536532Smckusick return (0); 7546532Smckusick } 7554788Smckusic if (acg.cg_cs.cs_nbfree == 0) { 7564234Smckusick printf("first cylinder group ran out of space\n"); 7574234Smckusick return (0); 7584234Smckusick } 7595324Smckusic for (d = 0; d < acg.cg_ndblk; d += sblock.fs_frag) 7605324Smckusic if (isblock(&sblock, acg.cg_free, d / sblock.fs_frag)) 7614234Smckusick goto goth; 7624234Smckusick printf("internal error: can't find block in cyl 0\n"); 7634234Smckusick return (0); 7644234Smckusick goth: 7655324Smckusic clrblock(&sblock, acg.cg_free, d / sblock.fs_frag); 7664788Smckusic acg.cg_cs.cs_nbfree--; 7674788Smckusic sblock.fs_cstotal.cs_nbfree--; 7684234Smckusick fscs[0].cs_nbfree--; 7694427Smckusic if (mode & IFDIR) { 7704788Smckusic acg.cg_cs.cs_ndir++; 7714788Smckusic sblock.fs_cstotal.cs_ndir++; 7724427Smckusic fscs[0].cs_ndir++; 7734427Smckusic } 7745370Smckusic acg.cg_btot[cbtocylno(&sblock, d)]--; 7755362Smckusic acg.cg_b[cbtocylno(&sblock, d)][cbtorpos(&sblock, d)]--; 7765324Smckusic if (size != sblock.fs_bsize) { 7775324Smckusic frag = howmany(size, sblock.fs_fsize); 7785324Smckusic fscs[0].cs_nffree += sblock.fs_frag - frag; 7795324Smckusic sblock.fs_cstotal.cs_nffree += sblock.fs_frag - frag; 7805324Smckusic acg.cg_cs.cs_nffree += sblock.fs_frag - frag; 7815324Smckusic acg.cg_frsum[sblock.fs_frag - frag]++; 7825324Smckusic for (i = frag; i < sblock.fs_frag; i++) 7836532Smckusick setbit(acg.cg_free, d + i); 7844234Smckusick } 7855955Smckusic wtfs(fsbtodb(&sblock, cgtod(&sblock, 0)), sblock.fs_cgsize, 7865955Smckusic (char *)&acg); 7874234Smckusick return (d); 7884234Smckusick } 7894234Smckusick 7905336Smckusic /* 7915336Smckusic * Allocate an inode on the disk 7925336Smckusic */ 7935336Smckusic iput(ip) 7945336Smckusic register struct inode *ip; 7954234Smckusick { 7965336Smckusic struct dinode buf[MAXINOPB]; 7975336Smckusic daddr_t d; 7985336Smckusic int c; 7994234Smckusick 8005383Smckusic c = itog(&sblock, ip->i_number); 8015955Smckusic rdfs(fsbtodb(&sblock, cgtod(&sblock, 0)), sblock.fs_cgsize, 8025955Smckusic (char *)&acg); 8036532Smckusick if (acg.cg_magic != CG_MAGIC) { 8046532Smckusick printf("cg 0: bad magic number\n"); 8056532Smckusick exit(1); 8066532Smckusick } 8075336Smckusic acg.cg_cs.cs_nifree--; 8085336Smckusic setbit(acg.cg_iused, ip->i_number); 8095955Smckusic wtfs(fsbtodb(&sblock, cgtod(&sblock, 0)), sblock.fs_cgsize, 8105955Smckusic (char *)&acg); 8115336Smckusic sblock.fs_cstotal.cs_nifree--; 8125336Smckusic fscs[0].cs_nifree--; 8135336Smckusic if(ip->i_number >= sblock.fs_ipg * sblock.fs_ncg) { 8145336Smckusic printf("fsinit: inode value out of range (%d).\n", 8155336Smckusic ip->i_number); 8165336Smckusic exit(1); 8175336Smckusic } 8185383Smckusic d = fsbtodb(&sblock, itod(&sblock, ip->i_number)); 8195336Smckusic rdfs(d, sblock.fs_bsize, buf); 8205383Smckusic buf[itoo(&sblock, ip->i_number)].di_ic = ip->i_ic; 8215336Smckusic wtfs(d, sblock.fs_bsize, buf); 8224234Smckusick } 8234234Smckusick 8245336Smckusic /* 8255336Smckusic * read a block from the file system 8265336Smckusic */ 8275336Smckusic rdfs(bno, size, bf) 8285336Smckusic daddr_t bno; 8294427Smckusic int size; 8305336Smckusic char *bf; 8314234Smckusick { 8325336Smckusic int n; 8334234Smckusick 8345346Smckusic if (lseek(fsi, bno * DEV_BSIZE, 0) < 0) { 8355346Smckusic printf("seek error: %ld\n", bno); 8365346Smckusic perror("rdfs"); 8375346Smckusic exit(1); 8385346Smckusic } 8395336Smckusic n = read(fsi, bf, size); 8405336Smckusic if(n != size) { 8415336Smckusic printf("read error: %ld\n", bno); 8425346Smckusic perror("rdfs"); 8435336Smckusic exit(1); 8444234Smckusick } 8454234Smckusick } 8464234Smckusick 8475336Smckusic /* 8485336Smckusic * write a block to the file system 8495336Smckusic */ 8505336Smckusic wtfs(bno, size, bf) 8515336Smckusic daddr_t bno; 8525336Smckusic int size; 8535336Smckusic char *bf; 8544234Smckusick { 8555336Smckusic int n; 8564234Smckusick 85716944Smckusick if (Nflag) 85816944Smckusick return; 8595346Smckusic if (lseek(fso, bno * DEV_BSIZE, 0) < 0) { 8605346Smckusic printf("seek error: %ld\n", bno); 8615346Smckusic perror("wtfs"); 8625346Smckusic exit(1); 8635346Smckusic } 8645336Smckusic n = write(fso, bf, size); 8655336Smckusic if(n != size) { 8665336Smckusic printf("write error: %D\n", bno); 8675346Smckusic perror("wtfs"); 8684234Smckusick exit(1); 8694234Smckusick } 8704234Smckusick } 8715324Smckusic 8725324Smckusic /* 8735336Smckusic * check if a block is available 8745324Smckusic */ 8755324Smckusic isblock(fs, cp, h) 8765324Smckusic struct fs *fs; 8775324Smckusic unsigned char *cp; 8785324Smckusic int h; 8795324Smckusic { 8805324Smckusic unsigned char mask; 8815324Smckusic 8825324Smckusic switch (fs->fs_frag) { 8835324Smckusic case 8: 8845324Smckusic return (cp[h] == 0xff); 8855324Smckusic case 4: 8865324Smckusic mask = 0x0f << ((h & 0x1) << 2); 8875324Smckusic return ((cp[h >> 1] & mask) == mask); 8885324Smckusic case 2: 8895324Smckusic mask = 0x03 << ((h & 0x3) << 1); 8905324Smckusic return ((cp[h >> 2] & mask) == mask); 8915324Smckusic case 1: 8925324Smckusic mask = 0x01 << (h & 0x7); 8935324Smckusic return ((cp[h >> 3] & mask) == mask); 8945324Smckusic default: 8958140Smckusick #ifdef STANDALONE 8968140Smckusick printf("isblock bad fs_frag %d\n", fs->fs_frag); 8978140Smckusick #else 8985324Smckusic fprintf(stderr, "isblock bad fs_frag %d\n", fs->fs_frag); 8998140Smckusick #endif 9005324Smckusic return; 9015324Smckusic } 9025324Smckusic } 9035324Smckusic 9045336Smckusic /* 9055336Smckusic * take a block out of the map 9065336Smckusic */ 9075324Smckusic clrblock(fs, cp, h) 9085324Smckusic struct fs *fs; 9095324Smckusic unsigned char *cp; 9105324Smckusic int h; 9115324Smckusic { 9125324Smckusic switch ((fs)->fs_frag) { 9135324Smckusic case 8: 9145324Smckusic cp[h] = 0; 9155324Smckusic return; 9165324Smckusic case 4: 9175324Smckusic cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2)); 9185324Smckusic return; 9195324Smckusic case 2: 9205324Smckusic cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1)); 9215324Smckusic return; 9225324Smckusic case 1: 9235324Smckusic cp[h >> 3] &= ~(0x01 << (h & 0x7)); 9245324Smckusic return; 9255324Smckusic default: 9268140Smckusick #ifdef STANDALONE 9278140Smckusick printf("clrblock bad fs_frag %d\n", fs->fs_frag); 9288140Smckusick #else 9295324Smckusic fprintf(stderr, "clrblock bad fs_frag %d\n", fs->fs_frag); 9308140Smckusick #endif 9315324Smckusic return; 9325324Smckusic } 9335324Smckusic } 9345324Smckusic 9355336Smckusic /* 9365336Smckusic * put a block into the map 9375336Smckusic */ 9385324Smckusic setblock(fs, cp, h) 9395324Smckusic struct fs *fs; 9405324Smckusic unsigned char *cp; 9415324Smckusic int h; 9425324Smckusic { 9435324Smckusic switch (fs->fs_frag) { 9445324Smckusic case 8: 9455324Smckusic cp[h] = 0xff; 9465324Smckusic return; 9475324Smckusic case 4: 9485324Smckusic cp[h >> 1] |= (0x0f << ((h & 0x1) << 2)); 9495324Smckusic return; 9505324Smckusic case 2: 9515324Smckusic cp[h >> 2] |= (0x03 << ((h & 0x3) << 1)); 9525324Smckusic return; 9535324Smckusic case 1: 9545324Smckusic cp[h >> 3] |= (0x01 << (h & 0x7)); 9555324Smckusic return; 9565324Smckusic default: 9578140Smckusick #ifdef STANDALONE 9588140Smckusick printf("setblock bad fs_frag %d\n", fs->fs_frag); 9598140Smckusick #else 9605324Smckusic fprintf(stderr, "setblock bad fs_frag %d\n", fs->fs_frag); 9618140Smckusick #endif 9625324Smckusic return; 9635324Smckusic } 9645324Smckusic } 965