1*6547Smckusick static char *sccsid = "@(#)main.c 2.4 (Berkeley) 04/15/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; 1396491Smckusick 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; 3836533Smckusick n_blks += howmany(sblock.fs_cssize, sblock.fs_fsize); 3844236Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 3855381Smckusic if (getblk(&cgblk, cgtod(&sblock, c), sblock.fs_cgsize) == 0) 3864236Smckusick continue; 3876533Smckusick if (debug && cgrp.cg_magic != CG_MAGIC) 3886533Smckusick printf("cg %d: bad magic number\n", c); 3894236Smckusick n = 0; 3904465Smckusic for (i = 0; i < sblock.fs_ipg; i++, inum++) { 3914465Smckusic dp = ginode(); 3924465Smckusic if (dp == NULL) 3934465Smckusic continue; 3945944Smckusic n++; 3954236Smckusick if (ALLOC) { 3964236Smckusick if (!isset(cgrp.cg_iused, i)) { 3975381Smckusic if (debug) 3985381Smckusic printf("%d bad, not used\n", 3995381Smckusic inum); 4004236Smckusick inosumbad++; 4014236Smckusick } 4025944Smckusic n--; 4034236Smckusick lastino = inum; 4044236Smckusick if (ftypeok(dp) == 0) { 4054236Smckusick pfatal("UNKNOWN FILE TYPE I=%u", inum); 4064236Smckusick if (reply("CLEAR") == 1) { 4074236Smckusick zapino(dp); 4084236Smckusick inodirty(); 4094236Smckusick inosumbad++; 4104236Smckusick } 4114236Smckusick continue; 4124236Smckusick } 4134236Smckusick n_files++; 4144236Smckusick if (setlncnt(dp->di_nlink) <= 0) { 4154236Smckusick if (badlnp < &badlncnt[MAXLNCNT]) 4164236Smckusick *badlnp++ = inum; 4174236Smckusick else { 4184236Smckusick pfatal("LINK COUNT TABLE OVERFLOW"); 4194236Smckusick if (reply("CONTINUE") == 0) 4204236Smckusick errexit(""); 4214236Smckusick } 4224236Smckusick } 4235877Smckusic setstate(DIRCT ? DSTATE : FSTATE); 4244236Smckusick badblk = dupblk = 0; filsize = 0; maxblk = 0; 4254236Smckusick ckinode(dp, ADDR); 4264236Smckusick } else { 4274236Smckusick if (isset(cgrp.cg_iused, i)) { 4285381Smckusic if (debug) 4295381Smckusic printf("%d bad, marked used\n", 4305381Smckusic inum); 4314236Smckusick inosumbad++; 4324465Smckusic n--; 4334236Smckusick } 4344236Smckusick if (dp->di_mode != 0) { 4354236Smckusick pfatal("PARTIALLY ALLOCATED INODE I=%u", inum); 4364236Smckusick if (reply("CLEAR") == 1) { 4374236Smckusick zapino(dp); 4384236Smckusick inodirty(); 4394236Smckusick inosumbad++; 4404236Smckusick } 4414236Smckusick } 4424236Smckusick } 4434236Smckusick } 4444789Smckusic if (n != cgrp.cg_cs.cs_nifree) { 4455381Smckusic if (debug) 4465944Smckusic printf("cg[%d].cg_cs.cs_nifree is %d; calc %d\n", 4475381Smckusic c, cgrp.cg_cs.cs_nifree, n); 4484236Smckusick inosumbad++; 4494236Smckusick } 4506491Smckusick if (cgrp.cg_cs.cs_nbfree != sblock.fs_cs(&sblock, c).cs_nbfree 4516491Smckusick || cgrp.cg_cs.cs_nffree != sblock.fs_cs(&sblock, c).cs_nffree 4526491Smckusick || cgrp.cg_cs.cs_nifree != sblock.fs_cs(&sblock, c).cs_nifree 4536491Smckusick || cgrp.cg_cs.cs_ndir != sblock.fs_cs(&sblock, c).cs_ndir) 4546491Smckusick sbsumbad++; 4554236Smckusick } 4564236Smckusick /* 1b */ 4574236Smckusick if (enddup != &duplist[0]) { 4584236Smckusick if (preen) 4594236Smckusick pfatal("INTERNAL ERROR: dups with -p"); 4604236Smckusick printf("** Phase 1b - Rescan For More DUPS\n"); 4614236Smckusick pfunc = pass1b; 4624236Smckusick inum = 0; 4634236Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 4644465Smckusic for (i = 0; i < sblock.fs_ipg; i++, inum++) { 4654465Smckusic dp = ginode(); 4664465Smckusic if (dp == NULL) 4674465Smckusic continue; 4684236Smckusick if (getstate() != USTATE && 4694236Smckusick (ckinode(dp, ADDR) & STOP)) 4704236Smckusick goto out1b; 4714465Smckusic } 4724236Smckusick } 4734236Smckusick } 4744236Smckusick out1b: 4754465Smckusic flush(&dfile, &inoblk); 4764236Smckusick /* 2 */ 4774236Smckusick if (preen == 0) 4784236Smckusick printf("** Phase 2 - Check Pathnames\n"); 4794236Smckusick inum = ROOTINO; 4804236Smckusick thisname = pathp = pathname; 4814236Smckusick pfunc = pass2; 4824236Smckusick switch (getstate()) { 4834236Smckusick 4844236Smckusick case USTATE: 4854236Smckusick errexit("ROOT INODE UNALLOCATED. TERMINATING.\n"); 4864236Smckusick 4874236Smckusick case FSTATE: 4884236Smckusick pfatal("ROOT INODE NOT DIRECTORY"); 4894236Smckusick if (reply("FIX") == 0 || (dp = ginode()) == NULL) 4904236Smckusick errexit(""); 4914236Smckusick dp->di_mode &= ~IFMT; 4924236Smckusick dp->di_mode |= IFDIR; 4934236Smckusick inodirty(); 4944236Smckusick inosumbad++; 4954236Smckusick setstate(DSTATE); 4964236Smckusick /* fall into ... */ 4974236Smckusick 4984236Smckusick case DSTATE: 4994236Smckusick descend(); 5004236Smckusick break; 5014236Smckusick 5024236Smckusick case CLEAR: 5034236Smckusick pfatal("DUPS/BAD IN ROOT INODE"); 5044236Smckusick printf("\n"); 5054236Smckusick if (reply("CONTINUE") == 0) 5064236Smckusick errexit(""); 5074236Smckusick setstate(DSTATE); 5084236Smckusick descend(); 5094236Smckusick } 5104236Smckusick /* 3 */ 5114236Smckusick if (preen == 0) 5124236Smckusick printf("** Phase 3 - Check Connectivity\n"); 5134236Smckusick for (inum = ROOTINO; inum <= lastino; inum++) { 5144236Smckusick if (getstate() == DSTATE) { 5154236Smckusick pfunc = findino; 5164236Smckusick srchname = ".."; 5174236Smckusick savino = inum; 5184236Smckusick do { 5194236Smckusick orphan = inum; 5204236Smckusick if ((dp = ginode()) == NULL) 5214236Smckusick break; 5224236Smckusick filsize = dp->di_size; 5234236Smckusick parentdir = 0; 5244236Smckusick ckinode(dp, DATA); 5254236Smckusick if ((inum = parentdir) == 0) 5264236Smckusick break; 5274236Smckusick } while (getstate() == DSTATE); 5284236Smckusick inum = orphan; 5294236Smckusick if (linkup() == 1) { 5304236Smckusick thisname = pathp = pathname; 5314236Smckusick *pathp++ = '?'; 5324236Smckusick pfunc = pass2; 5334236Smckusick descend(); 5344236Smckusick } 5354236Smckusick inum = savino; 5364236Smckusick } 5374236Smckusick } 5384236Smckusick /* 4 */ 5394236Smckusick if (preen == 0) 5404236Smckusick printf("** Phase 4 - Check Reference Counts\n"); 5414236Smckusick pfunc = pass4; 5424236Smckusick for (inum = ROOTINO; inum <= lastino; inum++) { 5434236Smckusick switch (getstate()) { 5444236Smckusick 5454236Smckusick case FSTATE: 5464236Smckusick if (n = getlncnt()) 5474236Smckusick adjust((short)n); 5484236Smckusick else { 5494236Smckusick for (blp = badlncnt;blp < badlnp; blp++) 5504236Smckusick if (*blp == inum) { 5514236Smckusick clri("UNREF", 1); 5524236Smckusick break; 5534236Smckusick } 5544236Smckusick } 5554236Smckusick break; 5564236Smckusick 5574236Smckusick case DSTATE: 5584236Smckusick clri("UNREF", 1); 5594236Smckusick break; 5604236Smckusick 5614236Smckusick case CLEAR: 5624236Smckusick clri("BAD/DUP", 1); 5634236Smckusick break; 5644236Smckusick } 5654236Smckusick } 5665337Smckusic if (imax - ROOTINO - n_files != sblock.fs_cstotal.cs_nifree) { 5674236Smckusick pwarn("FREE INODE COUNT WRONG IN SUPERBLK"); 5684236Smckusick if (preen) 5694236Smckusick printf(" (FIXED)\n"); 5704236Smckusick if (preen || reply("FIX") == 1) { 5715944Smckusic sblock.fs_cstotal.cs_nifree = imax - ROOTINO - n_files; 5724236Smckusick sbdirty(); 5734236Smckusick } 5744236Smckusick } 5754236Smckusick flush(&dfile, &fileblk); 5764236Smckusick 5774236Smckusick /* 5 */ 5784236Smckusick if (preen == 0) 5794236Smckusick printf("** Phase 5 - Check Cyl groups\n"); 5806314Smckusick copy(blockmap, freemap, (unsigned)bmapsz); 5814236Smckusick dupblk = 0; 5825381Smckusic n_index = sblock.fs_ncg * (cgdmin(&sblock, 0) - cgtod(&sblock, 0)); 5834236Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 5845381Smckusic daddr_t cbase = cgbase(&sblock, c); 5854236Smckusick short bo[MAXCPG][NRPOS]; 5865371Smckusic long botot[MAXCPG]; 5875325Smckusic long frsum[MAXFRAG]; 5884465Smckusic int blk; 5894465Smckusic 5905371Smckusic for (n = 0; n < sblock.fs_cpg; n++) { 5915371Smckusic botot[n] = 0; 5924236Smckusick for (i = 0; i < NRPOS; i++) 5934236Smckusick bo[n][i] = 0; 5945371Smckusic } 5955325Smckusic for (i = 0; i < sblock.fs_frag; i++) { 5964465Smckusic frsum[i] = 0; 5974465Smckusic } 5984465Smckusic /* 5996533Smckusick * need to account for the super blocks 6004465Smckusic * which appear (inaccurately) bad 6014465Smckusic */ 6026533Smckusick n_bad += cgtod(&sblock, c) - cgsblock(&sblock, c); 6035381Smckusic if (getblk(&cgblk, cgtod(&sblock, c), sblock.fs_cgsize) == 0) 6044236Smckusick continue; 6056533Smckusick if (debug && cgrp.cg_magic != CG_MAGIC) 6066533Smckusick printf("cg %d: bad magic number\n", c); 6075325Smckusic for (b = 0; b < sblock.fs_fpg; b += sblock.fs_frag) { 6085325Smckusic if (isblock(&sblock, cgrp.cg_free, b/sblock.fs_frag)) { 6095325Smckusic if (pass5(cbase+b, sblock.fs_frag) == STOP) 6104236Smckusick goto out5; 6114236Smckusick /* this is clumsy ... */ 6125325Smckusic n_ffree -= sblock.fs_frag; 6134236Smckusick n_bfree++; 6145371Smckusic botot[cbtocylno(&sblock, b)]++; 6155363Smckusic bo[cbtocylno(&sblock, b)] 6165363Smckusic [cbtorpos(&sblock, b)]++; 6174465Smckusic } else { 6185325Smckusic for (d = 0; d < sblock.fs_frag; d++) 6194236Smckusick if (isset(cgrp.cg_free, b+d)) 6204236Smckusick if (pass5(cbase+b+d,1) == STOP) 6214236Smckusick goto out5; 6224465Smckusic blk = ((cgrp.cg_free[b / NBBY] >> (b % NBBY)) & 6235325Smckusic (0xff >> (NBBY - sblock.fs_frag))); 6244465Smckusic if (blk != 0) 6255325Smckusic fragacct(&sblock, blk, frsum, 1); 6264465Smckusic } 6274236Smckusick } 6285325Smckusic for (i = 0; i < sblock.fs_frag; i++) { 6294465Smckusic if (cgrp.cg_frsum[i] != frsum[i]) { 6305381Smckusic if (debug) 6315381Smckusic printf("cg[%d].cg_frsum[%d] have %d calc %d\n", 6325381Smckusic c, i, cgrp.cg_frsum[i], frsum[i]); 6334465Smckusic frsumbad++; 6344465Smckusic } 6354465Smckusic } 6365371Smckusic for (n = 0; n < sblock.fs_cpg; n++) { 6375371Smckusic if (botot[n] != cgrp.cg_btot[n]) { 6385381Smckusic if (debug) 6395381Smckusic printf("cg[%d].cg_btot[%d] have %d calc %d\n", 6405381Smckusic c, n, cgrp.cg_btot[n], botot[n]); 6415371Smckusic offsumbad++; 6425371Smckusic } 6434236Smckusick for (i = 0; i < NRPOS; i++) 6444236Smckusick if (bo[n][i] != cgrp.cg_b[n][i]) { 6455381Smckusic if (debug) 6465381Smckusic printf("cg[%d].cg_b[%d][%d] have %d calc %d\n", 6475381Smckusic c, n, i, cgrp.cg_b[n][i], 6485381Smckusic bo[n][i]); 6494236Smckusick offsumbad++; 6504236Smckusick } 6515371Smckusic } 6524236Smckusick } 6534236Smckusick out5: 6544236Smckusick if (dupblk) 6554236Smckusick pwarn("%d DUP BLKS IN BIT MAPS\n", dupblk); 6564236Smckusick if (fixcg == 0) { 6575325Smckusic if ((b = n_blks+n_ffree+sblock.fs_frag*n_bfree+n_index+n_bad) != fmax) { 6584236Smckusick pwarn("%ld BLK(S) MISSING\n", fmax - b); 6594236Smckusick fixcg = 1; 6606491Smckusick } else if (inosumbad + offsumbad + frsumbad + sbsumbad) { 6616491Smckusick pwarn("SUMMARY INFORMATION %s%s%s%sBAD\n", 6624236Smckusick inosumbad ? "(INODE FREE) " : "", 6634465Smckusic offsumbad ? "(BLOCK OFFSETS) " : "", 6646491Smckusick frsumbad ? "(FRAG SUMMARIES) " : "", 6656491Smckusick sbsumbad ? "(SUPER BLOCK SUMMARIES) " : ""); 6664236Smckusick fixcg = 1; 6674789Smckusic } else if (n_ffree != sblock.fs_cstotal.cs_nffree || 6684789Smckusic n_bfree != sblock.fs_cstotal.cs_nbfree) { 6694236Smckusick pwarn("FREE BLK COUNT(S) WRONG IN SUPERBLK"); 6704236Smckusick if (preen) 6714236Smckusick printf(" (FIXED)\n"); 6724236Smckusick if (preen || reply("FIX") == 1) { 6734789Smckusic sblock.fs_cstotal.cs_nffree = n_ffree; 6744789Smckusic sblock.fs_cstotal.cs_nbfree = n_bfree; 6754236Smckusick sbdirty(); 6764236Smckusick } 6774236Smckusick } 6784236Smckusick } 6794236Smckusick if (fixcg) { 6804236Smckusick pwarn("BAD CYLINDER GROUPS"); 6814236Smckusick if (preen) 6824236Smckusick printf(" (SALVAGED)\n"); 6834236Smckusick else if (reply("SALVAGE") == 0) 6844236Smckusick fixcg = 0; 6854236Smckusick } 6864236Smckusick 6874236Smckusick if (fixcg) { 6884236Smckusick if (preen == 0) 6894236Smckusick printf("** Phase 6 - Salvage Cylinder Groups\n"); 6904236Smckusick makecg(); 6914789Smckusic n_ffree = sblock.fs_cstotal.cs_nffree; 6924789Smckusic n_bfree = sblock.fs_cstotal.cs_nbfree; 6934236Smckusick } 6944236Smckusick 6954236Smckusick pwarn("%d files, %d used, %d free (%d frags, %d blocks)\n", 6966533Smckusick n_files, n_blks - howmany(sblock.fs_cssize, sblock.fs_fsize), 6975325Smckusic n_ffree + sblock.fs_frag * n_bfree, n_ffree, n_bfree); 6984236Smckusick if (dfile.mod) { 6994236Smckusick time(&sblock.fs_time); 7004236Smckusick sbdirty(); 7014236Smckusick } 7024236Smckusick ckfini(); 7034236Smckusick sync(); 7044236Smckusick if (dfile.mod && hotroot) { 7054236Smckusick printf("\n***** BOOT UNIX (NO SYNC!) *****\n"); 7064236Smckusick exit(4); 7074236Smckusick } 7084236Smckusick if (dfile.mod && preen == 0) 7094236Smckusick printf("\n***** FILE SYSTEM WAS MODIFIED *****\n"); 7106314Smckusick free(blockmap); 7114236Smckusick free(freemap); 7124236Smckusick free(statemap); 7134236Smckusick free(lncntp); 7144236Smckusick } 7154236Smckusick 7164236Smckusick /* VARARGS1 */ 7174236Smckusick error(s1, s2, s3, s4) 7184715Smckusic char *s1; 7194236Smckusick { 7204236Smckusick 7214236Smckusick printf(s1, s2, s3, s4); 7224236Smckusick } 7234236Smckusick 7244236Smckusick /* VARARGS1 */ 7254236Smckusick errexit(s1, s2, s3, s4) 7264715Smckusic char *s1; 7274236Smckusick { 7284236Smckusick error(s1, s2, s3, s4); 7294236Smckusick exit(8); 7304236Smckusick } 7314236Smckusick 7324236Smckusick /* 7334236Smckusick * An inconsistency occured which shouldn't during normal operations. 7344236Smckusick * Die if preening, otw just printf. 7354236Smckusick */ 7364236Smckusick /* VARARGS1 */ 7374236Smckusick pfatal(s, a1, a2, a3) 7384236Smckusick char *s; 7394236Smckusick { 7404236Smckusick 7414236Smckusick if (preen) { 7424236Smckusick printf("%s: ", devname); 7434236Smckusick printf(s, a1, a2, a3); 7444236Smckusick printf("\n"); 7454236Smckusick preendie(); 7464236Smckusick } 7474236Smckusick printf(s, a1, a2, a3); 7484236Smckusick } 7494236Smckusick 7504236Smckusick preendie() 7514236Smckusick { 7524236Smckusick 7534236Smckusick printf("%s: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n", devname); 7544236Smckusick exit(8); 7554236Smckusick } 7564236Smckusick 7574236Smckusick /* 7584236Smckusick * Pwarn is like printf when not preening, 7594236Smckusick * or a warning (preceded by filename) when preening. 7604236Smckusick */ 7614236Smckusick /* VARARGS1 */ 7624236Smckusick pwarn(s, a1, a2, a3, a4, a5) 7634236Smckusick char *s; 7644236Smckusick { 7654236Smckusick 7664236Smckusick if (preen) 7674236Smckusick printf("%s: ", devname); 7684236Smckusick printf(s, a1, a2, a3, a4, a5); 7694236Smckusick } 7704236Smckusick 7714236Smckusick ckinode(dp, flg) 7724236Smckusick DINODE *dp; 7734236Smckusick register flg; 7744236Smckusick { 7754236Smckusick register daddr_t *ap; 7764236Smckusick register ret; 7775956Smckusic int (*func)(), n, ndb, size, offset; 7784236Smckusick 7794236Smckusick if (SPECIAL) 7804236Smckusick return (KEEPON); 7814236Smckusick func = (flg == ADDR) ? pfunc : dirscan; 7825325Smckusic ndb = howmany(dp->di_size, sblock.fs_bsize); 7834428Smckusic for (ap = &dp->di_db[0]; ap < &dp->di_db[NDADDR]; ap++) { 7845956Smckusic if (--ndb == 0 && (offset = blkoff(&sblock, dp->di_size)) != 0) 7855956Smckusic size = numfrags(&sblock, fragroundup(&sblock, offset)); 7864236Smckusick else 7875325Smckusic size = sblock.fs_frag; 7884236Smckusick if (*ap && (ret = (*func)(*ap, size)) & STOP) 7894236Smckusick return (ret); 7904236Smckusick } 7914428Smckusic for (ap = &dp->di_ib[0], n = 1; n <= 2; ap++, n++) { 7925325Smckusic if (*ap && (ret = iblock(*ap, n, flg, dp->di_size - sblock.fs_bsize * NDADDR)) & STOP) 7934236Smckusick return (ret); 7944236Smckusick } 7954236Smckusick return (KEEPON); 7964236Smckusick } 7974236Smckusick 7984236Smckusick iblock(blk, ilevel, flg, isize) 7994236Smckusick daddr_t blk; 8004236Smckusick register ilevel; 8014236Smckusick int isize; 8024236Smckusick { 8034236Smckusick register daddr_t *ap; 8044236Smckusick register daddr_t *aplim; 8054428Smckusic register int i, n; 8064236Smckusick int (*func)(), nif; 8074236Smckusick BUFAREA ib; 8084236Smckusick 8094236Smckusick if (flg == ADDR) { 8104236Smckusick func = pfunc; 8115325Smckusic if (((n = (*func)(blk, sblock.fs_frag)) & KEEPON) == 0) 8124236Smckusick return (n); 8134236Smckusick } else 8144236Smckusick func = dirscan; 8154236Smckusick if (outrange(blk)) /* protect thyself */ 8164236Smckusick return (SKIP); 8174236Smckusick initbarea(&ib); 8185325Smckusic if (getblk(&ib, blk, sblock.fs_bsize) == NULL) 8194236Smckusick return (SKIP); 8204236Smckusick ilevel--; 8214428Smckusic if (ilevel == 0) { 8225956Smckusic nif = lblkno(&sblock, isize) + 1; 8234428Smckusic } else /* ilevel == 1 */ { 8245325Smckusic nif = isize / (sblock.fs_bsize * NINDIR(&sblock)) + 1; 8254428Smckusic } 8265325Smckusic if (nif > NINDIR(&sblock)) 8275325Smckusic nif = NINDIR(&sblock); 8284428Smckusic aplim = & ib.b_un.b_indir[nif]; 8294428Smckusic for (ap = ib.b_un.b_indir, i = 1; ap < aplim; ap++, i++) 8304236Smckusick if (*ap) { 8314236Smckusick if (ilevel > 0) 8325325Smckusic n = iblock(*ap, ilevel, flg, isize - i * NINDIR(&sblock) * sblock.fs_bsize); 8334236Smckusick else 8345325Smckusic n = (*func)(*ap, sblock.fs_frag); 8354236Smckusick if (n & STOP) 8364236Smckusick return (n); 8374236Smckusick } 8384236Smckusick return (KEEPON); 8394236Smckusick } 8404236Smckusick 8414236Smckusick pass1(blk, size) 8424236Smckusick daddr_t blk; 8434236Smckusick int size; 8444236Smckusick { 8454236Smckusick register daddr_t *dlp; 8464236Smckusick int res = KEEPON; 8474236Smckusick 8484236Smckusick for (; size > 0; blk++, size--) { 8494236Smckusick if (outrange(blk)) { 8504236Smckusick blkerr("BAD", blk); 8514236Smckusick if (++badblk >= MAXBAD) { 8524236Smckusick printf("EXCESSIVE BAD BLKS I=%u", inum); 8534236Smckusick if (reply("CONTINUE") == 0) 8544236Smckusick errexit(""); 8554236Smckusick return (STOP); 8564236Smckusick } 8574236Smckusick res = SKIP; 8584236Smckusick } else if (getbmap(blk)) { 8594236Smckusick blkerr("DUP", blk); 8604236Smckusick if (++dupblk >= MAXDUP) { 8614236Smckusick printf("EXCESSIVE DUP BLKS I=%u", inum); 8624236Smckusick if (reply("CONTINUE") == 0) 8634236Smckusick errexit(""); 8644236Smckusick return (STOP); 8654236Smckusick } 8664236Smckusick if (enddup >= &duplist[DUPTBLSIZE]) { 8674236Smckusick printf("DUP TABLE OVERFLOW."); 8684236Smckusick if (reply("CONTINUE") == 0) 8694236Smckusick errexit(""); 8704236Smckusick return (STOP); 8714236Smckusick } 8724236Smckusick for (dlp = duplist; dlp < muldup; dlp++) 8734236Smckusick if (*dlp == blk) { 8744236Smckusick *enddup++ = blk; 8754236Smckusick break; 8764236Smckusick } 8774236Smckusick if (dlp >= muldup) { 8784236Smckusick *enddup++ = *muldup; 8794236Smckusick *muldup++ = blk; 8804236Smckusick } 8814236Smckusick } else { 8824236Smckusick n_blks++; 8834236Smckusick setbmap(blk); 8844236Smckusick } 8854236Smckusick filsize++; 8864236Smckusick } 8874236Smckusick return (res); 8884236Smckusick } 8894236Smckusick 8904236Smckusick pass1b(blk, size) 8914236Smckusick daddr_t blk; 8924236Smckusick int size; 8934236Smckusick { 8944236Smckusick register daddr_t *dlp; 8954236Smckusick int res = KEEPON; 8964236Smckusick 8974236Smckusick for (; size > 0; blk++, size--) { 8984236Smckusick if (outrange(blk)) 8994236Smckusick res = SKIP; 9004236Smckusick for (dlp = duplist; dlp < muldup; dlp++) 9014236Smckusick if (*dlp == blk) { 9024236Smckusick blkerr("DUP", blk); 9034236Smckusick *dlp = *--muldup; 9044236Smckusick *muldup = blk; 9054236Smckusick if (muldup == duplist) 9064236Smckusick return (STOP); 9074236Smckusick } 9084236Smckusick } 9094236Smckusick return (res); 9104236Smckusick } 9114236Smckusick 9124236Smckusick pass2(dirp) 9134236Smckusick register DIRECT *dirp; 9144236Smckusick { 9154236Smckusick register char *p; 9164236Smckusick register n; 9174236Smckusick DINODE *dp; 9184236Smckusick 9194236Smckusick if ((inum = dirp->d_ino) == 0) 9204236Smckusick return (KEEPON); 9214236Smckusick thisname = pathp; 9225877Smckusic for (p = dirp->d_name; p < &dirp->d_name[MAXNAMLEN]; ) 9234236Smckusick if ((*pathp++ = *p++) == 0) { 9244236Smckusick --pathp; 9254236Smckusick break; 9264236Smckusick } 9274236Smckusick *pathp = 0; 9284236Smckusick n = 0; 9294715Smckusic if (inum > imax || inum <= 0) 9304236Smckusick n = direrr("I OUT OF RANGE"); 9314236Smckusick else { 9324236Smckusick again: 9334236Smckusick switch (getstate()) { 9344236Smckusick case USTATE: 9354236Smckusick n = direrr("UNALLOCATED"); 9364236Smckusick break; 9374236Smckusick 9384236Smckusick case CLEAR: 9394236Smckusick if ((n = direrr("DUP/BAD")) == 1) 9404236Smckusick break; 9414236Smckusick if ((dp = ginode()) == NULL) 9424236Smckusick break; 9435877Smckusic setstate(DIRCT ? DSTATE : FSTATE); 9444236Smckusick goto again; 9454236Smckusick 9464236Smckusick case FSTATE: 9474236Smckusick declncnt(); 9484236Smckusick break; 9494236Smckusick 9504236Smckusick case DSTATE: 9514236Smckusick declncnt(); 9524236Smckusick descend(); 9534236Smckusick break; 9544236Smckusick } 9554236Smckusick } 9564236Smckusick pathp = thisname; 9574236Smckusick if (n == 0) 9584236Smckusick return (KEEPON); 9594236Smckusick dirp->d_ino = 0; 9604236Smckusick return (KEEPON|ALTERD); 9614236Smckusick } 9624236Smckusick 9634236Smckusick pass4(blk, size) 9644715Smckusic daddr_t blk; 9654236Smckusick { 9664236Smckusick register daddr_t *dlp; 9674236Smckusick int res = KEEPON; 9684236Smckusick 9694236Smckusick for (; size > 0; blk++, size--) { 9704236Smckusick if (outrange(blk)) 9714236Smckusick res = SKIP; 9724236Smckusick else if (getbmap(blk)) { 9734236Smckusick for (dlp = duplist; dlp < enddup; dlp++) 9744236Smckusick if (*dlp == blk) { 9754236Smckusick *dlp = *--enddup; 9764236Smckusick return (KEEPON); 9774236Smckusick } 9784236Smckusick clrbmap(blk); 9794236Smckusick n_blks--; 9804236Smckusick } 9814236Smckusick } 9824236Smckusick return (res); 9834236Smckusick } 9844236Smckusick 9854236Smckusick pass5(blk, size) 9864236Smckusick daddr_t blk; 9874236Smckusick int size; 9884236Smckusick { 9894236Smckusick int res = KEEPON; 9904236Smckusick 9914236Smckusick for (; size > 0; blk++, size--) { 9924236Smckusick if (outrange(blk)) { 9934236Smckusick fixcg = 1; 9944236Smckusick if (preen) 9954236Smckusick pfatal("BAD BLOCKS IN BIT MAPS."); 9964236Smckusick if (++badblk >= MAXBAD) { 9974236Smckusick printf("EXCESSIVE BAD BLKS IN BIT MAPS."); 9984236Smckusick if (reply("CONTINUE") == 0) 9994236Smckusick errexit(""); 10004236Smckusick return (STOP); 10014236Smckusick } 10024236Smckusick } else if (getfmap(blk)) { 10034236Smckusick fixcg = 1; 10044236Smckusick if (++dupblk >= DUPTBLSIZE) { 10054236Smckusick printf("EXCESSIVE DUP BLKS IN BIT MAPS."); 10064236Smckusick if (reply("CONTINUE") == 0) 10074236Smckusick errexit(""); 10084236Smckusick return (STOP); 10094236Smckusick } 10104236Smckusick } else { 10114236Smckusick n_ffree++; 10124236Smckusick setfmap(blk); 10134236Smckusick } 10144236Smckusick } 10154236Smckusick return (res); 10164236Smckusick } 10174236Smckusick 10184236Smckusick outrange(blk) 10194236Smckusick daddr_t blk; 10204236Smckusick { 10214236Smckusick register int c; 10224236Smckusick 10235381Smckusic c = dtog(&sblock, blk); 10246533Smckusick if ((unsigned)blk >= fmax) { 10254236Smckusick return (1); 10264428Smckusic } 10274236Smckusick return (0); 10284236Smckusick } 10294236Smckusick 10304236Smckusick blkerr(s, blk) 10314236Smckusick daddr_t blk; 10324236Smckusick char *s; 10334236Smckusick { 10344236Smckusick pfatal("%ld %s I=%u", blk, s, inum); 10354236Smckusick printf("\n"); 10364236Smckusick setstate(CLEAR); /* mark for possible clearing */ 10374236Smckusick } 10384236Smckusick 10394236Smckusick descend() 10404236Smckusick { 10414236Smckusick register DINODE *dp; 10424236Smckusick register char *savname; 10434236Smckusick off_t savsize; 10444236Smckusick 10454236Smckusick setstate(FSTATE); 10464236Smckusick if ((dp = ginode()) == NULL) 10474236Smckusick return; 10484236Smckusick savname = thisname; 10494236Smckusick *pathp++ = '/'; 10504236Smckusick savsize = filsize; 10514236Smckusick filsize = dp->di_size; 10524236Smckusick ckinode(dp, DATA); 10534236Smckusick thisname = savname; 10544236Smckusick *--pathp = 0; 10554236Smckusick filsize = savsize; 10564236Smckusick } 10574236Smckusick 10585877Smckusic struct dirstuff { 10595877Smckusic int loc; 10605877Smckusic int blkno; 10615877Smckusic int blksiz; 10625877Smckusic }; 10635877Smckusic 10644236Smckusick dirscan(blk, nf) 10654715Smckusic daddr_t blk; 10664715Smckusic int nf; 10674236Smckusick { 10685877Smckusic register DIRECT *dp; 10695877Smckusic struct dirstuff dirp; 10706251Smckusick int blksiz, dsize, n; 10716251Smckusick char dbuf[DIRBLKSIZ]; 10724236Smckusick 10734236Smckusick if (outrange(blk)) { 10745325Smckusic filsize -= sblock.fs_bsize; 10754236Smckusick return (SKIP); 10764236Smckusick } 10775877Smckusic blksiz = nf * sblock.fs_fsize; 10785877Smckusic dirp.loc = 0; 10795877Smckusic dirp.blkno = blk; 10805877Smckusic dirp.blksiz = blksiz; 10815877Smckusic for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) { 10826251Smckusick dsize = dp->d_reclen; 10836251Smckusick copy(dp, dbuf, dsize); 10846251Smckusick if ((n = (*pfunc)(dbuf)) & ALTERD) { 10855877Smckusic if (getblk(&fileblk, blk, blksiz) != NULL) { 10866251Smckusick copy(dbuf, dp, dsize); 10874715Smckusic dirty(&fileblk); 10884236Smckusick sbdirty(); 10894236Smckusick } else 10904236Smckusick n &= ~ALTERD; 10914236Smckusick } 10925877Smckusic if (n & STOP) 10934236Smckusick return (n); 10944236Smckusick } 10954236Smckusick return (filsize > 0 ? KEEPON : STOP); 10964236Smckusick } 10974236Smckusick 10985877Smckusic /* 10995877Smckusic * get next entry in a directory. 11005877Smckusic */ 11015877Smckusic DIRECT * 11025877Smckusic readdir(dirp) 11035877Smckusic register struct dirstuff *dirp; 11045877Smckusic { 11056251Smckusick register DIRECT *dp, *ndp; 11065877Smckusic 11075877Smckusic if (getblk(&fileblk, dirp->blkno, dirp->blksiz) == NULL) { 11085877Smckusic filsize -= dirp->blksiz - dirp->loc; 11095877Smckusic return NULL; 11105877Smckusic } 11115877Smckusic for (;;) { 11125877Smckusic if (filsize <= 0 || dirp->loc >= dirp->blksiz) 11135877Smckusic return NULL; 11145935Smckusic dp = (DIRECT *)(dirblk.b_buf + dirp->loc); 11155935Smckusic dirp->loc += dp->d_reclen; 11165935Smckusic filsize -= dp->d_reclen; 11176251Smckusick ndp = (DIRECT *)(dirblk.b_buf + dirp->loc); 11186372Smckusick if (dirp->loc < dirp->blksiz && filsize > 0 && 11196251Smckusick (ndp->d_ino > imax || ndp->d_namlen > MAXNAMLEN || 11206251Smckusick ndp->d_reclen <= 0 || 11216251Smckusick ndp->d_reclen > DIRBLKSIZ - (dirp->loc % DIRBLKSIZ))) { 11226251Smckusick pwarn("DIRECTORY CORRUPTED"); 11236251Smckusick if (preen) 11246251Smckusick printf(" (SALVAGED)\n"); 11256251Smckusick else if (reply("SALVAGE") == 0) { 11266251Smckusick dirp->loc += 11276251Smckusick DIRBLKSIZ - (dirp->loc % DIRBLKSIZ); 11286251Smckusick filsize -= DIRBLKSIZ - (dirp->loc % DIRBLKSIZ); 11296251Smckusick return(dp); 11306251Smckusick } 11316251Smckusick dirp->loc -= dp->d_reclen; 11326251Smckusick filsize += dp->d_reclen; 11336251Smckusick dp->d_reclen = DIRBLKSIZ - (dirp->loc % DIRBLKSIZ); 11346251Smckusick dirty(&fileblk); 11355877Smckusic continue; 11366251Smckusick } 11375935Smckusic return (dp); 11385877Smckusic } 11395877Smckusic } 11405877Smckusic 11414236Smckusick direrr(s) 11424715Smckusic char *s; 11434236Smckusick { 11444236Smckusick register DINODE *dp; 11454236Smckusick 11464236Smckusick pwarn("%s ", s); 11474236Smckusick pinode(); 11484236Smckusick printf("\n"); 11494236Smckusick if ((dp = ginode()) != NULL && ftypeok(dp)) 11505877Smckusic pfatal("%s=%s", DIRCT?"DIR":"FILE", pathname); 11514236Smckusick else 11524236Smckusick pfatal("NAME=%s", pathname); 11534236Smckusick return (reply("REMOVE")); 11544236Smckusick } 11554236Smckusick 11564236Smckusick adjust(lcnt) 11574465Smckusic register short lcnt; 11584236Smckusick { 11594236Smckusick register DINODE *dp; 11604236Smckusick 11614236Smckusick if ((dp = ginode()) == NULL) 11624236Smckusick return; 11634236Smckusick if (dp->di_nlink == lcnt) { 11644236Smckusick if (linkup() == 0) 11654236Smckusick clri("UNREF", 0); 11664236Smckusick } 11674236Smckusick else { 11684236Smckusick pwarn("LINK COUNT %s", 11695877Smckusic (lfdir==inum)?lfname:(DIRCT?"DIR":"FILE")); 11704236Smckusick pinode(); 11714236Smckusick printf(" COUNT %d SHOULD BE %d", 11724236Smckusick dp->di_nlink, dp->di_nlink-lcnt); 11734236Smckusick if (preen) { 11744236Smckusick if (lcnt < 0) { 11754236Smckusick printf("\n"); 11764236Smckusick preendie(); 11774236Smckusick } 11784236Smckusick printf(" (ADJUSTED)\n"); 11794236Smckusick } 11804236Smckusick if (preen || reply("ADJUST") == 1) { 11814236Smckusick dp->di_nlink -= lcnt; 11824236Smckusick inodirty(); 11834236Smckusick } 11844236Smckusick } 11854236Smckusick } 11864236Smckusick 11874236Smckusick clri(s, flg) 11884715Smckusic char *s; 11894236Smckusick { 11904236Smckusick register DINODE *dp; 11914236Smckusick 11924236Smckusick if ((dp = ginode()) == NULL) 11934236Smckusick return; 11944236Smckusick if (flg == 1) { 11955877Smckusic pwarn("%s %s", s, DIRCT?"DIR":"FILE"); 11964236Smckusick pinode(); 11974236Smckusick } 11984236Smckusick if (preen || reply("CLEAR") == 1) { 11994236Smckusick if (preen) 12004236Smckusick printf(" (CLEARED)\n"); 12014236Smckusick n_files--; 12024236Smckusick pfunc = pass4; 12034236Smckusick ckinode(dp, ADDR); 12044236Smckusick zapino(dp); 12054465Smckusic setstate(USTATE); 12064236Smckusick inodirty(); 12074236Smckusick inosumbad++; 12084236Smckusick } 12094236Smckusick } 12104236Smckusick 12114236Smckusick setup(dev) 12124715Smckusic char *dev; 12134236Smckusick { 12144236Smckusick dev_t rootdev; 12156489Smckusick struct stat statb; 12164236Smckusick int super = bflag ? bflag : SBLOCK; 12176533Smckusick int i, j, size; 12186533Smckusick int c, d, cgd; 12194236Smckusick 12204236Smckusick bflag = 0; 12214236Smckusick if (stat("/", &statb) < 0) 12224236Smckusick errexit("Can't stat root\n"); 12234236Smckusick rootdev = statb.st_dev; 12244236Smckusick if (stat(dev, &statb) < 0) { 12254236Smckusick error("Can't stat %s\n", dev); 12264236Smckusick return (0); 12274236Smckusick } 12284236Smckusick rawflg = 0; 12294236Smckusick if ((statb.st_mode & S_IFMT) == S_IFBLK) 12304236Smckusick ; 12314236Smckusick else if ((statb.st_mode & S_IFMT) == S_IFCHR) 12324236Smckusick rawflg++; 12334236Smckusick else { 12344236Smckusick if (reply("file is not a block or character device; OK") == 0) 12354236Smckusick return (0); 12364236Smckusick } 12374236Smckusick if (rootdev == statb.st_rdev) 12384236Smckusick hotroot++; 12394236Smckusick if ((dfile.rfdes = open(dev, 0)) < 0) { 12404236Smckusick error("Can't open %s\n", dev); 12414236Smckusick return (0); 12424236Smckusick } 12434236Smckusick if (preen == 0) 12444236Smckusick printf("** %s", dev); 12454236Smckusick if (nflag || (dfile.wfdes = open(dev, 1)) < 0) { 12464236Smckusick dfile.wfdes = -1; 12474236Smckusick if (preen) 12484236Smckusick pfatal("NO WRITE ACCESS"); 12494236Smckusick printf(" (NO WRITE)"); 12504236Smckusick } 12514236Smckusick if (preen == 0) 12524236Smckusick printf("\n"); 12536491Smckusick fixcg = 0; inosumbad = 0; offsumbad = 0; frsumbad = 0; sbsumbad = 0; 12544236Smckusick dfile.mod = 0; 12554236Smckusick n_files = n_blks = n_ffree = n_bfree = 0; 12564236Smckusick muldup = enddup = &duplist[0]; 12574236Smckusick badlnp = &badlncnt[0]; 12584236Smckusick lfdir = 0; 12594236Smckusick rplyflag = 0; 12604236Smckusick initbarea(&sblk); 12614236Smckusick initbarea(&fileblk); 12624236Smckusick initbarea(&inoblk); 12634236Smckusick initbarea(&cgblk); 12646491Smckusick /* 12656491Smckusick * Read in the super block and its summary info. 12666491Smckusick */ 12675347Smckusic if (bread(&dfile, &sblock, super, SBSIZE) == 0) 12684236Smckusick return (0); 12694465Smckusic sblk.b_bno = super; 12705347Smckusic sblk.b_size = SBSIZE; 12715363Smckusic /* 12725363Smckusic * run a few consistency checks of the super block 12735363Smckusic */ 12744236Smckusick if (sblock.fs_magic != FS_MAGIC) 12754236Smckusick { badsb("MAGIC NUMBER WRONG"); return (0); } 12764236Smckusick if (sblock.fs_ncg < 1) 12774236Smckusick { badsb("NCG OUT OF RANGE"); return (0); } 12784236Smckusick if (sblock.fs_cpg < 1 || sblock.fs_cpg > MAXCPG) 12794236Smckusick { badsb("CPG OUT OF RANGE"); return (0); } 12804236Smckusick if (sblock.fs_nsect < 1) 12814236Smckusick { badsb("NSECT < 1"); return (0); } 12824236Smckusick if (sblock.fs_ntrak < 1) 12834236Smckusick { badsb("NTRAK < 1"); return (0); } 12845363Smckusic if (sblock.fs_spc != sblock.fs_nsect * sblock.fs_ntrak) 12855363Smckusic { badsb("SPC DOES NOT JIVE w/NTRAK*NSECT"); return (0); } 12865363Smckusic if (sblock.fs_ipg % INOPB(&sblock)) 12875363Smckusic { badsb("INODES NOT MULTIPLE OF A BLOCK"); return (0); } 12885381Smckusic if (cgdmin(&sblock, 0) >= sblock.fs_cpg * sblock.fs_spc / NSPF(&sblock)) 12894236Smckusick { badsb("IMPLIES MORE INODE THAN DATA BLOCKS"); return (0); } 12905363Smckusic if (sblock.fs_ncg * sblock.fs_cpg < sblock.fs_ncyl || 12915363Smckusic (sblock.fs_ncg - 1) * sblock.fs_cpg >= sblock.fs_ncyl) 12924236Smckusick { badsb("NCYL DOES NOT JIVE WITH NCG*CPG"); return (0); } 12935325Smckusic if (sblock.fs_fpg != sblock.fs_cpg * sblock.fs_spc / NSPF(&sblock)) 12944236Smckusick { badsb("FPG DOES NOT JIVE WITH CPG & SPC"); return (0); } 12955363Smckusic if (sblock.fs_size * NSPF(&sblock) <= 12965363Smckusic (sblock.fs_ncyl - 1) * sblock.fs_spc) 12974236Smckusick { badsb("SIZE PREPOSTEROUSLY SMALL"); return (0); } 12985363Smckusic if (sblock.fs_size * NSPF(&sblock) > sblock.fs_ncyl * sblock.fs_spc) 12994236Smckusick { badsb("SIZE PREPOSTEROUSLY LARGE"); return (0); } 13004236Smckusick /* rest we COULD repair... */ 13015956Smckusic if (sblock.fs_cgsize != fragroundup(&sblock, 13025956Smckusic sizeof(struct cg) + howmany(sblock.fs_fpg, NBBY))) 13034236Smckusick { badsb("CGSIZE INCORRECT"); return (0); } 13046533Smckusick if (sblock.fs_cssize != 13056533Smckusick fragroundup(&sblock, sblock.fs_ncg * sizeof(struct csum))) 13064236Smckusick { badsb("CSSIZE INCORRECT"); return (0); } 13074236Smckusick fmax = sblock.fs_size; 13084236Smckusick imax = sblock.fs_ncg * sblock.fs_ipg; 13096533Smckusick n_bad = cgsblock(&sblock, 0); /* boot block plus dedicated sblock */ 13105363Smckusic /* 13116533Smckusick * read in the summary info. 13125363Smckusic */ 13136533Smckusick for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) { 13146533Smckusick size = sblock.fs_cssize - i < sblock.fs_bsize ? 13156533Smckusick sblock.fs_cssize - i : sblock.fs_bsize; 13166533Smckusick sblock.fs_csp[j] = (struct csum *)calloc(1, size); 13176533Smckusick bread(&dfile, (char *)sblock.fs_csp[j], 13186533Smckusick fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag), 13196533Smckusick size); 13206533Smckusick } 13216533Smckusick /* 13226533Smckusick * allocate and initialize the necessary maps 13236533Smckusick */ 13244236Smckusick bmapsz = roundup(howmany(fmax, NBBY), sizeof(short)); 13256314Smckusick blockmap = (char *)calloc(bmapsz, sizeof (char)); 1326*6547Smckusick if (blockmap == NULL) { 1327*6547Smckusick printf("cannot alloc %d bytes for blockmap\n", bmapsz); 1328*6547Smckusick exit(1); 1329*6547Smckusick } 13304236Smckusick freemap = (char *)calloc(bmapsz, sizeof (char)); 1331*6547Smckusick if (freemap == NULL) { 1332*6547Smckusick printf("cannot alloc %d bytes for freemap\n", bmapsz); 1333*6547Smckusick exit(1); 1334*6547Smckusick } 13354236Smckusick statemap = (char *)calloc(imax+1, sizeof(char)); 1336*6547Smckusick if (statemap == NULL) { 1337*6547Smckusick printf("cannot alloc %d bytes for statemap\n", imax + 1); 1338*6547Smckusick exit(1); 1339*6547Smckusick } 13404236Smckusick lncntp = (short *)calloc(imax+1, sizeof(short)); 1341*6547Smckusick if (lncntp == NULL) { 1342*6547Smckusick printf("cannot alloc %d bytes for lncntp\n", 1343*6547Smckusick (imax + 1) * sizeof(short)); 1344*6547Smckusick exit(1); 1345*6547Smckusick } 13466533Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 13476533Smckusick cgd = cgdmin(&sblock, c); 13486533Smckusick if (c == 0) { 13496533Smckusick d = cgbase(&sblock, c); 13506533Smckusick cgd += howmany(sblock.fs_cssize, sblock.fs_fsize); 13516533Smckusick } else 13526533Smckusick d = cgsblock(&sblock, c); 13536533Smckusick for (; d < cgd; d++) 13546533Smckusick setbmap(d); 13556533Smckusick } 13564236Smckusick 13574465Smckusic startinum = imax + 1; 13584236Smckusick return (1); 13594236Smckusick 13604236Smckusick badsb: 13614236Smckusick ckfini(); 13624236Smckusick return (0); 13634236Smckusick } 13644236Smckusick 13654236Smckusick badsb(s) 13664236Smckusick char *s; 13674236Smckusick { 13684236Smckusick 13694236Smckusick if (preen) 13704236Smckusick printf("%s: ", devname); 13714236Smckusick printf("BAD SUPER BLOCK: %s\n", s); 13724236Smckusick pwarn("USE -b OPTION TO FSCK TO SPECIFY LOCATION OF AN ALTERNATE\n"); 13734236Smckusick pfatal("SUPER-BLOCK TO SUPPLY NEEDED INFORMATION; SEE fsck(8).\n"); 13744236Smckusick } 13754236Smckusick 13764236Smckusick DINODE * 13774236Smckusick ginode() 13784236Smckusick { 13794236Smckusick daddr_t iblk; 13804236Smckusick 1381*6547Smckusick if (inum < ROOTINO || inum > imax) { 1382*6547Smckusick if (debug && (inum < 0 || inum > imax)) 1383*6547Smckusick printf("inum out of range (%d)\n", inum); 13844236Smckusick return (NULL); 1385*6547Smckusick } 13865325Smckusic if (inum < startinum || inum >= startinum + INOPB(&sblock)) { 13875381Smckusic iblk = itod(&sblock, inum); 13885325Smckusic if (getblk(&inoblk, iblk, sblock.fs_bsize) == NULL) { 13894236Smckusick return (NULL); 13904236Smckusick } 13915325Smckusic startinum = (inum / INOPB(&sblock)) * INOPB(&sblock); 13924236Smckusick } 13935325Smckusic return (&inoblk.b_un.b_dinode[inum % INOPB(&sblock)]); 13944236Smckusick } 13954236Smckusick 13964236Smckusick ftypeok(dp) 13974236Smckusick DINODE *dp; 13984236Smckusick { 13994236Smckusick switch (dp->di_mode & IFMT) { 14004236Smckusick 14014236Smckusick case IFDIR: 14024236Smckusick case IFREG: 14034236Smckusick case IFBLK: 14044236Smckusick case IFCHR: 14056285Smckusick case IFLNK: 14064236Smckusick return (1); 14074236Smckusick 14084236Smckusick default: 14094236Smckusick return (0); 14104236Smckusick } 14114236Smckusick } 14124236Smckusick 14134236Smckusick reply(s) 14144236Smckusick char *s; 14154236Smckusick { 14164236Smckusick char line[80]; 14174236Smckusick 14184236Smckusick if (preen) 14194236Smckusick pfatal("INTERNAL ERROR: GOT TO reply()"); 14204236Smckusick rplyflag = 1; 14214236Smckusick printf("\n%s? ", s); 14224236Smckusick if (nflag || dfile.wfdes < 0) { 14234236Smckusick printf(" no\n\n"); 14244236Smckusick return (0); 14254236Smckusick } 14264236Smckusick if (yflag) { 14274236Smckusick printf(" yes\n\n"); 14284236Smckusick return (1); 14294236Smckusick } 14304236Smckusick if (getline(stdin, line, sizeof(line)) == EOF) 14314236Smckusick errexit("\n"); 14324236Smckusick printf("\n"); 14334236Smckusick if (line[0] == 'y' || line[0] == 'Y') 14344236Smckusick return (1); 14354236Smckusick else 14364236Smckusick return (0); 14374236Smckusick } 14384236Smckusick 14394236Smckusick getline(fp, loc, maxlen) 14404236Smckusick FILE *fp; 14414236Smckusick char *loc; 14424236Smckusick { 14434236Smckusick register n; 14444236Smckusick register char *p, *lastloc; 14454236Smckusick 14464236Smckusick p = loc; 14474236Smckusick lastloc = &p[maxlen-1]; 14484236Smckusick while ((n = getc(fp)) != '\n') { 14494236Smckusick if (n == EOF) 14504236Smckusick return (EOF); 14514236Smckusick if (!isspace(n) && p < lastloc) 14524236Smckusick *p++ = n; 14534236Smckusick } 14544236Smckusick *p = 0; 14554236Smckusick return (p - loc); 14564236Smckusick } 14574236Smckusick 14584236Smckusick BUFAREA * 14594236Smckusick getblk(bp, blk, size) 14604236Smckusick daddr_t blk; 14614236Smckusick register BUFAREA *bp; 14624236Smckusick int size; 14634236Smckusick { 14644236Smckusick register struct filecntl *fcp; 14655325Smckusic daddr_t dblk; 14664236Smckusick 14674236Smckusick fcp = &dfile; 14685325Smckusic dblk = fsbtodb(&sblock, blk); 14695325Smckusic if (bp->b_bno == dblk) 14704236Smckusick return (bp); 14714236Smckusick flush(fcp, bp); 14725325Smckusic if (bread(fcp, bp->b_un.b_buf, dblk, size) != 0) { 14735325Smckusic bp->b_bno = dblk; 14744236Smckusick bp->b_size = size; 14754236Smckusick return (bp); 14764236Smckusick } 14774236Smckusick bp->b_bno = (daddr_t)-1; 14784236Smckusick return (NULL); 14794236Smckusick } 14804236Smckusick 14814236Smckusick flush(fcp, bp) 14824236Smckusick struct filecntl *fcp; 14834236Smckusick register BUFAREA *bp; 14844236Smckusick { 14854236Smckusick 14864236Smckusick if (bp->b_dirty) 14874236Smckusick bwrite(fcp, bp->b_un.b_buf, bp->b_bno, bp->b_size); 14884236Smckusick bp->b_dirty = 0; 14894236Smckusick } 14904236Smckusick 14914236Smckusick rwerr(s, blk) 14924236Smckusick char *s; 14934236Smckusick daddr_t blk; 14944236Smckusick { 14954236Smckusick 14964236Smckusick if (preen == 0) 14974236Smckusick printf("\n"); 14984236Smckusick pfatal("CANNOT %s: BLK %ld", s, blk); 14994236Smckusick if (reply("CONTINUE") == 0) 15004236Smckusick errexit("Program terminated\n"); 15014236Smckusick } 15024236Smckusick 15034236Smckusick ckfini() 15044236Smckusick { 15054236Smckusick 15064236Smckusick flush(&dfile, &fileblk); 15074236Smckusick flush(&dfile, &sblk); 15084465Smckusic if (sblk.b_bno != SBLOCK) { 15094465Smckusic sblk.b_bno = SBLOCK; 15104465Smckusic sbdirty(); 15114465Smckusic flush(&dfile, &sblk); 15124465Smckusic } 15134236Smckusick flush(&dfile, &inoblk); 15144236Smckusick close(dfile.rfdes); 15154236Smckusick close(dfile.wfdes); 15164236Smckusick } 15174236Smckusick 15184236Smckusick pinode() 15194236Smckusick { 15204236Smckusick register DINODE *dp; 15214236Smckusick register char *p; 15225877Smckusic char uidbuf[BUFSIZ]; 15234236Smckusick char *ctime(); 15244236Smckusick 15254236Smckusick printf(" I=%u ", inum); 15264236Smckusick if ((dp = ginode()) == NULL) 15274236Smckusick return; 15284236Smckusick printf(" OWNER="); 15294236Smckusick if (getpw((int)dp->di_uid, uidbuf) == 0) { 15304236Smckusick for (p = uidbuf; *p != ':'; p++); 15314236Smckusick *p = 0; 15324236Smckusick printf("%s ", uidbuf); 15334236Smckusick } 15344236Smckusick else { 15354236Smckusick printf("%d ", dp->di_uid); 15364236Smckusick } 15374236Smckusick printf("MODE=%o\n", dp->di_mode); 15384236Smckusick if (preen) 15394236Smckusick printf("%s: ", devname); 15404236Smckusick printf("SIZE=%ld ", dp->di_size); 15414236Smckusick p = ctime(&dp->di_mtime); 15424236Smckusick printf("MTIME=%12.12s %4.4s ", p+4, p+20); 15434236Smckusick } 15444236Smckusick 15454236Smckusick copy(fp, tp, size) 15464236Smckusick register char *tp, *fp; 15474236Smckusick unsigned size; 15484236Smckusick { 15494236Smckusick 15504236Smckusick while (size--) 15514236Smckusick *tp++ = *fp++; 15524236Smckusick } 15534236Smckusick 15544236Smckusick makecg() 15554236Smckusick { 15564465Smckusic int c, blk; 15576533Smckusick daddr_t dbase, d, dlower, dupper, dmax; 15584236Smckusick long i, j, s; 15594236Smckusick register struct csum *cs; 15604465Smckusic register DINODE *dp; 15614236Smckusick 15624789Smckusic sblock.fs_cstotal.cs_nbfree = 0; 15634789Smckusic sblock.fs_cstotal.cs_nffree = 0; 15644789Smckusic sblock.fs_cstotal.cs_nifree = 0; 15654789Smckusic sblock.fs_cstotal.cs_ndir = 0; 15664236Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 15675381Smckusic dbase = cgbase(&sblock, c); 15684236Smckusick dmax = dbase + sblock.fs_fpg; 15695409Smckusic if (dmax > sblock.fs_size) { 15705944Smckusic for ( ; dmax >= sblock.fs_size; dmax--) 15715401Smckusic clrbit(cgrp.cg_free, dmax - dbase); 15725409Smckusic dmax++; 15735409Smckusic } 15746533Smckusick dlower = cgsblock(&sblock, c) - dbase; 15756533Smckusick dupper = cgdmin(&sblock, c) - dbase; 15765325Smckusic cs = &sblock.fs_cs(&sblock, c); 15774236Smckusick cgrp.cg_time = time(0); 15784236Smckusick cgrp.cg_magic = CG_MAGIC; 15794236Smckusick cgrp.cg_cgx = c; 15804236Smckusick cgrp.cg_ncyl = sblock.fs_cpg; 15814236Smckusick cgrp.cg_niblk = sblock.fs_ipg; 15824236Smckusick cgrp.cg_ndblk = dmax - dbase; 15834789Smckusic cgrp.cg_cs.cs_ndir = 0; 15844789Smckusic cgrp.cg_cs.cs_nffree = 0; 15854789Smckusic cgrp.cg_cs.cs_nbfree = 0; 15864789Smckusic cgrp.cg_cs.cs_nifree = 0; 15876533Smckusick cgrp.cg_rotor = 0; 15886533Smckusick cgrp.cg_frotor = 0; 15894258Smckusic cgrp.cg_irotor = 0; 15905325Smckusic for (i = 0; i < sblock.fs_frag; i++) 15914465Smckusic cgrp.cg_frsum[i] = 0; 15924236Smckusick inum = sblock.fs_ipg * c; 15934465Smckusic for (i = 0; i < sblock.fs_ipg; inum++, i++) { 15945944Smckusic cgrp.cg_cs.cs_nifree++; 15955944Smckusic clrbit(cgrp.cg_iused, i); 15964465Smckusic dp = ginode(); 15974465Smckusic if (dp == NULL) 15984465Smckusic continue; 15994465Smckusic if (ALLOC) { 16005877Smckusic if (DIRCT) 16014789Smckusic cgrp.cg_cs.cs_ndir++; 16025944Smckusic cgrp.cg_cs.cs_nifree--; 16034465Smckusic setbit(cgrp.cg_iused, i); 16044465Smckusic continue; 16054465Smckusic } 16064236Smckusick } 16074236Smckusick while (i < MAXIPG) { 16084236Smckusick clrbit(cgrp.cg_iused, i); 16094236Smckusick i++; 16104236Smckusick } 16115944Smckusic if (c == 0) 16125944Smckusic for (i = 0; i < ROOTINO; i++) { 16135944Smckusic setbit(cgrp.cg_iused, i); 16145944Smckusic cgrp.cg_cs.cs_nifree--; 16155944Smckusic } 16165371Smckusic for (s = 0; s < MAXCPG; s++) { 16175371Smckusic cgrp.cg_btot[s] = 0; 16184236Smckusick for (i = 0; i < NRPOS; i++) 16194236Smckusick cgrp.cg_b[s][i] = 0; 16205371Smckusic } 16214236Smckusick if (c == 0) { 16226533Smckusick dupper += howmany(sblock.fs_cssize, sblock.fs_fsize); 16234236Smckusick } 16246533Smckusick for (d = dlower; d < dupper; d++) 16254236Smckusick clrbit(cgrp.cg_free, d); 16266533Smckusick for (d = 0; (d + sblock.fs_frag) <= dmax - dbase; 16276533Smckusick d += sblock.fs_frag) { 16284236Smckusick j = 0; 16295325Smckusic for (i = 0; i < sblock.fs_frag; i++) { 16306533Smckusick if (!getbmap(dbase + d + i)) { 16316533Smckusick setbit(cgrp.cg_free, d + i); 16324236Smckusick j++; 16334236Smckusick } else 16344236Smckusick clrbit(cgrp.cg_free, d+i); 16354236Smckusick } 16365325Smckusic if (j == sblock.fs_frag) { 16374789Smckusic cgrp.cg_cs.cs_nbfree++; 16385371Smckusic cgrp.cg_btot[cbtocylno(&sblock, d)]++; 16395363Smckusic cgrp.cg_b[cbtocylno(&sblock, d)] 16405363Smckusic [cbtorpos(&sblock, d)]++; 16414465Smckusic } else if (j > 0) { 16424789Smckusic cgrp.cg_cs.cs_nffree += j; 16436533Smckusick blk = blkmap(&sblock, cgrp.cg_free, d); 16445325Smckusic fragacct(&sblock, blk, cgrp.cg_frsum, 1); 16454465Smckusic } 16464236Smckusick } 16474465Smckusic for (j = d; d < dmax - dbase; d++) { 16486533Smckusick if (!getbmap(dbase + d)) { 16494236Smckusick setbit(cgrp.cg_free, d); 16504789Smckusic cgrp.cg_cs.cs_nffree++; 16514236Smckusick } else 16524236Smckusick clrbit(cgrp.cg_free, d); 16534236Smckusick } 16544465Smckusic if (j != d) { 16556533Smckusick blk = blkmap(&sblock, cgrp.cg_free, j); 16565325Smckusic fragacct(&sblock, blk, cgrp.cg_frsum, 1); 16574465Smckusic } 16585325Smckusic for (; d < MAXBPG(&sblock); d++) 16594236Smckusick clrbit(cgrp.cg_free, d); 16604789Smckusic sblock.fs_cstotal.cs_nffree += cgrp.cg_cs.cs_nffree; 16614789Smckusic sblock.fs_cstotal.cs_nbfree += cgrp.cg_cs.cs_nbfree; 16624789Smckusic sblock.fs_cstotal.cs_nifree += cgrp.cg_cs.cs_nifree; 16634789Smckusic sblock.fs_cstotal.cs_ndir += cgrp.cg_cs.cs_ndir; 16644789Smckusic *cs = cgrp.cg_cs; 16655381Smckusic bwrite(&dfile, &cgrp, fsbtodb(&sblock, cgtod(&sblock, c)), 16665956Smckusic sblock.fs_cgsize); 16674236Smckusick } 16686533Smckusick for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) { 16696533Smckusick bwrite(&dfile, (char *)sblock.fs_csp[j], 16706533Smckusick fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag), 16716533Smckusick sblock.fs_cssize - i < sblock.fs_bsize ? 16726533Smckusick sblock.fs_cssize - i : sblock.fs_bsize); 16735097Smckusic } 16744236Smckusick sblock.fs_ronly = 0; 16754236Smckusick sblock.fs_fmod = 0; 16764236Smckusick sbdirty(); 16774236Smckusick } 16784236Smckusick 16794465Smckusic /* 16804465Smckusic * update the frsum fields to reflect addition or deletion 16814465Smckusic * of some frags 16824465Smckusic */ 16835325Smckusic fragacct(fs, fragmap, fraglist, cnt) 16845325Smckusic struct fs *fs; 16854470Smckusic int fragmap; 16864789Smckusic long fraglist[]; 16874465Smckusic int cnt; 16884465Smckusic { 16894465Smckusic int inblk; 16904465Smckusic register int field, subfield; 16914465Smckusic register int siz, pos; 16924465Smckusic 16935325Smckusic inblk = (int)(fragtbl[fs->fs_frag][fragmap] << 1); 16944465Smckusic fragmap <<= 1; 16955325Smckusic for (siz = 1; siz < fs->fs_frag; siz++) { 16966290Smckusick if ((inblk & (1 << (siz + (fs->fs_frag % NBBY)))) == 0) 16974465Smckusic continue; 16984465Smckusic field = around[siz]; 16994465Smckusic subfield = inside[siz]; 17005325Smckusic for (pos = siz; pos <= fs->fs_frag; pos++) { 17014465Smckusic if ((fragmap & field) == subfield) { 17024465Smckusic fraglist[siz] += cnt; 17034465Smckusic pos += siz; 17044465Smckusic field <<= siz; 17054465Smckusic subfield <<= siz; 17064465Smckusic } 17074465Smckusic field <<= 1; 17084465Smckusic subfield <<= 1; 17094465Smckusic } 17104465Smckusic } 17114465Smckusic } 17124465Smckusic 17134236Smckusick findino(dirp) 17144236Smckusick register DIRECT *dirp; 17154236Smckusick { 17164236Smckusick if (dirp->d_ino == 0) 17174236Smckusick return (KEEPON); 17185877Smckusic if (!strcmp(dirp->d_name, srchname)) { 17195877Smckusic if (dirp->d_ino >= ROOTINO && dirp->d_ino <= imax) 17205877Smckusic parentdir = dirp->d_ino; 17215877Smckusic return (STOP); 17224236Smckusick } 17234236Smckusick return (KEEPON); 17244236Smckusick } 17254236Smckusick 17264236Smckusick mkentry(dirp) 17274236Smckusick register DIRECT *dirp; 17284236Smckusick { 17294236Smckusick register ino_t in; 17304236Smckusick register char *p; 17316251Smckusick DIRECT newent; 17326251Smckusick int newlen, oldlen; 17334236Smckusick 17346251Smckusick newent.d_namlen = 11; 17356251Smckusick newlen = DIRSIZ(&newent); 17366251Smckusick if (dirp->d_ino != 0) 17376251Smckusick oldlen = DIRSIZ(dirp); 17386251Smckusick else 17396251Smckusick oldlen = 0; 17406251Smckusick if (dirp->d_reclen - oldlen < newlen) 17414236Smckusick return (KEEPON); 17426251Smckusick newent.d_reclen = dirp->d_reclen - oldlen; 17436251Smckusick dirp->d_reclen = oldlen; 17446251Smckusick dirp = (struct direct *)(((char *)dirp) + oldlen); 17454236Smckusick dirp->d_ino = orphan; 17466251Smckusick dirp->d_reclen = newent.d_reclen; 17476251Smckusick p = &dirp->d_name[2]; 17486251Smckusick for (in = imax; in > 0; in /= 10) 17496251Smckusick p++; 17506251Smckusick *--p = 0; 17516251Smckusick dirp->d_namlen = p - dirp->d_name; 17524236Smckusick in = orphan; 17534236Smckusick while (p > dirp->d_name) { 17544236Smckusick *--p = (in % 10) + '0'; 17554236Smckusick in /= 10; 17564236Smckusick } 17574236Smckusick *p = '#'; 17584236Smckusick return (ALTERD|STOP); 17594236Smckusick } 17604236Smckusick 17614236Smckusick chgdd(dirp) 17624236Smckusick register DIRECT *dirp; 17634236Smckusick { 17644236Smckusick if (dirp->d_name[0] == '.' && dirp->d_name[1] == '.' && 17654236Smckusick dirp->d_name[2] == 0) { 17664236Smckusick dirp->d_ino = lfdir; 17674236Smckusick return (ALTERD|STOP); 17684236Smckusick } 17694236Smckusick return (KEEPON); 17704236Smckusick } 17714236Smckusick 17724236Smckusick linkup() 17734236Smckusick { 17744236Smckusick register DINODE *dp; 17754236Smckusick register lostdir; 17764236Smckusick register ino_t pdir; 17774236Smckusick 17784236Smckusick if ((dp = ginode()) == NULL) 17794236Smckusick return (0); 17805877Smckusic lostdir = DIRCT; 17814236Smckusick pdir = parentdir; 17824236Smckusick pwarn("UNREF %s ", lostdir ? "DIR" : "FILE"); 17834236Smckusick pinode(); 17844236Smckusick if (preen && dp->di_size == 0) 17854236Smckusick return (0); 17864236Smckusick if (preen) 17874236Smckusick printf(" (RECONNECTED)\n"); 17884236Smckusick else 17894236Smckusick if (reply("RECONNECT") == 0) 17904236Smckusick return (0); 17914236Smckusick orphan = inum; 17924236Smckusick if (lfdir == 0) { 17934236Smckusick inum = ROOTINO; 17944236Smckusick if ((dp = ginode()) == NULL) { 17954236Smckusick inum = orphan; 17964236Smckusick return (0); 17974236Smckusick } 17984236Smckusick pfunc = findino; 17994236Smckusick srchname = lfname; 18004236Smckusick filsize = dp->di_size; 18014236Smckusick parentdir = 0; 18024236Smckusick ckinode(dp, DATA); 18034236Smckusick inum = orphan; 18044236Smckusick if ((lfdir = parentdir) == 0) { 18054236Smckusick pfatal("SORRY. NO lost+found DIRECTORY"); 18064236Smckusick printf("\n\n"); 18074236Smckusick return (0); 18084236Smckusick } 18094236Smckusick } 18104236Smckusick inum = lfdir; 18115877Smckusic if ((dp = ginode()) == NULL || !DIRCT || getstate() != FSTATE) { 18124236Smckusick inum = orphan; 18134236Smckusick pfatal("SORRY. NO lost+found DIRECTORY"); 18144236Smckusick printf("\n\n"); 18154236Smckusick return (0); 18164236Smckusick } 18175956Smckusic if (fragoff(&sblock, dp->di_size)) { 18185956Smckusic dp->di_size = fragroundup(&sblock, dp->di_size); 18194236Smckusick inodirty(); 18204236Smckusick } 18214236Smckusick filsize = dp->di_size; 18224236Smckusick inum = orphan; 18234236Smckusick pfunc = mkentry; 18244236Smckusick if ((ckinode(dp, DATA) & ALTERD) == 0) { 18254236Smckusick pfatal("SORRY. NO SPACE IN lost+found DIRECTORY"); 18264236Smckusick printf("\n\n"); 18274236Smckusick return (0); 18284236Smckusick } 18294236Smckusick declncnt(); 18304236Smckusick if (lostdir) { 18314236Smckusick pfunc = chgdd; 18324236Smckusick dp = ginode(); 18334236Smckusick filsize = dp->di_size; 18344236Smckusick ckinode(dp, DATA); 18354236Smckusick inum = lfdir; 18364236Smckusick if ((dp = ginode()) != NULL) { 18374236Smckusick dp->di_nlink++; 18384236Smckusick inodirty(); 18394236Smckusick setlncnt(getlncnt()+1); 18404236Smckusick } 18414236Smckusick inum = orphan; 18424236Smckusick pwarn("DIR I=%u CONNECTED. ", orphan); 18434236Smckusick printf("PARENT WAS I=%u\n", pdir); 18444236Smckusick if (preen == 0) 18454236Smckusick printf("\n"); 18464236Smckusick } 18474236Smckusick return (1); 18484236Smckusick } 18494236Smckusick 18504236Smckusick bread(fcp, buf, blk, size) 18514236Smckusick daddr_t blk; 18524236Smckusick register struct filecntl *fcp; 18534236Smckusick register size; 18544236Smckusick char *buf; 18554236Smckusick { 18565325Smckusic if (lseek(fcp->rfdes, blk * DEV_BSIZE, 0) < 0) 18574236Smckusick rwerr("SEEK", blk); 18584236Smckusick else if (read(fcp->rfdes, buf, size) == size) 18594236Smckusick return (1); 18604236Smckusick rwerr("READ", blk); 18614236Smckusick return (0); 18624236Smckusick } 18634236Smckusick 18644236Smckusick bwrite(fcp, buf, blk, size) 18654236Smckusick daddr_t blk; 18664236Smckusick register struct filecntl *fcp; 18674236Smckusick register size; 18684236Smckusick char *buf; 18694236Smckusick { 18704236Smckusick 18714236Smckusick if (fcp->wfdes < 0) 18724236Smckusick return (0); 18735325Smckusic if (lseek(fcp->wfdes, blk * DEV_BSIZE, 0) < 0) 18744236Smckusick rwerr("SEEK", blk); 18754236Smckusick else if (write(fcp->wfdes, buf, size) == size) { 18764236Smckusick fcp->mod = 1; 18774236Smckusick return (1); 18784236Smckusick } 18794236Smckusick rwerr("WRITE", blk); 18804236Smckusick return (0); 18814236Smckusick } 18824236Smckusick 18834236Smckusick catch() 18844236Smckusick { 18854236Smckusick 18864236Smckusick ckfini(); 18874236Smckusick exit(12); 18884236Smckusick } 18895325Smckusic 18905325Smckusic /* 18915325Smckusic * block operations 18925325Smckusic */ 18935325Smckusic 18945325Smckusic isblock(fs, cp, h) 18955325Smckusic struct fs *fs; 18965325Smckusic unsigned char *cp; 18975325Smckusic int h; 18985325Smckusic { 18995325Smckusic unsigned char mask; 19005325Smckusic 19015325Smckusic switch (fs->fs_frag) { 19025325Smckusic case 8: 19035325Smckusic return (cp[h] == 0xff); 19045325Smckusic case 4: 19055325Smckusic mask = 0x0f << ((h & 0x1) << 2); 19065325Smckusic return ((cp[h >> 1] & mask) == mask); 19075325Smckusic case 2: 19085325Smckusic mask = 0x03 << ((h & 0x3) << 1); 19095325Smckusic return ((cp[h >> 2] & mask) == mask); 19105325Smckusic case 1: 19115325Smckusic mask = 0x01 << (h & 0x7); 19125325Smckusic return ((cp[h >> 3] & mask) == mask); 19135325Smckusic default: 19145381Smckusic error("isblock bad fs_frag %d\n", fs->fs_frag); 19155381Smckusic return (0); 19165325Smckusic } 19175325Smckusic } 19186489Smckusick 19196489Smckusick /* tables.c 4.1 82/03/25 */ 19206489Smckusick 19216489Smckusick /* merged into kernel: tables.c 2.1 3/25/82 */ 19226489Smckusick 19236489Smckusick /* last monet version: partab.c 4.2 81/03/08 */ 19246489Smckusick 19256489Smckusick /* 19266489Smckusick * bit patterns for identifying fragments in the block map 19276489Smckusick * used as ((map & around) == inside) 19286489Smckusick */ 19296489Smckusick int around[9] = { 19306489Smckusick 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff 19316489Smckusick }; 19326489Smckusick int inside[9] = { 19336489Smckusick 0x0, 0x2, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe 19346489Smckusick }; 19356489Smckusick 19366489Smckusick /* 19376489Smckusick * given a block map bit pattern, the frag tables tell whether a 19386489Smckusick * particular size fragment is available. 19396489Smckusick * 19406489Smckusick * used as: 19416489Smckusick * if ((1 << (size - 1)) & fragtbl[fs->fs_frag][map] { 19426489Smckusick * at least one fragment of the indicated size is available 19436489Smckusick * } 19446489Smckusick * 19456489Smckusick * These tables are used by the scanc instruction on the VAX to 19466489Smckusick * quickly find an appropriate fragment. 19476489Smckusick */ 19486489Smckusick 19496489Smckusick unsigned char fragtbl124[256] = { 19506489Smckusick 0x00, 0x16, 0x16, 0x2a, 0x16, 0x16, 0x26, 0x4e, 19516489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x2a, 0x3e, 0x4e, 0x8a, 19526489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 19536489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 19546489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 19556489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 19566489Smckusick 0x2a, 0x3e, 0x3e, 0x2a, 0x3e, 0x3e, 0x2e, 0x6e, 19576489Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x2a, 0x3e, 0x6e, 0xaa, 19586489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 19596489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 19606489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 19616489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 19626489Smckusick 0x26, 0x36, 0x36, 0x2e, 0x36, 0x36, 0x26, 0x6e, 19636489Smckusick 0x36, 0x36, 0x36, 0x3e, 0x2e, 0x3e, 0x6e, 0xae, 19646489Smckusick 0x4e, 0x5e, 0x5e, 0x6e, 0x5e, 0x5e, 0x6e, 0x4e, 19656489Smckusick 0x5e, 0x5e, 0x5e, 0x7e, 0x6e, 0x7e, 0x4e, 0xce, 19666489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 19676489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 19686489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 19696489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 19706489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 19716489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 19726489Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 19736489Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 0xbe, 19746489Smckusick 0x2a, 0x3e, 0x3e, 0x2a, 0x3e, 0x3e, 0x2e, 0x6e, 19756489Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x2a, 0x3e, 0x6e, 0xaa, 19766489Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 19776489Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 0xbe, 19786489Smckusick 0x4e, 0x5e, 0x5e, 0x6e, 0x5e, 0x5e, 0x6e, 0x4e, 19796489Smckusick 0x5e, 0x5e, 0x5e, 0x7e, 0x6e, 0x7e, 0x4e, 0xce, 19806489Smckusick 0x8a, 0x9e, 0x9e, 0xaa, 0x9e, 0x9e, 0xae, 0xce, 19816489Smckusick 0x9e, 0x9e, 0x9e, 0xbe, 0xaa, 0xbe, 0xce, 0x8a, 19826489Smckusick }; 19836489Smckusick 19846489Smckusick unsigned char fragtbl8[256] = { 19856489Smckusick 0x00, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x04, 19866489Smckusick 0x01, 0x01, 0x01, 0x03, 0x02, 0x03, 0x04, 0x08, 19876489Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 19886489Smckusick 0x02, 0x03, 0x03, 0x02, 0x04, 0x05, 0x08, 0x10, 19896489Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 19906489Smckusick 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 19916489Smckusick 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, 19926489Smckusick 0x04, 0x05, 0x05, 0x06, 0x08, 0x09, 0x10, 0x20, 19936489Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 19946489Smckusick 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 19956489Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 19966489Smckusick 0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11, 19976489Smckusick 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, 19986489Smckusick 0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0a, 19996489Smckusick 0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04, 20006489Smckusick 0x08, 0x09, 0x09, 0x0a, 0x10, 0x11, 0x20, 0x40, 20016489Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 20026489Smckusick 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 20036489Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 20046489Smckusick 0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11, 20056489Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 20066489Smckusick 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 20076489Smckusick 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07, 20086489Smckusick 0x05, 0x05, 0x05, 0x07, 0x09, 0x09, 0x11, 0x21, 20096489Smckusick 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, 20106489Smckusick 0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0a, 20116489Smckusick 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07, 20126489Smckusick 0x02, 0x03, 0x03, 0x02, 0x06, 0x07, 0x0a, 0x12, 20136489Smckusick 0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04, 20146489Smckusick 0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x04, 0x0c, 20156489Smckusick 0x08, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x0a, 0x0c, 20166489Smckusick 0x10, 0x11, 0x11, 0x12, 0x20, 0x21, 0x40, 0x80, 20176489Smckusick }; 20186489Smckusick 20196489Smckusick /* 20206489Smckusick * the actual fragtbl array 20216489Smckusick */ 20226489Smckusick unsigned char *fragtbl[MAXFRAG + 1] = { 20236489Smckusick 0, fragtbl124, fragtbl124, 0, fragtbl124, 0, 0, 0, fragtbl8, 20246489Smckusick }; 2025