|
|
1.1 ! root 1: /* ! 2: * Perform initialization for phases of fsck ! 3: */ ! 4: #include "fsck.h" ! 5: #include <mnttab.h> ! 6: #include <mtab.h> ! 7: ! 8: int fsfd; /* file system file descriptor */ ! 9: int writeflg; /* write ok or read-only flag */ ! 10: daddr_t fsize = SUPERI+1; /* file system size in blocks */ ! 11: /* Allows for read of Super Block */ ! 12: int isize; /* First block not in inode list */ ! 13: daddr_t totfree; /* Running total free block count */ ! 14: unsigned ninodes; /* number of inodes */ ! 15: int numfiles; /* number of files in file system */ ! 16: ! 17: char superb[BSIZE]; /* Super Block */ ! 18: struct filsys *sbp = superb; ! 19: int sbpfix; /* flag for super block fixes */ ! 20: ! 21: int offsets[] = /* table of offsets for the levels */ ! 22: { ND, ND+NI, ND+NI+NII, /* of indirection of blocks in the */ ! 23: ND+NI+NII+NIII }; /* inode block list */ ! 24: ! 25: daddr_t dupblck[DUPTBLSIZE]; /* duplicate referenced blocks */ ! 26: int totdups; /* number of dup blocks so far */ ! 27: ! 28: /* ! 29: * A small aside is the fact that the link counter table allocates an ! 30: * unsigned short if !SMALLMODEL, but is in fact only an unsigned char ! 31: * if SMALLMODEL. As a result, we cannot currently fsck correctly a ! 32: * filesystem with any inode having more than 255 links if SMALLMODEL. ! 33: * The reason for this is that the virtual system is heavily designed ! 34: * to work with byte sized tables, and that's that for now! Anyway, ! 35: * everybody has a 386 by now! ! 36: */ ! 37: ! 38: #if !SMALLMODEL ! 39: unsigned short *linkPtr; ! 40: unsigned char *flagptr, *blockPtr, *dupPtr; ! 41: #endif ! 42: ! 43: init() ! 44: { ! 45: int mode; ! 46: struct stat status; ! 47: unsigned short stmode; ! 48: ! 49: mode = (mdaction == NO) ? 0 : 2; ! 50: ! 51: if ( (fsfd = open(fsname, mode)) == (-1) ) { ! 52: mode = 0; ! 53: if ( (fsfd = open(fsname, mode)) == (-1) ) { ! 54: nonfatal("Can't open: %s", fsname); ! 55: return; ! 56: } ! 57: } ! 58: ! 59: if (mode == 0) { ! 60: daction = NO; ! 61: writeflg = FALSE; ! 62: } else { ! 63: daction = mdaction; ! 64: writeflg = TRUE; ! 65: } ! 66: ! 67: printf("%s: %s\n", fsname, (mode == 0) ? "(NO WRITE)" : ""); ! 68: ! 69: if ( fstat(fsfd, &status) == (-1) ) { ! 70: nonfatal("Can't stat: %s", fsname); ! 71: return; ! 72: } ! 73: ! 74: stmode = status.st_mode & S_IFMT; ! 75: if ( (stmode != S_IFBLK) && (stmode != S_IFCHR) ) ! 76: switch(query("file is not a block or character device; OK?")){ ! 77: case YES: ! 78: break; ! 79: case NO: ! 80: errflag = TRUE; ! 81: return; ! 82: } ! 83: ! 84: domount(); ! 85: sbpfix = FALSE; ! 86: readsuper(); ! 87: checksuper(); ! 88: if ( !errflag ) ! 89: alloctables(); ! 90: } ! 91: ! 92: /* ! 93: * Read in the super block and canonicalize ! 94: */ ! 95: ! 96: readsuper() ! 97: { ! 98: register int i; ! 99: ! 100: bread((daddr_t)SUPERI, superb); ! 101: sbp = superb; ! 102: ! 103: canshort(sbp->s_isize); ! 104: candaddr(sbp->s_fsize); ! 105: canshort(sbp->s_nfree); ! 106: for(i=0; i<NICFREE; i++) ! 107: candaddr(sbp->s_free[i]); ! 108: canshort(sbp->s_ninode); ! 109: for(i=0; i<NICINOD; i++) ! 110: canino(sbp->s_inode[i]); ! 111: cantime(sbp->s_time); ! 112: candaddr(sbp->s_tfree); ! 113: canino(sbp->s_tinode); ! 114: canshort(sbp->s_m); ! 115: canshort(sbp->s_n); ! 116: canlong(sbp->s_unique); ! 117: ! 118: } ! 119: ! 120: /* ! 121: * Check super block for obvious inconsistencies ! 122: */ ! 123: ! 124: checksuper() ! 125: { ! 126: fsize = sbp->s_fsize; ! 127: isize = sbp->s_isize; ! 128: totfree = fsize - isize; ! 129: ! 130: if ( (isize<=INODEI) || (isize>=fsize) || (fsize<=INODEI) ) { ! 131: badsuper("Size check: fsize %U isize %u", fsize, isize); ! 132: errflag = TRUE; ! 133: } ! 134: ! 135: if ( sbp->s_nfree > NICFREE ) ! 136: badsuper("Too large free block count"); ! 137: ! 138: if ( sbp->s_ninode > NICINOD ) ! 139: badsuper("Too large free i-node count"); ! 140: } ! 141: ! 142: /* ! 143: * Super Block Error Functions ! 144: */ ! 145: badsuper(x) ! 146: { ! 147: printf("%r\n", &x); ! 148: printf("fsck: %s: Bad Super Block: %u\n", fsname, SUPERI); ! 149: } ! 150: ! 151: /* ! 152: * Allocate the necessary buffers for tables ! 153: */ ! 154: alloctables() ! 155: { ! 156: unsigned num, numl; ! 157: ! 158: numl = 0; ! 159: if (!fflag) { ! 160: ninodes = (unsigned) (isize - INODEI) * INOPB; ! 161: numl = (unsigned) ninodes; ! 162: } ! 163: ! 164: num = (unsigned) ((fsize+NBPC-1)/NBPC) * sizeof(char); ! 165: #if SMALLMODEL ! 166: initV(numl, numl, num, num); /* virtual allocation */ ! 167: #else ! 168: if (NULL != linkPtr) { ! 169: free(linkPtr); ! 170: free(flagPtr); ! 171: free(blockPtr); ! 172: free(dupPtr); ! 173: } ! 174: linkPtr = calloc(numl, sizeof(unsigned short)); ! 175: flagPtr = calloc(numl, sizeof(unsigned char)); ! 176: blockPtr = calloc(num, sizeof(unsigned char)); ! 177: dupPtr = calloc(num, sizeof(unsigned char)); ! 178: #endif ! 179: numfiles = /* number of files in the file system */ ! 180: totdups = 0; /* num dup blocks */ ! 181: } ! 182: ! 183: /* ! 184: * domount() checks the files /etc/mnttab and /etc/mtab to find ! 185: * out where the file system is mounted (if at all). It then ! 186: * reports where (and when if possible) it was last mounted. ! 187: */ ! 188: char *mnttab_name = "/etc/mnttab"; ! 189: char *mtab_name = "/etc/mtab"; ! 190: char *bttime_name = "/etc/boottime"; ! 191: ! 192: domount() ! 193: { ! 194: int fd; ! 195: struct mnttab mnttab; ! 196: struct mtab mtab; ! 197: register char *name; ! 198: struct stat sbuf; ! 199: time_t boottime; ! 200: int nothing(); ! 201: char devname[MNTNSIZ+6] = "/dev/"; ! 202: ! 203: mounted = FALSE; ! 204: name = fsname; /* strip off all initial */ ! 205: while (*name++ != '\0') ; /* directories in fsname */ ! 206: while ( (*--name != '/') && (name>fsname) ) ; ! 207: if (*name == '/') name++; ! 208: ! 209: if ( stat(bttime_name, &sbuf) == -1 ) ! 210: boottime = (time_t)0; ! 211: else ! 212: boottime = sbuf.st_mtime; ! 213: ! 214: if ( (fd=open(mnttab_name, 0)) != (-1) ) { ! 215: while ( read(fd, &mnttab, sizeof(mnttab))==sizeof(mnttab) ) ! 216: if ( mnttab.mt_dev[0] && mnttab.mt_filsys[0] ) { ! 217: strncpy(&devname[5], mnttab.mt_filsys, MNTNSIZ); ! 218: devname[MNTNSIZ+5] = '\0'; ! 219: statit(devname, nothing); ! 220: if (stats.st_rdev != fsysrdev) ! 221: continue; ! 222: statit(mnttab.mt_dev, nothing); ! 223: mounted = (stats.st_dev == fsysrdev); ! 224: prmnttab(&mnttab, boottime); ! 225: return; ! 226: } ! 227: } ! 228: if ( (fd=open(mtab_name, 0)) != (-1) ) { ! 229: while ( read(fd, &mtab, sizeof(mtab))==sizeof(mtab) ) ! 230: if ( mtab.mt_name[0] && mtab.mt_special[0] ) { ! 231: strncpy(&devname[5], mtab.mt_special, MNAMSIZ); ! 232: devname[MNAMSIZ+5] = '\0'; ! 233: statit(devname, nothing); ! 234: if (stats.st_rdev != fsysrdev) ! 235: continue; ! 236: statit(mtab.mt_name, nothing); ! 237: mounted = (stats.st_dev == fsysrdev); ! 238: prmtab(&mtab); ! 239: return; ! 240: } ! 241: } ! 242: ! 243: if (fsysrdev == rootdev) ! 244: mounted = TRUE; ! 245: else ! 246: mounted = FALSE; ! 247: ! 248: } ! 249: ! 250: prmnttab(ptr, boottime) ! 251: struct mnttab *ptr; ! 252: time_t boottime; ! 253: { ! 254: if (mounted) { ! 255: if (boottime < ptr->mt_time) ! 256: boottime = ptr->mt_time; ! 257: printf("%s mounted on %.*s as of %s", fsname, MNTNSIZ, ! 258: ptr->mt_dev, ctime(&boottime)); ! 259: } else ! 260: printf("%s unmounted. Last mounted on %.*s -- %s", ! 261: fsname, MNTNSIZ, ptr->mt_dev, ! 262: ctime(&ptr->mt_time)); ! 263: } ! 264: ! 265: ! 266: prmtab(ptr) ! 267: struct mtab *ptr; ! 268: { ! 269: if (mounted) ! 270: printf("%s mounted on %.*s\n", fsname, MNAMSIZ, ptr->mt_name); ! 271: else ! 272: printf("%s unmounted. Last mounted on %.*s\n", fsname, ! 273: MNAMSIZ, ptr->mt_name); ! 274: } ! 275: ! 276: nothing() ! 277: {}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.