1*6491Smckusick static char *sccsid = "@(#)main.c 2.2 (Berkeley) 04/08/82"; 24428Smckusic 34236Smckusick #include <stdio.h> 44236Smckusick #include <ctype.h> 56489Smckusick #ifndef SIMFS 66489Smckusick #include <sys/param.h> 76489Smckusick #include <sys/fs.h> 86489Smckusick #include <sys/inode.h> 96489Smckusick #include <ndir.h> 106489Smckusick #else 114236Smckusick #include "../h/param.h" 124236Smckusick #include "../h/fs.h" 134236Smckusick #include "../h/inode.h" 146489Smckusick #include "../h/ndir.h" 156489Smckusick #endif 166489Smckusick #include <sys/stat.h> 174236Smckusick #include <fstab.h> 184236Smckusick 194236Smckusick typedef int (*SIG_TYP)(); 204236Smckusick 215347Smckusic #define MAXNINDIR (MAXBSIZE / sizeof (daddr_t)) 225347Smckusic #define MAXINOPB (MAXBSIZE / sizeof (struct dinode)) 235325Smckusic #define SPERB (MAXBSIZE / sizeof(short)) 244236Smckusick 254236Smckusick #define MAXDUP 10 /* limit on dup blks (per inode) */ 264236Smckusick #define MAXBAD 10 /* limit on bad blks (per inode) */ 274236Smckusick 284236Smckusick #define USTATE 0 /* inode not allocated */ 294236Smckusick #define FSTATE 01 /* inode is file */ 304236Smckusick #define DSTATE 02 /* inode is directory */ 314236Smckusick #define CLEAR 03 /* inode is to be cleared */ 324236Smckusick 334236Smckusick typedef struct dinode DINODE; 344236Smckusick typedef struct direct DIRECT; 354236Smckusick 364236Smckusick #define ALLOC ((dp->di_mode & IFMT) != 0) 375877Smckusic #define DIRCT ((dp->di_mode & IFMT) == IFDIR) 384236Smckusick #define REG ((dp->di_mode & IFMT) == IFREG) 394236Smckusick #define BLK ((dp->di_mode & IFMT) == IFBLK) 404236Smckusick #define CHR ((dp->di_mode & IFMT) == IFCHR) 416285Smckusick #define SPECIAL (BLK || CHR) 424236Smckusick 434465Smckusic ino_t startinum; /* blk num of first in raw area */ 444236Smckusick 454236Smckusick struct bufarea { 464236Smckusick struct bufarea *b_next; /* must be first */ 474236Smckusick daddr_t b_bno; 484236Smckusick int b_size; 494236Smckusick union { 505325Smckusic char b_buf[MAXBSIZE]; /* buffer space */ 514236Smckusick short b_lnks[SPERB]; /* link counts */ 525325Smckusic daddr_t b_indir[MAXNINDIR]; /* indirect block */ 534236Smckusick struct fs b_fs; /* super block */ 544236Smckusick struct cg b_cg; /* cylinder group */ 555325Smckusic struct dinode b_dinode[MAXINOPB]; /* inode block */ 564236Smckusick } b_un; 574236Smckusick char b_dirty; 584236Smckusick }; 594236Smckusick 604236Smckusick typedef struct bufarea BUFAREA; 614236Smckusick 624236Smckusick BUFAREA inoblk; /* inode blocks */ 634236Smckusick BUFAREA fileblk; /* other blks in filesys */ 644236Smckusick BUFAREA sblk; /* file system superblock */ 654236Smckusick BUFAREA cgblk; 664236Smckusick 674236Smckusick #define initbarea(x) (x)->b_dirty = 0;(x)->b_bno = (daddr_t)-1 684236Smckusick #define dirty(x) (x)->b_dirty = 1 694236Smckusick #define inodirty() inoblk.b_dirty = 1 704236Smckusick #define sbdirty() sblk.b_dirty = 1 714236Smckusick #define cgdirty() cgblk.b_dirty = 1 724236Smckusick 734236Smckusick #define dirblk fileblk.b_un 744236Smckusick #define sblock sblk.b_un.b_fs 754236Smckusick #define cgrp cgblk.b_un.b_cg 764236Smckusick 774236Smckusick struct filecntl { 784236Smckusick int rfdes; 794236Smckusick int wfdes; 804236Smckusick int mod; 814236Smckusick } dfile; /* file descriptors for filesys */ 824236Smckusick 834236Smckusick #define DUPTBLSIZE 100 /* num of dup blocks to remember */ 844236Smckusick daddr_t duplist[DUPTBLSIZE]; /* dup block table */ 854236Smckusick daddr_t *enddup; /* next entry in dup table */ 864236Smckusick daddr_t *muldup; /* multiple dups part of table */ 874236Smckusick 884236Smckusick #define MAXLNCNT 20 /* num zero link cnts to remember */ 894236Smckusick ino_t badlncnt[MAXLNCNT]; /* table of inos with zero link cnts */ 904236Smckusick ino_t *badlnp; /* next entry in table */ 914236Smckusick 924236Smckusick char rawflg; 934236Smckusick char nflag; /* assume a no response */ 944236Smckusick char yflag; /* assume a yes response */ 954236Smckusick int bflag; /* location of alternate super block */ 965381Smckusic int debug; /* output debugging info */ 974236Smckusick char preen; /* just fix normal inconsistencies */ 984236Smckusick char rplyflag; /* any questions asked? */ 994236Smckusick char hotroot; /* checking root device */ 1004236Smckusick char fixcg; /* corrupted free list bit maps */ 1014236Smckusick 1026314Smckusick char *blockmap; /* ptr to primary blk allocation map */ 1034236Smckusick char *freemap; /* ptr to secondary blk allocation map */ 1044236Smckusick char *statemap; /* ptr to inode state table */ 1054236Smckusick short *lncntp; /* ptr to link count table */ 1064236Smckusick 1074236Smckusick char *pathp; /* pointer to pathname position */ 1084236Smckusick char *thisname; /* ptr to current pathname component */ 1094236Smckusick char *srchname; /* name being searched for in dir */ 1105877Smckusic char pathname[BUFSIZ]; 1114236Smckusick 1124236Smckusick char *lfname = "lost+found"; 1134236Smckusick 1144236Smckusick ino_t inum; /* inode we are currently working on */ 1154236Smckusick ino_t imax; /* number of inodes */ 1164236Smckusick ino_t parentdir; /* i number of parent directory */ 1174236Smckusick ino_t lastino; /* hiwater mark of inodes */ 1184236Smckusick ino_t lfdir; /* lost & found directory */ 1194236Smckusick ino_t orphan; /* orphaned inode */ 1204236Smckusick 1214236Smckusick off_t filsize; /* num blks seen in file */ 1224236Smckusick off_t maxblk; /* largest logical blk in file */ 1236314Smckusick off_t bmapsz; /* num chars in blockmap */ 1244236Smckusick 1254236Smckusick daddr_t n_ffree; /* number of small free blocks */ 1264236Smckusick daddr_t n_bfree; /* number of large free blocks */ 1274236Smckusick daddr_t n_blks; /* number of blocks used */ 1284236Smckusick daddr_t n_files; /* number of files seen */ 1294236Smckusick daddr_t n_index; 1304236Smckusick daddr_t n_bad; 1314236Smckusick daddr_t fmax; /* number of blocks in the volume */ 1324236Smckusick 1334236Smckusick daddr_t badblk; 1344236Smckusick daddr_t dupblk; 1354236Smckusick 1364236Smckusick int inosumbad; 1374236Smckusick int offsumbad; 1384465Smckusic int frsumbad; 139*6491Smckusick int sbsumbad; 1404236Smckusick 1414236Smckusick #define zapino(x) (*(x) = zino) 1424236Smckusick struct dinode zino; 1434236Smckusick 1444236Smckusick #define setlncnt(x) (lncntp[inum] = x) 1454236Smckusick #define getlncnt() (lncntp[inum]) 1464236Smckusick #define declncnt() (--lncntp[inum]) 1474236Smckusick 1486314Smckusick #define setbmap(x) setbit(blockmap, x) 1496314Smckusick #define getbmap(x) isset(blockmap, x) 1506314Smckusick #define clrbmap(x) clrbit(blockmap, x) 1514236Smckusick 1524236Smckusick #define setfmap(x) setbit(freemap, x) 1534236Smckusick #define getfmap(x) isset(freemap, x) 1544236Smckusick #define clrfmap(x) clrbit(freemap, x) 1554236Smckusick 1564236Smckusick #define setstate(x) (statemap[inum] = x) 1574236Smckusick #define getstate() statemap[inum] 1584236Smckusick 1594236Smckusick #define DATA 1 1604236Smckusick #define ADDR 0 1614236Smckusick 1624236Smckusick #define ALTERD 010 1634236Smckusick #define KEEPON 04 1644236Smckusick #define SKIP 02 1654236Smckusick #define STOP 01 1664236Smckusick 1674236Smckusick int (*signal())(); 1684236Smckusick long lseek(); 1694236Smckusick time_t time(); 1704236Smckusick DINODE *ginode(); 1714236Smckusick BUFAREA *getblk(); 1724236Smckusick int dirscan(); 1734236Smckusick int findino(); 1744236Smckusick int catch(); 1754236Smckusick int mkentry(); 1764236Smckusick int chgdd(); 1774236Smckusick int pass1(), pass1b(), pass2(), pass4(), pass5(); 1784236Smckusick int (*pfunc)(); 1794236Smckusick char *rawname(), *rindex(), *unrawname(); 1804606Smckusic extern int inside[], around[]; 1815325Smckusic extern unsigned char *fragtbl[]; 1824236Smckusick 1834236Smckusick char *devname; 1844236Smckusick 1854236Smckusick main(argc, argv) 1864715Smckusic int argc; 1874715Smckusic char *argv[]; 1884236Smckusick { 1894236Smckusick struct fstab *fsp; 1904236Smckusick int pid, passno, anygtr, sumstatus; 1914236Smckusick 1924236Smckusick sync(); 1934236Smckusick while (--argc > 0 && **++argv == '-') { 1944236Smckusick switch (*++*argv) { 1954236Smckusick 1964236Smckusick case 'p': 1974236Smckusick preen++; 1984236Smckusick break; 1994236Smckusick 2004236Smckusick case 'b': 2014236Smckusick bflag = atoi(argv[0]+1); 2024236Smckusick printf("Alternate super block location: %d\n", bflag); 2034236Smckusick break; 2044236Smckusick 2055381Smckusic case 'd': 2065381Smckusic debug++; 2075381Smckusic break; 2085381Smckusic 2094236Smckusick case 'n': /* default no answer flag */ 2104236Smckusick case 'N': 2114236Smckusick nflag++; 2124236Smckusick yflag = 0; 2134236Smckusick break; 2144236Smckusick 2154236Smckusick case 'y': /* default yes answer flag */ 2164236Smckusick case 'Y': 2174236Smckusick yflag++; 2184236Smckusick nflag = 0; 2194236Smckusick break; 2204236Smckusick 2214236Smckusick default: 2224236Smckusick errexit("%c option?\n", **argv); 2234236Smckusick } 2244236Smckusick } 2254236Smckusick if (signal(SIGINT, SIG_IGN) != SIG_IGN) 2264236Smckusick signal(SIGINT, catch); 2274236Smckusick if (argc) { 2284236Smckusick while (argc-- > 0) { 2294236Smckusick hotroot = 0; 2304236Smckusick check(*argv++); 2314236Smckusick } 2324236Smckusick exit(0); 2334236Smckusick } 2344236Smckusick sumstatus = 0; 2354236Smckusick passno = 1; 2364236Smckusick do { 2374236Smckusick anygtr = 0; 2384236Smckusick if (setfsent() == 0) 2394236Smckusick errexit("Can't open checklist file: %s\n", FSTAB); 2404236Smckusick while ((fsp = getfsent()) != 0) { 2414236Smckusick if (strcmp(fsp->fs_type, FSTAB_RW) && 2424236Smckusick strcmp(fsp->fs_type, FSTAB_RO)) 2434236Smckusick continue; 2444236Smckusick if (preen == 0 || 2454236Smckusick passno == 1 && fsp->fs_passno == passno) { 2464236Smckusick if (blockcheck(fsp->fs_spec) == 0 && preen) 2474236Smckusick exit(8); 2484236Smckusick } else if (fsp->fs_passno > passno) 2494236Smckusick anygtr = 1; 2504236Smckusick else if (fsp->fs_passno == passno) { 2514236Smckusick pid = fork(); 2524236Smckusick if (pid < 0) { 2534236Smckusick perror("fork"); 2544236Smckusick exit(8); 2554236Smckusick } 2564236Smckusick if (pid == 0) 2574236Smckusick if (blockcheck(fsp->fs_spec)==0) 2584236Smckusick exit(8); 2594236Smckusick else 2604236Smckusick exit(0); 2614236Smckusick } 2624236Smckusick } 2634236Smckusick if (preen) { 2644236Smckusick int status; 2654236Smckusick while (wait(&status) != -1) 2664236Smckusick sumstatus |= status; 2674236Smckusick } 2684236Smckusick passno++; 2694236Smckusick } while (anygtr); 2704236Smckusick if (sumstatus) 2714236Smckusick exit(8); 2724236Smckusick endfsent(); 2734236Smckusick exit(0); 2744236Smckusick } 2754236Smckusick 2764236Smckusick blockcheck(name) 2774236Smckusick char *name; 2784236Smckusick { 2796489Smckusick struct stat stslash, stblock, stchar; 2804236Smckusick char *raw; 2814236Smckusick int looped = 0; 2824236Smckusick 2834236Smckusick hotroot = 0; 2844236Smckusick if (stat("/", &stslash) < 0){ 2854236Smckusick error("Can't stat root\n"); 2864236Smckusick return (0); 2874236Smckusick } 2884236Smckusick retry: 2894236Smckusick if (stat(name, &stblock) < 0){ 2904236Smckusick error("Can't stat %s\n", name); 2914236Smckusick return (0); 2924236Smckusick } 2934236Smckusick if (stblock.st_mode & S_IFBLK) { 2944236Smckusick raw = rawname(name); 2954236Smckusick if (stat(raw, &stchar) < 0){ 2964236Smckusick error("Can't stat %s\n", raw); 2974236Smckusick return (0); 2984236Smckusick } 2994236Smckusick if (stchar.st_mode & S_IFCHR) { 3004236Smckusick if (stslash.st_dev == stblock.st_rdev) { 3014236Smckusick hotroot++; 3024236Smckusick raw = unrawname(name); 3034236Smckusick } 3044236Smckusick check(raw); 3054236Smckusick return (1); 3064236Smckusick } else { 3074236Smckusick error("%s is not a character device\n", raw); 3084236Smckusick return (0); 3094236Smckusick } 3104236Smckusick } else if (stblock.st_mode & S_IFCHR) { 3114236Smckusick if (looped) { 3124236Smckusick error("Can't make sense out of name %s\n", name); 3134236Smckusick return (0); 3144236Smckusick } 3154236Smckusick name = unrawname(name); 3164236Smckusick looped++; 3174236Smckusick goto retry; 3184236Smckusick } 3194236Smckusick error("Can't make sense out of name %s\n", name); 3204236Smckusick return (0); 3214236Smckusick } 3224236Smckusick 3234236Smckusick char * 3244236Smckusick unrawname(cp) 3254236Smckusick char *cp; 3264236Smckusick { 3274236Smckusick char *dp = rindex(cp, '/'); 3286489Smckusick struct stat stb; 3294236Smckusick 3304236Smckusick if (dp == 0) 3314236Smckusick return (cp); 3324236Smckusick if (stat(cp, &stb) < 0) 3334236Smckusick return (cp); 3344236Smckusick if ((stb.st_mode&S_IFMT) != S_IFCHR) 3354236Smckusick return (cp); 3364236Smckusick if (*(dp+1) != 'r') 3374236Smckusick return (cp); 3384236Smckusick strcpy(dp+1, dp+2); 3394236Smckusick return (cp); 3404236Smckusick } 3414236Smckusick 3424236Smckusick char * 3434236Smckusick rawname(cp) 3444236Smckusick char *cp; 3454236Smckusick { 3464236Smckusick static char rawbuf[32]; 3474236Smckusick char *dp = rindex(cp, '/'); 3484236Smckusick 3494236Smckusick if (dp == 0) 3504236Smckusick return (0); 3514236Smckusick *dp = 0; 3524236Smckusick strcpy(rawbuf, cp); 3534236Smckusick *dp = '/'; 3544236Smckusick strcat(rawbuf, "/r"); 3554236Smckusick strcat(rawbuf, dp+1); 3564236Smckusick return (rawbuf); 3574236Smckusick } 3584236Smckusick 3594236Smckusick check(dev) 3604236Smckusick char *dev; 3614236Smckusick { 3624236Smckusick register DINODE *dp; 3634236Smckusick register ino_t *blp; 3644236Smckusick register int i, n; 3654236Smckusick ino_t savino; 3664236Smckusick int b, c; 3674236Smckusick daddr_t d, s; 3684236Smckusick 3694236Smckusick devname = dev; 3704236Smckusick if (setup(dev) == 0) { 3714236Smckusick if (preen) 3724236Smckusick pfatal("CAN'T CHECK DEVICE."); 3734236Smckusick return; 3744236Smckusick } 3754236Smckusick /* 1 */ 3764236Smckusick if (preen==0) { 3774236Smckusick if (hotroot) 3784236Smckusick printf("** Root file system\n"); 3794236Smckusick printf("** Phase 1 - Check Blocks and Sizes\n"); 3804236Smckusick } 3814236Smckusick pfunc = pass1; 3824236Smckusick inum = 0; 3835325Smckusic n_blks += howmany(sblock.fs_cssize, sblock.fs_bsize) * sblock.fs_frag; 3844236Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 3855381Smckusic if (getblk(&cgblk, cgtod(&sblock, c), sblock.fs_cgsize) == 0) 3864236Smckusick continue; 3874236Smckusick n = 0; 3884465Smckusic for (i = 0; i < sblock.fs_ipg; i++, inum++) { 3894465Smckusic dp = ginode(); 3904465Smckusic if (dp == NULL) 3914465Smckusic continue; 3925944Smckusic n++; 3934236Smckusick if (ALLOC) { 3944236Smckusick if (!isset(cgrp.cg_iused, i)) { 3955381Smckusic if (debug) 3965381Smckusic printf("%d bad, not used\n", 3975381Smckusic inum); 3984236Smckusick inosumbad++; 3994236Smckusick } 4005944Smckusic n--; 4014236Smckusick lastino = inum; 4024236Smckusick if (ftypeok(dp) == 0) { 4034236Smckusick pfatal("UNKNOWN FILE TYPE I=%u", inum); 4044236Smckusick if (reply("CLEAR") == 1) { 4054236Smckusick zapino(dp); 4064236Smckusick inodirty(); 4074236Smckusick inosumbad++; 4084236Smckusick } 4094236Smckusick continue; 4104236Smckusick } 4114236Smckusick n_files++; 4124236Smckusick if (setlncnt(dp->di_nlink) <= 0) { 4134236Smckusick if (badlnp < &badlncnt[MAXLNCNT]) 4144236Smckusick *badlnp++ = inum; 4154236Smckusick else { 4164236Smckusick pfatal("LINK COUNT TABLE OVERFLOW"); 4174236Smckusick if (reply("CONTINUE") == 0) 4184236Smckusick errexit(""); 4194236Smckusick } 4204236Smckusick } 4215877Smckusic setstate(DIRCT ? DSTATE : FSTATE); 4224236Smckusick badblk = dupblk = 0; filsize = 0; maxblk = 0; 4234236Smckusick ckinode(dp, ADDR); 4244236Smckusick } else { 4254236Smckusick if (isset(cgrp.cg_iused, i)) { 4265381Smckusic if (debug) 4275381Smckusic printf("%d bad, marked used\n", 4285381Smckusic inum); 4294236Smckusick inosumbad++; 4304465Smckusic n--; 4314236Smckusick } 4324236Smckusick if (dp->di_mode != 0) { 4334236Smckusick pfatal("PARTIALLY ALLOCATED INODE I=%u", inum); 4344236Smckusick if (reply("CLEAR") == 1) { 4354236Smckusick zapino(dp); 4364236Smckusick inodirty(); 4374236Smckusick inosumbad++; 4384236Smckusick } 4394236Smckusick } 4404236Smckusick } 4414236Smckusick } 4424789Smckusic if (n != cgrp.cg_cs.cs_nifree) { 4435381Smckusic if (debug) 4445944Smckusic printf("cg[%d].cg_cs.cs_nifree is %d; calc %d\n", 4455381Smckusic c, cgrp.cg_cs.cs_nifree, n); 4464236Smckusick inosumbad++; 4474236Smckusick } 448*6491Smckusick if (cgrp.cg_cs.cs_nbfree != sblock.fs_cs(&sblock, c).cs_nbfree 449*6491Smckusick || cgrp.cg_cs.cs_nffree != sblock.fs_cs(&sblock, c).cs_nffree 450*6491Smckusick || cgrp.cg_cs.cs_nifree != sblock.fs_cs(&sblock, c).cs_nifree 451*6491Smckusick || cgrp.cg_cs.cs_ndir != sblock.fs_cs(&sblock, c).cs_ndir) 452*6491Smckusick sbsumbad++; 4534236Smckusick } 4544236Smckusick /* 1b */ 4554236Smckusick if (enddup != &duplist[0]) { 4564236Smckusick if (preen) 4574236Smckusick pfatal("INTERNAL ERROR: dups with -p"); 4584236Smckusick printf("** Phase 1b - Rescan For More DUPS\n"); 4594236Smckusick pfunc = pass1b; 4604236Smckusick inum = 0; 4614236Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 4624465Smckusic for (i = 0; i < sblock.fs_ipg; i++, inum++) { 4634465Smckusic dp = ginode(); 4644465Smckusic if (dp == NULL) 4654465Smckusic continue; 4664236Smckusick if (getstate() != USTATE && 4674236Smckusick (ckinode(dp, ADDR) & STOP)) 4684236Smckusick goto out1b; 4694465Smckusic } 4704236Smckusick } 4714236Smckusick } 4724236Smckusick out1b: 4734465Smckusic flush(&dfile, &inoblk); 4744236Smckusick /* 2 */ 4754236Smckusick if (preen == 0) 4764236Smckusick printf("** Phase 2 - Check Pathnames\n"); 4774236Smckusick inum = ROOTINO; 4784236Smckusick thisname = pathp = pathname; 4794236Smckusick pfunc = pass2; 4804236Smckusick switch (getstate()) { 4814236Smckusick 4824236Smckusick case USTATE: 4834236Smckusick errexit("ROOT INODE UNALLOCATED. TERMINATING.\n"); 4844236Smckusick 4854236Smckusick case FSTATE: 4864236Smckusick pfatal("ROOT INODE NOT DIRECTORY"); 4874236Smckusick if (reply("FIX") == 0 || (dp = ginode()) == NULL) 4884236Smckusick errexit(""); 4894236Smckusick dp->di_mode &= ~IFMT; 4904236Smckusick dp->di_mode |= IFDIR; 4914236Smckusick inodirty(); 4924236Smckusick inosumbad++; 4934236Smckusick setstate(DSTATE); 4944236Smckusick /* fall into ... */ 4954236Smckusick 4964236Smckusick case DSTATE: 4974236Smckusick descend(); 4984236Smckusick break; 4994236Smckusick 5004236Smckusick case CLEAR: 5014236Smckusick pfatal("DUPS/BAD IN ROOT INODE"); 5024236Smckusick printf("\n"); 5034236Smckusick if (reply("CONTINUE") == 0) 5044236Smckusick errexit(""); 5054236Smckusick setstate(DSTATE); 5064236Smckusick descend(); 5074236Smckusick } 5084236Smckusick /* 3 */ 5094236Smckusick if (preen == 0) 5104236Smckusick printf("** Phase 3 - Check Connectivity\n"); 5114236Smckusick for (inum = ROOTINO; inum <= lastino; inum++) { 5124236Smckusick if (getstate() == DSTATE) { 5134236Smckusick pfunc = findino; 5144236Smckusick srchname = ".."; 5154236Smckusick savino = inum; 5164236Smckusick do { 5174236Smckusick orphan = inum; 5184236Smckusick if ((dp = ginode()) == NULL) 5194236Smckusick break; 5204236Smckusick filsize = dp->di_size; 5214236Smckusick parentdir = 0; 5224236Smckusick ckinode(dp, DATA); 5234236Smckusick if ((inum = parentdir) == 0) 5244236Smckusick break; 5254236Smckusick } while (getstate() == DSTATE); 5264236Smckusick inum = orphan; 5274236Smckusick if (linkup() == 1) { 5284236Smckusick thisname = pathp = pathname; 5294236Smckusick *pathp++ = '?'; 5304236Smckusick pfunc = pass2; 5314236Smckusick descend(); 5324236Smckusick } 5334236Smckusick inum = savino; 5344236Smckusick } 5354236Smckusick } 5364236Smckusick /* 4 */ 5374236Smckusick if (preen == 0) 5384236Smckusick printf("** Phase 4 - Check Reference Counts\n"); 5394236Smckusick pfunc = pass4; 5404236Smckusick for (inum = ROOTINO; inum <= lastino; inum++) { 5414236Smckusick switch (getstate()) { 5424236Smckusick 5434236Smckusick case FSTATE: 5444236Smckusick if (n = getlncnt()) 5454236Smckusick adjust((short)n); 5464236Smckusick else { 5474236Smckusick for (blp = badlncnt;blp < badlnp; blp++) 5484236Smckusick if (*blp == inum) { 5494236Smckusick clri("UNREF", 1); 5504236Smckusick break; 5514236Smckusick } 5524236Smckusick } 5534236Smckusick break; 5544236Smckusick 5554236Smckusick case DSTATE: 5564236Smckusick clri("UNREF", 1); 5574236Smckusick break; 5584236Smckusick 5594236Smckusick case CLEAR: 5604236Smckusick clri("BAD/DUP", 1); 5614236Smckusick break; 5624236Smckusick } 5634236Smckusick } 5645337Smckusic if (imax - ROOTINO - n_files != sblock.fs_cstotal.cs_nifree) { 5654236Smckusick pwarn("FREE INODE COUNT WRONG IN SUPERBLK"); 5664236Smckusick if (preen) 5674236Smckusick printf(" (FIXED)\n"); 5684236Smckusick if (preen || reply("FIX") == 1) { 5695944Smckusic sblock.fs_cstotal.cs_nifree = imax - ROOTINO - n_files; 5704236Smckusick sbdirty(); 5714236Smckusick } 5724236Smckusick } 5734236Smckusick flush(&dfile, &fileblk); 5744236Smckusick 5754236Smckusick /* 5 */ 5764236Smckusick if (preen == 0) 5774236Smckusick printf("** Phase 5 - Check Cyl groups\n"); 5786314Smckusick copy(blockmap, freemap, (unsigned)bmapsz); 5794236Smckusick dupblk = 0; 5805381Smckusic n_index = sblock.fs_ncg * (cgdmin(&sblock, 0) - cgtod(&sblock, 0)); 5814236Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 5825381Smckusic daddr_t cbase = cgbase(&sblock, c); 5834236Smckusick short bo[MAXCPG][NRPOS]; 5845371Smckusic long botot[MAXCPG]; 5855325Smckusic long frsum[MAXFRAG]; 5864465Smckusic int blk; 5874465Smckusic 5885371Smckusic for (n = 0; n < sblock.fs_cpg; n++) { 5895371Smckusic botot[n] = 0; 5904236Smckusick for (i = 0; i < NRPOS; i++) 5914236Smckusick bo[n][i] = 0; 5925371Smckusic } 5935325Smckusic for (i = 0; i < sblock.fs_frag; i++) { 5944465Smckusic frsum[i] = 0; 5954465Smckusic } 5964465Smckusic /* 5974465Smckusic * need to account for the spare boot and super blocks 5984465Smckusic * which appear (inaccurately) bad 5994465Smckusic */ 6005381Smckusic n_bad += cgtod(&sblock, c) - cbase; 6015381Smckusic if (getblk(&cgblk, cgtod(&sblock, c), sblock.fs_cgsize) == 0) 6024236Smckusick continue; 6035325Smckusic for (b = 0; b < sblock.fs_fpg; b += sblock.fs_frag) { 6045325Smckusic if (isblock(&sblock, cgrp.cg_free, b/sblock.fs_frag)) { 6055325Smckusic if (pass5(cbase+b, sblock.fs_frag) == STOP) 6064236Smckusick goto out5; 6074236Smckusick /* this is clumsy ... */ 6085325Smckusic n_ffree -= sblock.fs_frag; 6094236Smckusick n_bfree++; 6105371Smckusic botot[cbtocylno(&sblock, b)]++; 6115363Smckusic bo[cbtocylno(&sblock, b)] 6125363Smckusic [cbtorpos(&sblock, b)]++; 6134465Smckusic } else { 6145325Smckusic for (d = 0; d < sblock.fs_frag; d++) 6154236Smckusick if (isset(cgrp.cg_free, b+d)) 6164236Smckusick if (pass5(cbase+b+d,1) == STOP) 6174236Smckusick goto out5; 6184465Smckusic blk = ((cgrp.cg_free[b / NBBY] >> (b % NBBY)) & 6195325Smckusic (0xff >> (NBBY - sblock.fs_frag))); 6204465Smckusic if (blk != 0) 6215325Smckusic fragacct(&sblock, blk, frsum, 1); 6224465Smckusic } 6234236Smckusick } 6245325Smckusic for (i = 0; i < sblock.fs_frag; i++) { 6254465Smckusic if (cgrp.cg_frsum[i] != frsum[i]) { 6265381Smckusic if (debug) 6275381Smckusic printf("cg[%d].cg_frsum[%d] have %d calc %d\n", 6285381Smckusic c, i, cgrp.cg_frsum[i], frsum[i]); 6294465Smckusic frsumbad++; 6304465Smckusic } 6314465Smckusic } 6325371Smckusic for (n = 0; n < sblock.fs_cpg; n++) { 6335371Smckusic if (botot[n] != cgrp.cg_btot[n]) { 6345381Smckusic if (debug) 6355381Smckusic printf("cg[%d].cg_btot[%d] have %d calc %d\n", 6365381Smckusic c, n, cgrp.cg_btot[n], botot[n]); 6375371Smckusic offsumbad++; 6385371Smckusic } 6394236Smckusick for (i = 0; i < NRPOS; i++) 6404236Smckusick if (bo[n][i] != cgrp.cg_b[n][i]) { 6415381Smckusic if (debug) 6425381Smckusic printf("cg[%d].cg_b[%d][%d] have %d calc %d\n", 6435381Smckusic c, n, i, cgrp.cg_b[n][i], 6445381Smckusic bo[n][i]); 6454236Smckusick offsumbad++; 6464236Smckusick } 6475371Smckusic } 6484236Smckusick } 6494236Smckusick out5: 6504236Smckusick if (dupblk) 6514236Smckusick pwarn("%d DUP BLKS IN BIT MAPS\n", dupblk); 6524236Smckusick if (fixcg == 0) { 6535325Smckusic if ((b = n_blks+n_ffree+sblock.fs_frag*n_bfree+n_index+n_bad) != fmax) { 6544236Smckusick pwarn("%ld BLK(S) MISSING\n", fmax - b); 6554236Smckusick fixcg = 1; 656*6491Smckusick } else if (inosumbad + offsumbad + frsumbad + sbsumbad) { 657*6491Smckusick pwarn("SUMMARY INFORMATION %s%s%s%sBAD\n", 6584236Smckusick inosumbad ? "(INODE FREE) " : "", 6594465Smckusic offsumbad ? "(BLOCK OFFSETS) " : "", 660*6491Smckusick frsumbad ? "(FRAG SUMMARIES) " : "", 661*6491Smckusick sbsumbad ? "(SUPER BLOCK SUMMARIES) " : ""); 6624236Smckusick fixcg = 1; 6634789Smckusic } else if (n_ffree != sblock.fs_cstotal.cs_nffree || 6644789Smckusic n_bfree != sblock.fs_cstotal.cs_nbfree) { 6654236Smckusick pwarn("FREE BLK COUNT(S) WRONG IN SUPERBLK"); 6664236Smckusick if (preen) 6674236Smckusick printf(" (FIXED)\n"); 6684236Smckusick if (preen || reply("FIX") == 1) { 6694789Smckusic sblock.fs_cstotal.cs_nffree = n_ffree; 6704789Smckusic sblock.fs_cstotal.cs_nbfree = n_bfree; 6714236Smckusick sbdirty(); 6724236Smckusick } 6734236Smckusick } 6744236Smckusick } 6754236Smckusick if (fixcg) { 6764236Smckusick pwarn("BAD CYLINDER GROUPS"); 6774236Smckusick if (preen) 6784236Smckusick printf(" (SALVAGED)\n"); 6794236Smckusick else if (reply("SALVAGE") == 0) 6804236Smckusick fixcg = 0; 6814236Smckusick } 6824236Smckusick 6834236Smckusick if (fixcg) { 6844236Smckusick if (preen == 0) 6854236Smckusick printf("** Phase 6 - Salvage Cylinder Groups\n"); 6864236Smckusick makecg(); 6874789Smckusic n_ffree = sblock.fs_cstotal.cs_nffree; 6884789Smckusic n_bfree = sblock.fs_cstotal.cs_nbfree; 6894236Smckusick } 6904236Smckusick 6914236Smckusick pwarn("%d files, %d used, %d free (%d frags, %d blocks)\n", 6925325Smckusic n_files, n_blks - howmany(sblock.fs_cssize, sblock.fs_bsize) * sblock.fs_frag, 6935325Smckusic n_ffree + sblock.fs_frag * n_bfree, n_ffree, n_bfree); 6944236Smckusick if (dfile.mod) { 6954236Smckusick time(&sblock.fs_time); 6964236Smckusick sbdirty(); 6974236Smckusick } 6984236Smckusick ckfini(); 6994236Smckusick sync(); 7004236Smckusick if (dfile.mod && hotroot) { 7014236Smckusick printf("\n***** BOOT UNIX (NO SYNC!) *****\n"); 7024236Smckusick exit(4); 7034236Smckusick } 7044236Smckusick if (dfile.mod && preen == 0) 7054236Smckusick printf("\n***** FILE SYSTEM WAS MODIFIED *****\n"); 7066314Smckusick free(blockmap); 7074236Smckusick free(freemap); 7084236Smckusick free(statemap); 7094236Smckusick free(lncntp); 7104236Smckusick } 7114236Smckusick 7124236Smckusick /* VARARGS1 */ 7134236Smckusick error(s1, s2, s3, s4) 7144715Smckusic char *s1; 7154236Smckusick { 7164236Smckusick 7174236Smckusick printf(s1, s2, s3, s4); 7184236Smckusick } 7194236Smckusick 7204236Smckusick /* VARARGS1 */ 7214236Smckusick errexit(s1, s2, s3, s4) 7224715Smckusic char *s1; 7234236Smckusick { 7244236Smckusick error(s1, s2, s3, s4); 7254236Smckusick exit(8); 7264236Smckusick } 7274236Smckusick 7284236Smckusick /* 7294236Smckusick * An inconsistency occured which shouldn't during normal operations. 7304236Smckusick * Die if preening, otw just printf. 7314236Smckusick */ 7324236Smckusick /* VARARGS1 */ 7334236Smckusick pfatal(s, a1, a2, a3) 7344236Smckusick char *s; 7354236Smckusick { 7364236Smckusick 7374236Smckusick if (preen) { 7384236Smckusick printf("%s: ", devname); 7394236Smckusick printf(s, a1, a2, a3); 7404236Smckusick printf("\n"); 7414236Smckusick preendie(); 7424236Smckusick } 7434236Smckusick printf(s, a1, a2, a3); 7444236Smckusick } 7454236Smckusick 7464236Smckusick preendie() 7474236Smckusick { 7484236Smckusick 7494236Smckusick printf("%s: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n", devname); 7504236Smckusick exit(8); 7514236Smckusick } 7524236Smckusick 7534236Smckusick /* 7544236Smckusick * Pwarn is like printf when not preening, 7554236Smckusick * or a warning (preceded by filename) when preening. 7564236Smckusick */ 7574236Smckusick /* VARARGS1 */ 7584236Smckusick pwarn(s, a1, a2, a3, a4, a5) 7594236Smckusick char *s; 7604236Smckusick { 7614236Smckusick 7624236Smckusick if (preen) 7634236Smckusick printf("%s: ", devname); 7644236Smckusick printf(s, a1, a2, a3, a4, a5); 7654236Smckusick } 7664236Smckusick 7674236Smckusick ckinode(dp, flg) 7684236Smckusick DINODE *dp; 7694236Smckusick register flg; 7704236Smckusick { 7714236Smckusick register daddr_t *ap; 7724236Smckusick register ret; 7735956Smckusic int (*func)(), n, ndb, size, offset; 7744236Smckusick 7754236Smckusick if (SPECIAL) 7764236Smckusick return (KEEPON); 7774236Smckusick func = (flg == ADDR) ? pfunc : dirscan; 7785325Smckusic ndb = howmany(dp->di_size, sblock.fs_bsize); 7794428Smckusic for (ap = &dp->di_db[0]; ap < &dp->di_db[NDADDR]; ap++) { 7805956Smckusic if (--ndb == 0 && (offset = blkoff(&sblock, dp->di_size)) != 0) 7815956Smckusic size = numfrags(&sblock, fragroundup(&sblock, offset)); 7824236Smckusick else 7835325Smckusic size = sblock.fs_frag; 7844236Smckusick if (*ap && (ret = (*func)(*ap, size)) & STOP) 7854236Smckusick return (ret); 7864236Smckusick } 7874428Smckusic for (ap = &dp->di_ib[0], n = 1; n <= 2; ap++, n++) { 7885325Smckusic if (*ap && (ret = iblock(*ap, n, flg, dp->di_size - sblock.fs_bsize * NDADDR)) & STOP) 7894236Smckusick return (ret); 7904236Smckusick } 7914236Smckusick return (KEEPON); 7924236Smckusick } 7934236Smckusick 7944236Smckusick iblock(blk, ilevel, flg, isize) 7954236Smckusick daddr_t blk; 7964236Smckusick register ilevel; 7974236Smckusick int isize; 7984236Smckusick { 7994236Smckusick register daddr_t *ap; 8004236Smckusick register daddr_t *aplim; 8014428Smckusic register int i, n; 8024236Smckusick int (*func)(), nif; 8034236Smckusick BUFAREA ib; 8044236Smckusick 8054236Smckusick if (flg == ADDR) { 8064236Smckusick func = pfunc; 8075325Smckusic if (((n = (*func)(blk, sblock.fs_frag)) & KEEPON) == 0) 8084236Smckusick return (n); 8094236Smckusick } else 8104236Smckusick func = dirscan; 8114236Smckusick if (outrange(blk)) /* protect thyself */ 8124236Smckusick return (SKIP); 8134236Smckusick initbarea(&ib); 8145325Smckusic if (getblk(&ib, blk, sblock.fs_bsize) == NULL) 8154236Smckusick return (SKIP); 8164236Smckusick ilevel--; 8174428Smckusic if (ilevel == 0) { 8185956Smckusic nif = lblkno(&sblock, isize) + 1; 8194428Smckusic } else /* ilevel == 1 */ { 8205325Smckusic nif = isize / (sblock.fs_bsize * NINDIR(&sblock)) + 1; 8214428Smckusic } 8225325Smckusic if (nif > NINDIR(&sblock)) 8235325Smckusic nif = NINDIR(&sblock); 8244428Smckusic aplim = & ib.b_un.b_indir[nif]; 8254428Smckusic for (ap = ib.b_un.b_indir, i = 1; ap < aplim; ap++, i++) 8264236Smckusick if (*ap) { 8274236Smckusick if (ilevel > 0) 8285325Smckusic n = iblock(*ap, ilevel, flg, isize - i * NINDIR(&sblock) * sblock.fs_bsize); 8294236Smckusick else 8305325Smckusic n = (*func)(*ap, sblock.fs_frag); 8314236Smckusick if (n & STOP) 8324236Smckusick return (n); 8334236Smckusick } 8344236Smckusick return (KEEPON); 8354236Smckusick } 8364236Smckusick 8374236Smckusick pass1(blk, size) 8384236Smckusick daddr_t blk; 8394236Smckusick int size; 8404236Smckusick { 8414236Smckusick register daddr_t *dlp; 8424236Smckusick int res = KEEPON; 8434236Smckusick 8444236Smckusick for (; size > 0; blk++, size--) { 8454236Smckusick if (outrange(blk)) { 8464236Smckusick blkerr("BAD", blk); 8474236Smckusick if (++badblk >= MAXBAD) { 8484236Smckusick printf("EXCESSIVE BAD BLKS I=%u", inum); 8494236Smckusick if (reply("CONTINUE") == 0) 8504236Smckusick errexit(""); 8514236Smckusick return (STOP); 8524236Smckusick } 8534236Smckusick res = SKIP; 8544236Smckusick } else if (getbmap(blk)) { 8554236Smckusick blkerr("DUP", blk); 8564236Smckusick if (++dupblk >= MAXDUP) { 8574236Smckusick printf("EXCESSIVE DUP BLKS I=%u", inum); 8584236Smckusick if (reply("CONTINUE") == 0) 8594236Smckusick errexit(""); 8604236Smckusick return (STOP); 8614236Smckusick } 8624236Smckusick if (enddup >= &duplist[DUPTBLSIZE]) { 8634236Smckusick printf("DUP TABLE OVERFLOW."); 8644236Smckusick if (reply("CONTINUE") == 0) 8654236Smckusick errexit(""); 8664236Smckusick return (STOP); 8674236Smckusick } 8684236Smckusick for (dlp = duplist; dlp < muldup; dlp++) 8694236Smckusick if (*dlp == blk) { 8704236Smckusick *enddup++ = blk; 8714236Smckusick break; 8724236Smckusick } 8734236Smckusick if (dlp >= muldup) { 8744236Smckusick *enddup++ = *muldup; 8754236Smckusick *muldup++ = blk; 8764236Smckusick } 8774236Smckusick } else { 8784236Smckusick n_blks++; 8794236Smckusick setbmap(blk); 8804236Smckusick } 8814236Smckusick filsize++; 8824236Smckusick } 8834236Smckusick return (res); 8844236Smckusick } 8854236Smckusick 8864236Smckusick pass1b(blk, size) 8874236Smckusick daddr_t blk; 8884236Smckusick int size; 8894236Smckusick { 8904236Smckusick register daddr_t *dlp; 8914236Smckusick int res = KEEPON; 8924236Smckusick 8934236Smckusick for (; size > 0; blk++, size--) { 8944236Smckusick if (outrange(blk)) 8954236Smckusick res = SKIP; 8964236Smckusick for (dlp = duplist; dlp < muldup; dlp++) 8974236Smckusick if (*dlp == blk) { 8984236Smckusick blkerr("DUP", blk); 8994236Smckusick *dlp = *--muldup; 9004236Smckusick *muldup = blk; 9014236Smckusick if (muldup == duplist) 9024236Smckusick return (STOP); 9034236Smckusick } 9044236Smckusick } 9054236Smckusick return (res); 9064236Smckusick } 9074236Smckusick 9084236Smckusick pass2(dirp) 9094236Smckusick register DIRECT *dirp; 9104236Smckusick { 9114236Smckusick register char *p; 9124236Smckusick register n; 9134236Smckusick DINODE *dp; 9144236Smckusick 9154236Smckusick if ((inum = dirp->d_ino) == 0) 9164236Smckusick return (KEEPON); 9174236Smckusick thisname = pathp; 9185877Smckusic for (p = dirp->d_name; p < &dirp->d_name[MAXNAMLEN]; ) 9194236Smckusick if ((*pathp++ = *p++) == 0) { 9204236Smckusick --pathp; 9214236Smckusick break; 9224236Smckusick } 9234236Smckusick *pathp = 0; 9244236Smckusick n = 0; 9254715Smckusic if (inum > imax || inum <= 0) 9264236Smckusick n = direrr("I OUT OF RANGE"); 9274236Smckusick else { 9284236Smckusick again: 9294236Smckusick switch (getstate()) { 9304236Smckusick case USTATE: 9314236Smckusick n = direrr("UNALLOCATED"); 9324236Smckusick break; 9334236Smckusick 9344236Smckusick case CLEAR: 9354236Smckusick if ((n = direrr("DUP/BAD")) == 1) 9364236Smckusick break; 9374236Smckusick if ((dp = ginode()) == NULL) 9384236Smckusick break; 9395877Smckusic setstate(DIRCT ? DSTATE : FSTATE); 9404236Smckusick goto again; 9414236Smckusick 9424236Smckusick case FSTATE: 9434236Smckusick declncnt(); 9444236Smckusick break; 9454236Smckusick 9464236Smckusick case DSTATE: 9474236Smckusick declncnt(); 9484236Smckusick descend(); 9494236Smckusick break; 9504236Smckusick } 9514236Smckusick } 9524236Smckusick pathp = thisname; 9534236Smckusick if (n == 0) 9544236Smckusick return (KEEPON); 9554236Smckusick dirp->d_ino = 0; 9564236Smckusick return (KEEPON|ALTERD); 9574236Smckusick } 9584236Smckusick 9594236Smckusick pass4(blk, size) 9604715Smckusic daddr_t blk; 9614236Smckusick { 9624236Smckusick register daddr_t *dlp; 9634236Smckusick int res = KEEPON; 9644236Smckusick 9654236Smckusick for (; size > 0; blk++, size--) { 9664236Smckusick if (outrange(blk)) 9674236Smckusick res = SKIP; 9684236Smckusick else if (getbmap(blk)) { 9694236Smckusick for (dlp = duplist; dlp < enddup; dlp++) 9704236Smckusick if (*dlp == blk) { 9714236Smckusick *dlp = *--enddup; 9724236Smckusick return (KEEPON); 9734236Smckusick } 9744236Smckusick clrbmap(blk); 9754236Smckusick n_blks--; 9764236Smckusick } 9774236Smckusick } 9784236Smckusick return (res); 9794236Smckusick } 9804236Smckusick 9814236Smckusick pass5(blk, size) 9824236Smckusick daddr_t blk; 9834236Smckusick int size; 9844236Smckusick { 9854236Smckusick int res = KEEPON; 9864236Smckusick 9874236Smckusick for (; size > 0; blk++, size--) { 9884236Smckusick if (outrange(blk)) { 9894236Smckusick fixcg = 1; 9904236Smckusick if (preen) 9914236Smckusick pfatal("BAD BLOCKS IN BIT MAPS."); 9924236Smckusick if (++badblk >= MAXBAD) { 9934236Smckusick printf("EXCESSIVE BAD BLKS IN BIT MAPS."); 9944236Smckusick if (reply("CONTINUE") == 0) 9954236Smckusick errexit(""); 9964236Smckusick return (STOP); 9974236Smckusick } 9984236Smckusick } else if (getfmap(blk)) { 9994236Smckusick fixcg = 1; 10004236Smckusick if (++dupblk >= DUPTBLSIZE) { 10014236Smckusick printf("EXCESSIVE DUP BLKS IN BIT MAPS."); 10024236Smckusick if (reply("CONTINUE") == 0) 10034236Smckusick errexit(""); 10044236Smckusick return (STOP); 10054236Smckusick } 10064236Smckusick } else { 10074236Smckusick n_ffree++; 10084236Smckusick setfmap(blk); 10094236Smckusick } 10104236Smckusick } 10114236Smckusick return (res); 10124236Smckusick } 10134236Smckusick 10144236Smckusick outrange(blk) 10154236Smckusick daddr_t blk; 10164236Smckusick { 10174236Smckusick register int c; 10184236Smckusick 10195381Smckusic c = dtog(&sblock, blk); 10205381Smckusic if (blk >= fmax || blk < cgdmin(&sblock, c)) { 10214236Smckusick return (1); 10224428Smckusic } 10234236Smckusick return (0); 10244236Smckusick } 10254236Smckusick 10264236Smckusick blkerr(s, blk) 10274236Smckusick daddr_t blk; 10284236Smckusick char *s; 10294236Smckusick { 10304236Smckusick pfatal("%ld %s I=%u", blk, s, inum); 10314236Smckusick printf("\n"); 10324236Smckusick setstate(CLEAR); /* mark for possible clearing */ 10334236Smckusick } 10344236Smckusick 10354236Smckusick descend() 10364236Smckusick { 10374236Smckusick register DINODE *dp; 10384236Smckusick register char *savname; 10394236Smckusick off_t savsize; 10404236Smckusick 10414236Smckusick setstate(FSTATE); 10424236Smckusick if ((dp = ginode()) == NULL) 10434236Smckusick return; 10444236Smckusick savname = thisname; 10454236Smckusick *pathp++ = '/'; 10464236Smckusick savsize = filsize; 10474236Smckusick filsize = dp->di_size; 10484236Smckusick ckinode(dp, DATA); 10494236Smckusick thisname = savname; 10504236Smckusick *--pathp = 0; 10514236Smckusick filsize = savsize; 10524236Smckusick } 10534236Smckusick 10545877Smckusic struct dirstuff { 10555877Smckusic int loc; 10565877Smckusic int blkno; 10575877Smckusic int blksiz; 10585877Smckusic }; 10595877Smckusic 10604236Smckusick dirscan(blk, nf) 10614715Smckusic daddr_t blk; 10624715Smckusic int nf; 10634236Smckusick { 10645877Smckusic register DIRECT *dp; 10655877Smckusic struct dirstuff dirp; 10666251Smckusick int blksiz, dsize, n; 10676251Smckusick char dbuf[DIRBLKSIZ]; 10684236Smckusick 10694236Smckusick if (outrange(blk)) { 10705325Smckusic filsize -= sblock.fs_bsize; 10714236Smckusick return (SKIP); 10724236Smckusick } 10735877Smckusic blksiz = nf * sblock.fs_fsize; 10745877Smckusic dirp.loc = 0; 10755877Smckusic dirp.blkno = blk; 10765877Smckusic dirp.blksiz = blksiz; 10775877Smckusic for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) { 10786251Smckusick dsize = dp->d_reclen; 10796251Smckusick copy(dp, dbuf, dsize); 10806251Smckusick if ((n = (*pfunc)(dbuf)) & ALTERD) { 10815877Smckusic if (getblk(&fileblk, blk, blksiz) != NULL) { 10826251Smckusick copy(dbuf, dp, dsize); 10834715Smckusic dirty(&fileblk); 10844236Smckusick sbdirty(); 10854236Smckusick } else 10864236Smckusick n &= ~ALTERD; 10874236Smckusick } 10885877Smckusic if (n & STOP) 10894236Smckusick return (n); 10904236Smckusick } 10914236Smckusick return (filsize > 0 ? KEEPON : STOP); 10924236Smckusick } 10934236Smckusick 10945877Smckusic /* 10955877Smckusic * get next entry in a directory. 10965877Smckusic */ 10975877Smckusic DIRECT * 10985877Smckusic readdir(dirp) 10995877Smckusic register struct dirstuff *dirp; 11005877Smckusic { 11016251Smckusick register DIRECT *dp, *ndp; 11025877Smckusic 11035877Smckusic if (getblk(&fileblk, dirp->blkno, dirp->blksiz) == NULL) { 11045877Smckusic filsize -= dirp->blksiz - dirp->loc; 11055877Smckusic return NULL; 11065877Smckusic } 11075877Smckusic for (;;) { 11085877Smckusic if (filsize <= 0 || dirp->loc >= dirp->blksiz) 11095877Smckusic return NULL; 11105935Smckusic dp = (DIRECT *)(dirblk.b_buf + dirp->loc); 11115935Smckusic dirp->loc += dp->d_reclen; 11125935Smckusic filsize -= dp->d_reclen; 11136251Smckusick ndp = (DIRECT *)(dirblk.b_buf + dirp->loc); 11146372Smckusick if (dirp->loc < dirp->blksiz && filsize > 0 && 11156251Smckusick (ndp->d_ino > imax || ndp->d_namlen > MAXNAMLEN || 11166251Smckusick ndp->d_reclen <= 0 || 11176251Smckusick ndp->d_reclen > DIRBLKSIZ - (dirp->loc % DIRBLKSIZ))) { 11186251Smckusick pwarn("DIRECTORY CORRUPTED"); 11196251Smckusick if (preen) 11206251Smckusick printf(" (SALVAGED)\n"); 11216251Smckusick else if (reply("SALVAGE") == 0) { 11226251Smckusick dirp->loc += 11236251Smckusick DIRBLKSIZ - (dirp->loc % DIRBLKSIZ); 11246251Smckusick filsize -= DIRBLKSIZ - (dirp->loc % DIRBLKSIZ); 11256251Smckusick return(dp); 11266251Smckusick } 11276251Smckusick dirp->loc -= dp->d_reclen; 11286251Smckusick filsize += dp->d_reclen; 11296251Smckusick dp->d_reclen = DIRBLKSIZ - (dirp->loc % DIRBLKSIZ); 11306251Smckusick dirty(&fileblk); 11315877Smckusic continue; 11326251Smckusick } 11335935Smckusic return (dp); 11345877Smckusic } 11355877Smckusic } 11365877Smckusic 11374236Smckusick direrr(s) 11384715Smckusic char *s; 11394236Smckusick { 11404236Smckusick register DINODE *dp; 11414236Smckusick 11424236Smckusick pwarn("%s ", s); 11434236Smckusick pinode(); 11444236Smckusick printf("\n"); 11454236Smckusick if ((dp = ginode()) != NULL && ftypeok(dp)) 11465877Smckusic pfatal("%s=%s", DIRCT?"DIR":"FILE", pathname); 11474236Smckusick else 11484236Smckusick pfatal("NAME=%s", pathname); 11494236Smckusick return (reply("REMOVE")); 11504236Smckusick } 11514236Smckusick 11524236Smckusick adjust(lcnt) 11534465Smckusic register short lcnt; 11544236Smckusick { 11554236Smckusick register DINODE *dp; 11564236Smckusick 11574236Smckusick if ((dp = ginode()) == NULL) 11584236Smckusick return; 11594236Smckusick if (dp->di_nlink == lcnt) { 11604236Smckusick if (linkup() == 0) 11614236Smckusick clri("UNREF", 0); 11624236Smckusick } 11634236Smckusick else { 11644236Smckusick pwarn("LINK COUNT %s", 11655877Smckusic (lfdir==inum)?lfname:(DIRCT?"DIR":"FILE")); 11664236Smckusick pinode(); 11674236Smckusick printf(" COUNT %d SHOULD BE %d", 11684236Smckusick dp->di_nlink, dp->di_nlink-lcnt); 11694236Smckusick if (preen) { 11704236Smckusick if (lcnt < 0) { 11714236Smckusick printf("\n"); 11724236Smckusick preendie(); 11734236Smckusick } 11744236Smckusick printf(" (ADJUSTED)\n"); 11754236Smckusick } 11764236Smckusick if (preen || reply("ADJUST") == 1) { 11774236Smckusick dp->di_nlink -= lcnt; 11784236Smckusick inodirty(); 11794236Smckusick } 11804236Smckusick } 11814236Smckusick } 11824236Smckusick 11834236Smckusick clri(s, flg) 11844715Smckusic char *s; 11854236Smckusick { 11864236Smckusick register DINODE *dp; 11874236Smckusick 11884236Smckusick if ((dp = ginode()) == NULL) 11894236Smckusick return; 11904236Smckusick if (flg == 1) { 11915877Smckusic pwarn("%s %s", s, DIRCT?"DIR":"FILE"); 11924236Smckusick pinode(); 11934236Smckusick } 11944236Smckusick if (preen || reply("CLEAR") == 1) { 11954236Smckusick if (preen) 11964236Smckusick printf(" (CLEARED)\n"); 11974236Smckusick n_files--; 11984236Smckusick pfunc = pass4; 11994236Smckusick ckinode(dp, ADDR); 12004236Smckusick zapino(dp); 12014465Smckusic setstate(USTATE); 12024236Smckusick inodirty(); 12034236Smckusick inosumbad++; 12044236Smckusick } 12054236Smckusick } 12064236Smckusick 12074236Smckusick setup(dev) 12084715Smckusic char *dev; 12094236Smckusick { 12104236Smckusick dev_t rootdev; 12116489Smckusick struct stat statb; 12124236Smckusick int super = bflag ? bflag : SBLOCK; 1213*6491Smckusick int i; 12144236Smckusick 12154236Smckusick bflag = 0; 12164236Smckusick if (stat("/", &statb) < 0) 12174236Smckusick errexit("Can't stat root\n"); 12184236Smckusick rootdev = statb.st_dev; 12194236Smckusick if (stat(dev, &statb) < 0) { 12204236Smckusick error("Can't stat %s\n", dev); 12214236Smckusick return (0); 12224236Smckusick } 12234236Smckusick rawflg = 0; 12244236Smckusick if ((statb.st_mode & S_IFMT) == S_IFBLK) 12254236Smckusick ; 12264236Smckusick else if ((statb.st_mode & S_IFMT) == S_IFCHR) 12274236Smckusick rawflg++; 12284236Smckusick else { 12294236Smckusick if (reply("file is not a block or character device; OK") == 0) 12304236Smckusick return (0); 12314236Smckusick } 12324236Smckusick if (rootdev == statb.st_rdev) 12334236Smckusick hotroot++; 12344236Smckusick if ((dfile.rfdes = open(dev, 0)) < 0) { 12354236Smckusick error("Can't open %s\n", dev); 12364236Smckusick return (0); 12374236Smckusick } 12384236Smckusick if (preen == 0) 12394236Smckusick printf("** %s", dev); 12404236Smckusick if (nflag || (dfile.wfdes = open(dev, 1)) < 0) { 12414236Smckusick dfile.wfdes = -1; 12424236Smckusick if (preen) 12434236Smckusick pfatal("NO WRITE ACCESS"); 12444236Smckusick printf(" (NO WRITE)"); 12454236Smckusick } 12464236Smckusick if (preen == 0) 12474236Smckusick printf("\n"); 1248*6491Smckusick fixcg = 0; inosumbad = 0; offsumbad = 0; frsumbad = 0; sbsumbad = 0; 12494236Smckusick dfile.mod = 0; 12504236Smckusick n_files = n_blks = n_ffree = n_bfree = 0; 12514236Smckusick muldup = enddup = &duplist[0]; 12524236Smckusick badlnp = &badlncnt[0]; 12534236Smckusick lfdir = 0; 12544236Smckusick rplyflag = 0; 12554236Smckusick initbarea(&sblk); 12564236Smckusick initbarea(&fileblk); 12574236Smckusick initbarea(&inoblk); 12584236Smckusick initbarea(&cgblk); 1259*6491Smckusick /* 1260*6491Smckusick * Read in the super block and its summary info. 1261*6491Smckusick */ 12625347Smckusic if (bread(&dfile, &sblock, super, SBSIZE) == 0) 12634236Smckusick return (0); 12644465Smckusic sblk.b_bno = super; 12655347Smckusic sblk.b_size = SBSIZE; 1266*6491Smckusick for (i = 0; i < howmany(sblock.fs_cssize, sblock.fs_bsize); i++) { 1267*6491Smckusick sblock.fs_csp[i] = (struct csum *)calloc(1, sblock.fs_bsize); 1268*6491Smckusick bread(&dfile, (char *)sblock.fs_csp[i], 1269*6491Smckusick fsbtodb(&sblock, sblock.fs_csaddr + (i * sblock.fs_frag)), 1270*6491Smckusick sblock.fs_bsize); 1271*6491Smckusick } 12725363Smckusic /* 12735363Smckusic * run a few consistency checks of the super block 12745363Smckusic */ 12754236Smckusick if (sblock.fs_magic != FS_MAGIC) 12764236Smckusick { badsb("MAGIC NUMBER WRONG"); return (0); } 12774236Smckusick if (sblock.fs_ncg < 1) 12784236Smckusick { badsb("NCG OUT OF RANGE"); return (0); } 12794236Smckusick if (sblock.fs_cpg < 1 || sblock.fs_cpg > MAXCPG) 12804236Smckusick { badsb("CPG OUT OF RANGE"); return (0); } 12814236Smckusick if (sblock.fs_nsect < 1) 12824236Smckusick { badsb("NSECT < 1"); return (0); } 12834236Smckusick if (sblock.fs_ntrak < 1) 12844236Smckusick { badsb("NTRAK < 1"); return (0); } 12855363Smckusic if (sblock.fs_spc != sblock.fs_nsect * sblock.fs_ntrak) 12865363Smckusic { badsb("SPC DOES NOT JIVE w/NTRAK*NSECT"); return (0); } 12875363Smckusic if (sblock.fs_ipg % INOPB(&sblock)) 12885363Smckusic { badsb("INODES NOT MULTIPLE OF A BLOCK"); return (0); } 12895381Smckusic if (cgdmin(&sblock, 0) >= sblock.fs_cpg * sblock.fs_spc / NSPF(&sblock)) 12904236Smckusick { badsb("IMPLIES MORE INODE THAN DATA BLOCKS"); return (0); } 12915363Smckusic if (sblock.fs_ncg * sblock.fs_cpg < sblock.fs_ncyl || 12925363Smckusic (sblock.fs_ncg - 1) * sblock.fs_cpg >= sblock.fs_ncyl) 12934236Smckusick { badsb("NCYL DOES NOT JIVE WITH NCG*CPG"); return (0); } 12945325Smckusic if (sblock.fs_fpg != sblock.fs_cpg * sblock.fs_spc / NSPF(&sblock)) 12954236Smckusick { badsb("FPG DOES NOT JIVE WITH CPG & SPC"); return (0); } 12965363Smckusic if (sblock.fs_size * NSPF(&sblock) <= 12975363Smckusic (sblock.fs_ncyl - 1) * sblock.fs_spc) 12984236Smckusick { badsb("SIZE PREPOSTEROUSLY SMALL"); return (0); } 12995363Smckusic if (sblock.fs_size * NSPF(&sblock) > sblock.fs_ncyl * sblock.fs_spc) 13004236Smckusick { badsb("SIZE PREPOSTEROUSLY LARGE"); return (0); } 13014236Smckusick /* rest we COULD repair... */ 13024236Smckusick if (sblock.fs_sblkno != SBLOCK) 13035363Smckusic { badsb("SBLKNO CORRUPTED"); return (0); } 13045363Smckusic if (sblock.fs_cblkno != 13055363Smckusic roundup(howmany(BBSIZE + SBSIZE, sblock.fs_fsize), sblock.fs_frag)) 13065363Smckusic { badsb("CBLKNO CORRUPTED"); return (0); } 13075363Smckusic if (sblock.fs_iblkno != sblock.fs_cblkno + sblock.fs_frag) 13085363Smckusic { badsb("IBLKNO CORRUPTED"); return (0); } 13095363Smckusic if (sblock.fs_dblkno != 13105363Smckusic sblock.fs_iblkno + sblock.fs_ipg / INOPF(&sblock)) 13115363Smckusic { badsb("DBLKNO CORRUPTED"); return (0); } 13125956Smckusic if (sblock.fs_cgsize != fragroundup(&sblock, 13135956Smckusic sizeof(struct cg) + howmany(sblock.fs_fpg, NBBY))) 13144236Smckusick { badsb("CGSIZE INCORRECT"); return (0); } 13155325Smckusic if (sblock.fs_cssize != sblock.fs_ncg * sizeof(struct csum)) 13164236Smckusick { badsb("CSSIZE INCORRECT"); return (0); } 13174236Smckusick fmax = sblock.fs_size; 13184236Smckusick imax = sblock.fs_ncg * sblock.fs_ipg; 13195363Smckusic /* 13205363Smckusic * allocate the necessary maps 13215363Smckusic */ 13224236Smckusick bmapsz = roundup(howmany(fmax, NBBY), sizeof(short)); 13236314Smckusick blockmap = (char *)calloc(bmapsz, sizeof (char)); 13244236Smckusick freemap = (char *)calloc(bmapsz, sizeof (char)); 13254236Smckusick statemap = (char *)calloc(imax+1, sizeof(char)); 13264236Smckusick lncntp = (short *)calloc(imax+1, sizeof(short)); 13274236Smckusick 13284465Smckusic startinum = imax + 1; 13294236Smckusick return (1); 13304236Smckusick 13314236Smckusick badsb: 13324236Smckusick ckfini(); 13334236Smckusick return (0); 13344236Smckusick } 13354236Smckusick 13364236Smckusick badsb(s) 13374236Smckusick char *s; 13384236Smckusick { 13394236Smckusick 13404236Smckusick if (preen) 13414236Smckusick printf("%s: ", devname); 13424236Smckusick printf("BAD SUPER BLOCK: %s\n", s); 13434236Smckusick pwarn("USE -b OPTION TO FSCK TO SPECIFY LOCATION OF AN ALTERNATE\n"); 13444236Smckusick pfatal("SUPER-BLOCK TO SUPPLY NEEDED INFORMATION; SEE fsck(8).\n"); 13454236Smckusick } 13464236Smckusick 13474236Smckusick DINODE * 13484236Smckusick ginode() 13494236Smckusick { 13504236Smckusick daddr_t iblk; 13514236Smckusick 13525337Smckusic if (inum < ROOTINO || inum > imax) 13534236Smckusick return (NULL); 13545325Smckusic if (inum < startinum || inum >= startinum + INOPB(&sblock)) { 13555381Smckusic iblk = itod(&sblock, inum); 13565325Smckusic if (getblk(&inoblk, iblk, sblock.fs_bsize) == NULL) { 13574236Smckusick return (NULL); 13584236Smckusick } 13595325Smckusic startinum = (inum / INOPB(&sblock)) * INOPB(&sblock); 13604236Smckusick } 13615325Smckusic return (&inoblk.b_un.b_dinode[inum % INOPB(&sblock)]); 13624236Smckusick } 13634236Smckusick 13644236Smckusick ftypeok(dp) 13654236Smckusick DINODE *dp; 13664236Smckusick { 13674236Smckusick switch (dp->di_mode & IFMT) { 13684236Smckusick 13694236Smckusick case IFDIR: 13704236Smckusick case IFREG: 13714236Smckusick case IFBLK: 13724236Smckusick case IFCHR: 13736285Smckusick case IFLNK: 13744236Smckusick return (1); 13754236Smckusick 13764236Smckusick default: 13774236Smckusick return (0); 13784236Smckusick } 13794236Smckusick } 13804236Smckusick 13814236Smckusick reply(s) 13824236Smckusick char *s; 13834236Smckusick { 13844236Smckusick char line[80]; 13854236Smckusick 13864236Smckusick if (preen) 13874236Smckusick pfatal("INTERNAL ERROR: GOT TO reply()"); 13884236Smckusick rplyflag = 1; 13894236Smckusick printf("\n%s? ", s); 13904236Smckusick if (nflag || dfile.wfdes < 0) { 13914236Smckusick printf(" no\n\n"); 13924236Smckusick return (0); 13934236Smckusick } 13944236Smckusick if (yflag) { 13954236Smckusick printf(" yes\n\n"); 13964236Smckusick return (1); 13974236Smckusick } 13984236Smckusick if (getline(stdin, line, sizeof(line)) == EOF) 13994236Smckusick errexit("\n"); 14004236Smckusick printf("\n"); 14014236Smckusick if (line[0] == 'y' || line[0] == 'Y') 14024236Smckusick return (1); 14034236Smckusick else 14044236Smckusick return (0); 14054236Smckusick } 14064236Smckusick 14074236Smckusick getline(fp, loc, maxlen) 14084236Smckusick FILE *fp; 14094236Smckusick char *loc; 14104236Smckusick { 14114236Smckusick register n; 14124236Smckusick register char *p, *lastloc; 14134236Smckusick 14144236Smckusick p = loc; 14154236Smckusick lastloc = &p[maxlen-1]; 14164236Smckusick while ((n = getc(fp)) != '\n') { 14174236Smckusick if (n == EOF) 14184236Smckusick return (EOF); 14194236Smckusick if (!isspace(n) && p < lastloc) 14204236Smckusick *p++ = n; 14214236Smckusick } 14224236Smckusick *p = 0; 14234236Smckusick return (p - loc); 14244236Smckusick } 14254236Smckusick 14264236Smckusick BUFAREA * 14274236Smckusick getblk(bp, blk, size) 14284236Smckusick daddr_t blk; 14294236Smckusick register BUFAREA *bp; 14304236Smckusick int size; 14314236Smckusick { 14324236Smckusick register struct filecntl *fcp; 14335325Smckusic daddr_t dblk; 14344236Smckusick 14354236Smckusick fcp = &dfile; 14365325Smckusic dblk = fsbtodb(&sblock, blk); 14375325Smckusic if (bp->b_bno == dblk) 14384236Smckusick return (bp); 14394236Smckusick flush(fcp, bp); 14405325Smckusic if (bread(fcp, bp->b_un.b_buf, dblk, size) != 0) { 14415325Smckusic bp->b_bno = dblk; 14424236Smckusick bp->b_size = size; 14434236Smckusick return (bp); 14444236Smckusick } 14454236Smckusick bp->b_bno = (daddr_t)-1; 14464236Smckusick return (NULL); 14474236Smckusick } 14484236Smckusick 14494236Smckusick flush(fcp, bp) 14504236Smckusick struct filecntl *fcp; 14514236Smckusick register BUFAREA *bp; 14524236Smckusick { 14534236Smckusick 14544236Smckusick if (bp->b_dirty) 14554236Smckusick bwrite(fcp, bp->b_un.b_buf, bp->b_bno, bp->b_size); 14564236Smckusick bp->b_dirty = 0; 14574236Smckusick } 14584236Smckusick 14594236Smckusick rwerr(s, blk) 14604236Smckusick char *s; 14614236Smckusick daddr_t blk; 14624236Smckusick { 14634236Smckusick 14644236Smckusick if (preen == 0) 14654236Smckusick printf("\n"); 14664236Smckusick pfatal("CANNOT %s: BLK %ld", s, blk); 14674236Smckusick if (reply("CONTINUE") == 0) 14684236Smckusick errexit("Program terminated\n"); 14694236Smckusick } 14704236Smckusick 14714236Smckusick ckfini() 14724236Smckusick { 14734236Smckusick 14744236Smckusick flush(&dfile, &fileblk); 14754236Smckusick flush(&dfile, &sblk); 14764465Smckusic if (sblk.b_bno != SBLOCK) { 14774465Smckusic sblk.b_bno = SBLOCK; 14784465Smckusic sbdirty(); 14794465Smckusic flush(&dfile, &sblk); 14804465Smckusic } 14814236Smckusick flush(&dfile, &inoblk); 14824236Smckusick close(dfile.rfdes); 14834236Smckusick close(dfile.wfdes); 14844236Smckusick } 14854236Smckusick 14864236Smckusick pinode() 14874236Smckusick { 14884236Smckusick register DINODE *dp; 14894236Smckusick register char *p; 14905877Smckusic char uidbuf[BUFSIZ]; 14914236Smckusick char *ctime(); 14924236Smckusick 14934236Smckusick printf(" I=%u ", inum); 14944236Smckusick if ((dp = ginode()) == NULL) 14954236Smckusick return; 14964236Smckusick printf(" OWNER="); 14974236Smckusick if (getpw((int)dp->di_uid, uidbuf) == 0) { 14984236Smckusick for (p = uidbuf; *p != ':'; p++); 14994236Smckusick *p = 0; 15004236Smckusick printf("%s ", uidbuf); 15014236Smckusick } 15024236Smckusick else { 15034236Smckusick printf("%d ", dp->di_uid); 15044236Smckusick } 15054236Smckusick printf("MODE=%o\n", dp->di_mode); 15064236Smckusick if (preen) 15074236Smckusick printf("%s: ", devname); 15084236Smckusick printf("SIZE=%ld ", dp->di_size); 15094236Smckusick p = ctime(&dp->di_mtime); 15104236Smckusick printf("MTIME=%12.12s %4.4s ", p+4, p+20); 15114236Smckusick } 15124236Smckusick 15134236Smckusick copy(fp, tp, size) 15144236Smckusick register char *tp, *fp; 15154236Smckusick unsigned size; 15164236Smckusick { 15174236Smckusick 15184236Smckusick while (size--) 15194236Smckusick *tp++ = *fp++; 15204236Smckusick } 15214236Smckusick 15224236Smckusick makecg() 15234236Smckusick { 15244465Smckusic int c, blk; 15254236Smckusick daddr_t dbase, d, dmin, dmax; 15264236Smckusick long i, j, s; 15274236Smckusick register struct csum *cs; 15284465Smckusic register DINODE *dp; 15294236Smckusick 15304789Smckusic sblock.fs_cstotal.cs_nbfree = 0; 15314789Smckusic sblock.fs_cstotal.cs_nffree = 0; 15324789Smckusic sblock.fs_cstotal.cs_nifree = 0; 15334789Smckusic sblock.fs_cstotal.cs_ndir = 0; 15344236Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 15355381Smckusic dbase = cgbase(&sblock, c); 15364236Smckusick dmax = dbase + sblock.fs_fpg; 15375409Smckusic if (dmax > sblock.fs_size) { 15385944Smckusic for ( ; dmax >= sblock.fs_size; dmax--) 15395401Smckusic clrbit(cgrp.cg_free, dmax - dbase); 15405409Smckusic dmax++; 15415409Smckusic } 15425401Smckusic dmin = sblock.fs_dblkno; 15435325Smckusic cs = &sblock.fs_cs(&sblock, c); 15444236Smckusick cgrp.cg_time = time(0); 15454236Smckusick cgrp.cg_magic = CG_MAGIC; 15464236Smckusick cgrp.cg_cgx = c; 15474236Smckusick cgrp.cg_ncyl = sblock.fs_cpg; 15484236Smckusick cgrp.cg_niblk = sblock.fs_ipg; 15494236Smckusick cgrp.cg_ndblk = dmax - dbase; 15504789Smckusic cgrp.cg_cs.cs_ndir = 0; 15514789Smckusic cgrp.cg_cs.cs_nffree = 0; 15524789Smckusic cgrp.cg_cs.cs_nbfree = 0; 15534789Smckusic cgrp.cg_cs.cs_nifree = 0; 15544465Smckusic cgrp.cg_rotor = dmin; 15554465Smckusic cgrp.cg_frotor = dmin; 15564258Smckusic cgrp.cg_irotor = 0; 15575325Smckusic for (i = 0; i < sblock.fs_frag; i++) 15584465Smckusic cgrp.cg_frsum[i] = 0; 15594236Smckusick inum = sblock.fs_ipg * c; 15604465Smckusic for (i = 0; i < sblock.fs_ipg; inum++, i++) { 15615944Smckusic cgrp.cg_cs.cs_nifree++; 15625944Smckusic clrbit(cgrp.cg_iused, i); 15634465Smckusic dp = ginode(); 15644465Smckusic if (dp == NULL) 15654465Smckusic continue; 15664465Smckusic if (ALLOC) { 15675877Smckusic if (DIRCT) 15684789Smckusic cgrp.cg_cs.cs_ndir++; 15695944Smckusic cgrp.cg_cs.cs_nifree--; 15704465Smckusic setbit(cgrp.cg_iused, i); 15714465Smckusic continue; 15724465Smckusic } 15734236Smckusick } 15744236Smckusick while (i < MAXIPG) { 15754236Smckusick clrbit(cgrp.cg_iused, i); 15764236Smckusick i++; 15774236Smckusick } 15785944Smckusic if (c == 0) 15795944Smckusic for (i = 0; i < ROOTINO; i++) { 15805944Smckusic setbit(cgrp.cg_iused, i); 15815944Smckusic cgrp.cg_cs.cs_nifree--; 15825944Smckusic } 15835371Smckusic for (s = 0; s < MAXCPG; s++) { 15845371Smckusic cgrp.cg_btot[s] = 0; 15854236Smckusick for (i = 0; i < NRPOS; i++) 15864236Smckusick cgrp.cg_b[s][i] = 0; 15875371Smckusic } 15884236Smckusick if (c == 0) { 15895944Smckusic dmin += howmany(sblock.fs_cssize, sblock.fs_bsize) * 15905944Smckusic sblock.fs_frag; 15914236Smckusick } 15924236Smckusick for (d = 0; d < dmin; d++) 15934236Smckusick clrbit(cgrp.cg_free, d); 15945325Smckusic for (; (d + sblock.fs_frag) <= dmax - dbase; d += sblock.fs_frag) { 15954236Smckusick j = 0; 15965325Smckusic for (i = 0; i < sblock.fs_frag; i++) { 15974236Smckusick if (!getbmap(dbase+d+i)) { 15984236Smckusick setbit(cgrp.cg_free, d+i); 15994236Smckusick j++; 16004236Smckusick } else 16014236Smckusick clrbit(cgrp.cg_free, d+i); 16024236Smckusick } 16035325Smckusic if (j == sblock.fs_frag) { 16044789Smckusic cgrp.cg_cs.cs_nbfree++; 16055371Smckusic cgrp.cg_btot[cbtocylno(&sblock, d)]++; 16065363Smckusic cgrp.cg_b[cbtocylno(&sblock, d)] 16075363Smckusic [cbtorpos(&sblock, d)]++; 16084465Smckusic } else if (j > 0) { 16094789Smckusic cgrp.cg_cs.cs_nffree += j; 16104465Smckusic blk = ((cgrp.cg_free[d / NBBY] >> (d % NBBY)) & 16115325Smckusic (0xff >> (NBBY - sblock.fs_frag))); 16125325Smckusic fragacct(&sblock, blk, cgrp.cg_frsum, 1); 16134465Smckusic } 16144236Smckusick } 16154465Smckusic for (j = d; d < dmax - dbase; d++) { 16164236Smckusick if (!getbmap(dbase+d)) { 16174236Smckusick setbit(cgrp.cg_free, d); 16184789Smckusic cgrp.cg_cs.cs_nffree++; 16194236Smckusick } else 16204236Smckusick clrbit(cgrp.cg_free, d); 16214236Smckusick } 16224465Smckusic if (j != d) { 16234465Smckusic blk = ((cgrp.cg_free[j / NBBY] >> (j % NBBY)) & 16245325Smckusic (0xff >> (NBBY - sblock.fs_frag))); 16255325Smckusic fragacct(&sblock, blk, cgrp.cg_frsum, 1); 16264465Smckusic } 16275325Smckusic for (; d < MAXBPG(&sblock); d++) 16284236Smckusick clrbit(cgrp.cg_free, d); 16294789Smckusic sblock.fs_cstotal.cs_nffree += cgrp.cg_cs.cs_nffree; 16304789Smckusic sblock.fs_cstotal.cs_nbfree += cgrp.cg_cs.cs_nbfree; 16314789Smckusic sblock.fs_cstotal.cs_nifree += cgrp.cg_cs.cs_nifree; 16324789Smckusic sblock.fs_cstotal.cs_ndir += cgrp.cg_cs.cs_ndir; 16334789Smckusic *cs = cgrp.cg_cs; 16345381Smckusic bwrite(&dfile, &cgrp, fsbtodb(&sblock, cgtod(&sblock, c)), 16355956Smckusic sblock.fs_cgsize); 16364236Smckusick } 16375325Smckusic for (i = 0; i < howmany(sblock.fs_cssize, sblock.fs_bsize); i++) { 16385097Smckusic bwrite(&dfile, (char *)sblock.fs_csp[i], 16395325Smckusic fsbtodb(&sblock, sblock.fs_csaddr + (i * sblock.fs_frag)), 16405325Smckusic sblock.fs_bsize); 16415097Smckusic } 16424236Smckusick sblock.fs_ronly = 0; 16434236Smckusick sblock.fs_fmod = 0; 16444236Smckusick sbdirty(); 16454236Smckusick } 16464236Smckusick 16474465Smckusic /* 16484465Smckusic * update the frsum fields to reflect addition or deletion 16494465Smckusic * of some frags 16504465Smckusic */ 16515325Smckusic fragacct(fs, fragmap, fraglist, cnt) 16525325Smckusic struct fs *fs; 16534470Smckusic int fragmap; 16544789Smckusic long fraglist[]; 16554465Smckusic int cnt; 16564465Smckusic { 16574465Smckusic int inblk; 16584465Smckusic register int field, subfield; 16594465Smckusic register int siz, pos; 16604465Smckusic 16615325Smckusic inblk = (int)(fragtbl[fs->fs_frag][fragmap] << 1); 16624465Smckusic fragmap <<= 1; 16635325Smckusic for (siz = 1; siz < fs->fs_frag; siz++) { 16646290Smckusick if ((inblk & (1 << (siz + (fs->fs_frag % NBBY)))) == 0) 16654465Smckusic continue; 16664465Smckusic field = around[siz]; 16674465Smckusic subfield = inside[siz]; 16685325Smckusic for (pos = siz; pos <= fs->fs_frag; pos++) { 16694465Smckusic if ((fragmap & field) == subfield) { 16704465Smckusic fraglist[siz] += cnt; 16714465Smckusic pos += siz; 16724465Smckusic field <<= siz; 16734465Smckusic subfield <<= siz; 16744465Smckusic } 16754465Smckusic field <<= 1; 16764465Smckusic subfield <<= 1; 16774465Smckusic } 16784465Smckusic } 16794465Smckusic } 16804465Smckusic 16814236Smckusick findino(dirp) 16824236Smckusick register DIRECT *dirp; 16834236Smckusick { 16844236Smckusick if (dirp->d_ino == 0) 16854236Smckusick return (KEEPON); 16865877Smckusic if (!strcmp(dirp->d_name, srchname)) { 16875877Smckusic if (dirp->d_ino >= ROOTINO && dirp->d_ino <= imax) 16885877Smckusic parentdir = dirp->d_ino; 16895877Smckusic return (STOP); 16904236Smckusick } 16914236Smckusick return (KEEPON); 16924236Smckusick } 16934236Smckusick 16944236Smckusick mkentry(dirp) 16954236Smckusick register DIRECT *dirp; 16964236Smckusick { 16974236Smckusick register ino_t in; 16984236Smckusick register char *p; 16996251Smckusick DIRECT newent; 17006251Smckusick int newlen, oldlen; 17014236Smckusick 17026251Smckusick newent.d_namlen = 11; 17036251Smckusick newlen = DIRSIZ(&newent); 17046251Smckusick if (dirp->d_ino != 0) 17056251Smckusick oldlen = DIRSIZ(dirp); 17066251Smckusick else 17076251Smckusick oldlen = 0; 17086251Smckusick if (dirp->d_reclen - oldlen < newlen) 17094236Smckusick return (KEEPON); 17106251Smckusick newent.d_reclen = dirp->d_reclen - oldlen; 17116251Smckusick dirp->d_reclen = oldlen; 17126251Smckusick dirp = (struct direct *)(((char *)dirp) + oldlen); 17134236Smckusick dirp->d_ino = orphan; 17146251Smckusick dirp->d_reclen = newent.d_reclen; 17156251Smckusick p = &dirp->d_name[2]; 17166251Smckusick for (in = imax; in > 0; in /= 10) 17176251Smckusick p++; 17186251Smckusick *--p = 0; 17196251Smckusick dirp->d_namlen = p - dirp->d_name; 17204236Smckusick in = orphan; 17214236Smckusick while (p > dirp->d_name) { 17224236Smckusick *--p = (in % 10) + '0'; 17234236Smckusick in /= 10; 17244236Smckusick } 17254236Smckusick *p = '#'; 17264236Smckusick return (ALTERD|STOP); 17274236Smckusick } 17284236Smckusick 17294236Smckusick chgdd(dirp) 17304236Smckusick register DIRECT *dirp; 17314236Smckusick { 17324236Smckusick if (dirp->d_name[0] == '.' && dirp->d_name[1] == '.' && 17334236Smckusick dirp->d_name[2] == 0) { 17344236Smckusick dirp->d_ino = lfdir; 17354236Smckusick return (ALTERD|STOP); 17364236Smckusick } 17374236Smckusick return (KEEPON); 17384236Smckusick } 17394236Smckusick 17404236Smckusick linkup() 17414236Smckusick { 17424236Smckusick register DINODE *dp; 17434236Smckusick register lostdir; 17444236Smckusick register ino_t pdir; 17454236Smckusick 17464236Smckusick if ((dp = ginode()) == NULL) 17474236Smckusick return (0); 17485877Smckusic lostdir = DIRCT; 17494236Smckusick pdir = parentdir; 17504236Smckusick pwarn("UNREF %s ", lostdir ? "DIR" : "FILE"); 17514236Smckusick pinode(); 17524236Smckusick if (preen && dp->di_size == 0) 17534236Smckusick return (0); 17544236Smckusick if (preen) 17554236Smckusick printf(" (RECONNECTED)\n"); 17564236Smckusick else 17574236Smckusick if (reply("RECONNECT") == 0) 17584236Smckusick return (0); 17594236Smckusick orphan = inum; 17604236Smckusick if (lfdir == 0) { 17614236Smckusick inum = ROOTINO; 17624236Smckusick if ((dp = ginode()) == NULL) { 17634236Smckusick inum = orphan; 17644236Smckusick return (0); 17654236Smckusick } 17664236Smckusick pfunc = findino; 17674236Smckusick srchname = lfname; 17684236Smckusick filsize = dp->di_size; 17694236Smckusick parentdir = 0; 17704236Smckusick ckinode(dp, DATA); 17714236Smckusick inum = orphan; 17724236Smckusick if ((lfdir = parentdir) == 0) { 17734236Smckusick pfatal("SORRY. NO lost+found DIRECTORY"); 17744236Smckusick printf("\n\n"); 17754236Smckusick return (0); 17764236Smckusick } 17774236Smckusick } 17784236Smckusick inum = lfdir; 17795877Smckusic if ((dp = ginode()) == NULL || !DIRCT || getstate() != FSTATE) { 17804236Smckusick inum = orphan; 17814236Smckusick pfatal("SORRY. NO lost+found DIRECTORY"); 17824236Smckusick printf("\n\n"); 17834236Smckusick return (0); 17844236Smckusick } 17855956Smckusic if (fragoff(&sblock, dp->di_size)) { 17865956Smckusic dp->di_size = fragroundup(&sblock, dp->di_size); 17874236Smckusick inodirty(); 17884236Smckusick } 17894236Smckusick filsize = dp->di_size; 17904236Smckusick inum = orphan; 17914236Smckusick pfunc = mkentry; 17924236Smckusick if ((ckinode(dp, DATA) & ALTERD) == 0) { 17934236Smckusick pfatal("SORRY. NO SPACE IN lost+found DIRECTORY"); 17944236Smckusick printf("\n\n"); 17954236Smckusick return (0); 17964236Smckusick } 17974236Smckusick declncnt(); 17984236Smckusick if (lostdir) { 17994236Smckusick pfunc = chgdd; 18004236Smckusick dp = ginode(); 18014236Smckusick filsize = dp->di_size; 18024236Smckusick ckinode(dp, DATA); 18034236Smckusick inum = lfdir; 18044236Smckusick if ((dp = ginode()) != NULL) { 18054236Smckusick dp->di_nlink++; 18064236Smckusick inodirty(); 18074236Smckusick setlncnt(getlncnt()+1); 18084236Smckusick } 18094236Smckusick inum = orphan; 18104236Smckusick pwarn("DIR I=%u CONNECTED. ", orphan); 18114236Smckusick printf("PARENT WAS I=%u\n", pdir); 18124236Smckusick if (preen == 0) 18134236Smckusick printf("\n"); 18144236Smckusick } 18154236Smckusick return (1); 18164236Smckusick } 18174236Smckusick 18184236Smckusick bread(fcp, buf, blk, size) 18194236Smckusick daddr_t blk; 18204236Smckusick register struct filecntl *fcp; 18214236Smckusick register size; 18224236Smckusick char *buf; 18234236Smckusick { 18245325Smckusic if (lseek(fcp->rfdes, blk * DEV_BSIZE, 0) < 0) 18254236Smckusick rwerr("SEEK", blk); 18264236Smckusick else if (read(fcp->rfdes, buf, size) == size) 18274236Smckusick return (1); 18284236Smckusick rwerr("READ", blk); 18294236Smckusick return (0); 18304236Smckusick } 18314236Smckusick 18324236Smckusick bwrite(fcp, buf, blk, size) 18334236Smckusick daddr_t blk; 18344236Smckusick register struct filecntl *fcp; 18354236Smckusick register size; 18364236Smckusick char *buf; 18374236Smckusick { 18384236Smckusick 18394236Smckusick if (fcp->wfdes < 0) 18404236Smckusick return (0); 18415325Smckusic if (lseek(fcp->wfdes, blk * DEV_BSIZE, 0) < 0) 18424236Smckusick rwerr("SEEK", blk); 18434236Smckusick else if (write(fcp->wfdes, buf, size) == size) { 18444236Smckusick fcp->mod = 1; 18454236Smckusick return (1); 18464236Smckusick } 18474236Smckusick rwerr("WRITE", blk); 18484236Smckusick return (0); 18494236Smckusick } 18504236Smckusick 18514236Smckusick catch() 18524236Smckusick { 18534236Smckusick 18544236Smckusick ckfini(); 18554236Smckusick exit(12); 18564236Smckusick } 18575325Smckusic 18585325Smckusic /* 18595325Smckusic * block operations 18605325Smckusic */ 18615325Smckusic 18625325Smckusic isblock(fs, cp, h) 18635325Smckusic struct fs *fs; 18645325Smckusic unsigned char *cp; 18655325Smckusic int h; 18665325Smckusic { 18675325Smckusic unsigned char mask; 18685325Smckusic 18695325Smckusic switch (fs->fs_frag) { 18705325Smckusic case 8: 18715325Smckusic return (cp[h] == 0xff); 18725325Smckusic case 4: 18735325Smckusic mask = 0x0f << ((h & 0x1) << 2); 18745325Smckusic return ((cp[h >> 1] & mask) == mask); 18755325Smckusic case 2: 18765325Smckusic mask = 0x03 << ((h & 0x3) << 1); 18775325Smckusic return ((cp[h >> 2] & mask) == mask); 18785325Smckusic case 1: 18795325Smckusic mask = 0x01 << (h & 0x7); 18805325Smckusic return ((cp[h >> 3] & mask) == mask); 18815325Smckusic default: 18825381Smckusic error("isblock bad fs_frag %d\n", fs->fs_frag); 18835381Smckusic return (0); 18845325Smckusic } 18855325Smckusic } 18866489Smckusick 18876489Smckusick /* tables.c 4.1 82/03/25 */ 18886489Smckusick 18896489Smckusick /* merged into kernel: tables.c 2.1 3/25/82 */ 18906489Smckusick 18916489Smckusick /* last monet version: partab.c 4.2 81/03/08 */ 18926489Smckusick 18936489Smckusick /* 18946489Smckusick * bit patterns for identifying fragments in the block map 18956489Smckusick * used as ((map & around) == inside) 18966489Smckusick */ 18976489Smckusick int around[9] = { 18986489Smckusick 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff 18996489Smckusick }; 19006489Smckusick int inside[9] = { 19016489Smckusick 0x0, 0x2, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe 19026489Smckusick }; 19036489Smckusick 19046489Smckusick /* 19056489Smckusick * given a block map bit pattern, the frag tables tell whether a 19066489Smckusick * particular size fragment is available. 19076489Smckusick * 19086489Smckusick * used as: 19096489Smckusick * if ((1 << (size - 1)) & fragtbl[fs->fs_frag][map] { 19106489Smckusick * at least one fragment of the indicated size is available 19116489Smckusick * } 19126489Smckusick * 19136489Smckusick * These tables are used by the scanc instruction on the VAX to 19146489Smckusick * quickly find an appropriate fragment. 19156489Smckusick */ 19166489Smckusick 19176489Smckusick unsigned char fragtbl124[256] = { 19186489Smckusick 0x00, 0x16, 0x16, 0x2a, 0x16, 0x16, 0x26, 0x4e, 19196489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x2a, 0x3e, 0x4e, 0x8a, 19206489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 19216489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 19226489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 19236489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 19246489Smckusick 0x2a, 0x3e, 0x3e, 0x2a, 0x3e, 0x3e, 0x2e, 0x6e, 19256489Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x2a, 0x3e, 0x6e, 0xaa, 19266489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 19276489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 19286489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 19296489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 19306489Smckusick 0x26, 0x36, 0x36, 0x2e, 0x36, 0x36, 0x26, 0x6e, 19316489Smckusick 0x36, 0x36, 0x36, 0x3e, 0x2e, 0x3e, 0x6e, 0xae, 19326489Smckusick 0x4e, 0x5e, 0x5e, 0x6e, 0x5e, 0x5e, 0x6e, 0x4e, 19336489Smckusick 0x5e, 0x5e, 0x5e, 0x7e, 0x6e, 0x7e, 0x4e, 0xce, 19346489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 19356489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 19366489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 19376489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 19386489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 19396489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 19406489Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 19416489Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 0xbe, 19426489Smckusick 0x2a, 0x3e, 0x3e, 0x2a, 0x3e, 0x3e, 0x2e, 0x6e, 19436489Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x2a, 0x3e, 0x6e, 0xaa, 19446489Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 19456489Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 0xbe, 19466489Smckusick 0x4e, 0x5e, 0x5e, 0x6e, 0x5e, 0x5e, 0x6e, 0x4e, 19476489Smckusick 0x5e, 0x5e, 0x5e, 0x7e, 0x6e, 0x7e, 0x4e, 0xce, 19486489Smckusick 0x8a, 0x9e, 0x9e, 0xaa, 0x9e, 0x9e, 0xae, 0xce, 19496489Smckusick 0x9e, 0x9e, 0x9e, 0xbe, 0xaa, 0xbe, 0xce, 0x8a, 19506489Smckusick }; 19516489Smckusick 19526489Smckusick unsigned char fragtbl8[256] = { 19536489Smckusick 0x00, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x04, 19546489Smckusick 0x01, 0x01, 0x01, 0x03, 0x02, 0x03, 0x04, 0x08, 19556489Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 19566489Smckusick 0x02, 0x03, 0x03, 0x02, 0x04, 0x05, 0x08, 0x10, 19576489Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 19586489Smckusick 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 19596489Smckusick 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, 19606489Smckusick 0x04, 0x05, 0x05, 0x06, 0x08, 0x09, 0x10, 0x20, 19616489Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 19626489Smckusick 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 19636489Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 19646489Smckusick 0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11, 19656489Smckusick 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, 19666489Smckusick 0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0a, 19676489Smckusick 0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04, 19686489Smckusick 0x08, 0x09, 0x09, 0x0a, 0x10, 0x11, 0x20, 0x40, 19696489Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 19706489Smckusick 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 19716489Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 19726489Smckusick 0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11, 19736489Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 19746489Smckusick 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 19756489Smckusick 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07, 19766489Smckusick 0x05, 0x05, 0x05, 0x07, 0x09, 0x09, 0x11, 0x21, 19776489Smckusick 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, 19786489Smckusick 0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0a, 19796489Smckusick 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07, 19806489Smckusick 0x02, 0x03, 0x03, 0x02, 0x06, 0x07, 0x0a, 0x12, 19816489Smckusick 0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04, 19826489Smckusick 0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x04, 0x0c, 19836489Smckusick 0x08, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x0a, 0x0c, 19846489Smckusick 0x10, 0x11, 0x11, 0x12, 0x20, 0x21, 0x40, 0x80, 19856489Smckusick }; 19866489Smckusick 19876489Smckusick /* 19886489Smckusick * the actual fragtbl array 19896489Smckusick */ 19906489Smckusick unsigned char *fragtbl[MAXFRAG + 1] = { 19916489Smckusick 0, fragtbl124, fragtbl124, 0, fragtbl124, 0, 0, 0, fragtbl8, 19926489Smckusick }; 1993