|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: */ ! 6: ! 7: #ifndef lint ! 8: static char sccsid[] = "@(#)inode.c 5.2 (Berkeley) 7/17/85"; ! 9: #endif not lint ! 10: ! 11: #include <pwd.h> ! 12: #include <sys/param.h> ! 13: #include <sys/inode.h> ! 14: #include <sys/fs.h> ! 15: #include <sys/dir.h> ! 16: #include "fsck.h" ! 17: ! 18: ckinode(dp, idesc) ! 19: DINODE *dp; ! 20: register struct inodesc *idesc; ! 21: { ! 22: register daddr_t *ap; ! 23: int ret, n, ndb, offset; ! 24: DINODE dino; ! 25: ! 26: idesc->id_fix = DONTKNOW; ! 27: idesc->id_entryno = 0; ! 28: idesc->id_filesize = dp->di_size; ! 29: if (SPECIAL(dp)) ! 30: return (KEEPON); ! 31: dino = *dp; ! 32: ndb = howmany(dino.di_size, sblock.fs_bsize); ! 33: for (ap = &dino.di_db[0]; ap < &dino.di_db[NDADDR]; ap++) { ! 34: if (--ndb == 0 && (offset = blkoff(&sblock, dino.di_size)) != 0) ! 35: idesc->id_numfrags = ! 36: numfrags(&sblock, fragroundup(&sblock, offset)); ! 37: else ! 38: idesc->id_numfrags = sblock.fs_frag; ! 39: if (*ap == 0) ! 40: continue; ! 41: idesc->id_blkno = *ap; ! 42: if (idesc->id_type == ADDR) ! 43: ret = (*idesc->id_func)(idesc); ! 44: else ! 45: ret = dirscan(idesc); ! 46: if (ret & STOP) ! 47: return (ret); ! 48: } ! 49: idesc->id_numfrags = sblock.fs_frag; ! 50: for (ap = &dino.di_ib[0], n = 1; n <= NIADDR; ap++, n++) { ! 51: if (*ap) { ! 52: idesc->id_blkno = *ap; ! 53: ret = iblock(idesc, n, ! 54: dino.di_size - sblock.fs_bsize * NDADDR); ! 55: if (ret & STOP) ! 56: return (ret); ! 57: } ! 58: } ! 59: return (KEEPON); ! 60: } ! 61: ! 62: iblock(idesc, ilevel, isize) ! 63: struct inodesc *idesc; ! 64: register ilevel; ! 65: long isize; ! 66: { ! 67: register daddr_t *ap; ! 68: register daddr_t *aplim; ! 69: int i, n, (*func)(), nif, sizepb; ! 70: BUFAREA ib; ! 71: char buf[BUFSIZ]; ! 72: extern int pass1check(); ! 73: ! 74: if (idesc->id_type == ADDR) { ! 75: func = idesc->id_func; ! 76: if (((n = (*func)(idesc)) & KEEPON) == 0) ! 77: return (n); ! 78: } else ! 79: func = dirscan; ! 80: if (outrange(idesc->id_blkno, idesc->id_numfrags)) /* protect thyself */ ! 81: return (SKIP); ! 82: initbarea(&ib); ! 83: getblk(&ib, idesc->id_blkno, sblock.fs_bsize); ! 84: if (ib.b_errs != NULL) ! 85: return (SKIP); ! 86: ilevel--; ! 87: for (sizepb = sblock.fs_bsize, i = 0; i < ilevel; i++) ! 88: sizepb *= NINDIR(&sblock); ! 89: nif = isize / sizepb + 1; ! 90: if (nif > NINDIR(&sblock)) ! 91: nif = NINDIR(&sblock); ! 92: if (idesc->id_func == pass1check && nif < NINDIR(&sblock)) { ! 93: aplim = &ib.b_un.b_indir[NINDIR(&sblock)]; ! 94: for (ap = &ib.b_un.b_indir[nif]; ap < aplim; ap++) { ! 95: if (*ap == 0) ! 96: continue; ! 97: sprintf(buf, "PARTIALLY TRUNCATED INODE I=%d", ! 98: idesc->id_number); ! 99: if (dofix(idesc, buf)) { ! 100: *ap = 0; ! 101: dirty(&ib); ! 102: } ! 103: } ! 104: flush(&dfile, &ib); ! 105: } ! 106: aplim = &ib.b_un.b_indir[nif]; ! 107: for (ap = ib.b_un.b_indir, i = 1; ap < aplim; ap++, i++) ! 108: if (*ap) { ! 109: idesc->id_blkno = *ap; ! 110: if (ilevel > 0) ! 111: n = iblock(idesc, ilevel, isize - i * sizepb); ! 112: else ! 113: n = (*func)(idesc); ! 114: if (n & STOP) ! 115: return (n); ! 116: } ! 117: return (KEEPON); ! 118: } ! 119: ! 120: outrange(blk, cnt) ! 121: daddr_t blk; ! 122: int cnt; ! 123: { ! 124: register int c; ! 125: ! 126: if ((unsigned)(blk+cnt) > fmax) ! 127: return (1); ! 128: c = dtog(&sblock, blk); ! 129: if (blk < cgdmin(&sblock, c)) { ! 130: if ((blk+cnt) > cgsblock(&sblock, c)) { ! 131: if (debug) { ! 132: printf("blk %d < cgdmin %d;", ! 133: blk, cgdmin(&sblock, c)); ! 134: printf(" blk+cnt %d > cgsbase %d\n", ! 135: blk+cnt, cgsblock(&sblock, c)); ! 136: } ! 137: return (1); ! 138: } ! 139: } else { ! 140: if ((blk+cnt) > cgbase(&sblock, c+1)) { ! 141: if (debug) { ! 142: printf("blk %d >= cgdmin %d;", ! 143: blk, cgdmin(&sblock, c)); ! 144: printf(" blk+cnt %d > sblock.fs_fpg %d\n", ! 145: blk+cnt, sblock.fs_fpg); ! 146: } ! 147: return (1); ! 148: } ! 149: } ! 150: return (0); ! 151: } ! 152: ! 153: DINODE * ! 154: ginode(inumber) ! 155: ino_t inumber; ! 156: { ! 157: daddr_t iblk; ! 158: static ino_t startinum = 0; /* blk num of first in raw area */ ! 159: ! 160: if (inumber < ROOTINO || inumber > imax) ! 161: errexit("bad inode number %d to ginode\n", inumber); ! 162: if (startinum == 0 || ! 163: inumber < startinum || inumber >= startinum + INOPB(&sblock)) { ! 164: iblk = itod(&sblock, inumber); ! 165: getblk(&inoblk, iblk, sblock.fs_bsize); ! 166: startinum = (inumber / INOPB(&sblock)) * INOPB(&sblock); ! 167: } ! 168: return (&inoblk.b_un.b_dinode[inumber % INOPB(&sblock)]); ! 169: } ! 170: ! 171: clri(idesc, s, flg) ! 172: register struct inodesc *idesc; ! 173: char *s; ! 174: int flg; ! 175: { ! 176: register DINODE *dp; ! 177: ! 178: dp = ginode(idesc->id_number); ! 179: if (flg == 1) { ! 180: pwarn("%s %s", s, DIRCT(dp) ? "DIR" : "FILE"); ! 181: pinode(idesc->id_number); ! 182: } ! 183: if (preen || reply("CLEAR") == 1) { ! 184: if (preen) ! 185: printf(" (CLEARED)\n"); ! 186: n_files--; ! 187: (void)ckinode(dp, idesc); ! 188: zapino(dp); ! 189: statemap[idesc->id_number] = USTATE; ! 190: inodirty(); ! 191: } ! 192: } ! 193: ! 194: findname(idesc) ! 195: struct inodesc *idesc; ! 196: { ! 197: register DIRECT *dirp = idesc->id_dirp; ! 198: ! 199: if (dirp->d_ino != idesc->id_parent) ! 200: return (KEEPON); ! 201: bcopy(dirp->d_name, idesc->id_name, dirp->d_namlen + 1); ! 202: return (STOP); ! 203: } ! 204: ! 205: findino(idesc) ! 206: struct inodesc *idesc; ! 207: { ! 208: register DIRECT *dirp = idesc->id_dirp; ! 209: ! 210: if (dirp->d_ino == 0) ! 211: return (KEEPON); ! 212: if (strcmp(dirp->d_name, idesc->id_name) == 0 && ! 213: dirp->d_ino >= ROOTINO && dirp->d_ino <= imax) { ! 214: idesc->id_parent = dirp->d_ino; ! 215: return (STOP); ! 216: } ! 217: return (KEEPON); ! 218: } ! 219: ! 220: pinode(ino) ! 221: ino_t ino; ! 222: { ! 223: register DINODE *dp; ! 224: register char *p; ! 225: struct passwd *pw; ! 226: char *ctime(); ! 227: ! 228: printf(" I=%u ", ino); ! 229: if (ino < ROOTINO || ino > imax) ! 230: return; ! 231: dp = ginode(ino); ! 232: printf(" OWNER="); ! 233: if ((pw = getpwuid((int)dp->di_uid)) != 0) ! 234: printf("%s ", pw->pw_name); ! 235: else ! 236: printf("%d ", dp->di_uid); ! 237: printf("MODE=%o\n", dp->di_mode); ! 238: if (preen) ! 239: printf("%s: ", devname); ! 240: printf("SIZE=%ld ", dp->di_size); ! 241: p = ctime(&dp->di_mtime); ! 242: printf("MTIME=%12.12s %4.4s ", p+4, p+20); ! 243: } ! 244: ! 245: blkerr(ino, s, blk) ! 246: ino_t ino; ! 247: char *s; ! 248: daddr_t blk; ! 249: { ! 250: ! 251: pfatal("%ld %s I=%u", blk, s, ino); ! 252: printf("\n"); ! 253: switch (statemap[ino]) { ! 254: ! 255: case FSTATE: ! 256: statemap[ino] = FCLEAR; ! 257: return; ! 258: ! 259: case DSTATE: ! 260: statemap[ino] = DCLEAR; ! 261: return; ! 262: ! 263: case FCLEAR: ! 264: case DCLEAR: ! 265: return; ! 266: ! 267: default: ! 268: errexit("BAD STATE %d TO BLKERR", statemap[ino]); ! 269: /* NOTREACHED */ ! 270: } ! 271: } ! 272: ! 273: /* ! 274: * allocate an unused inode ! 275: */ ! 276: ino_t ! 277: allocino(request, type) ! 278: ino_t request; ! 279: int type; ! 280: { ! 281: register ino_t ino; ! 282: register DINODE *dp; ! 283: ! 284: if (request == 0) ! 285: request = ROOTINO; ! 286: else if (statemap[request] != USTATE) ! 287: return (0); ! 288: for (ino = request; ino < imax; ino++) ! 289: if (statemap[ino] == USTATE) ! 290: break; ! 291: if (ino == imax) ! 292: return (0); ! 293: switch (type & IFMT) { ! 294: case IFDIR: ! 295: statemap[ino] = DSTATE; ! 296: break; ! 297: case IFREG: ! 298: case IFLNK: ! 299: statemap[ino] = FSTATE; ! 300: break; ! 301: default: ! 302: return (0); ! 303: } ! 304: dp = ginode(ino); ! 305: dp->di_db[0] = allocblk(1); ! 306: if (dp->di_db[0] == 0) { ! 307: statemap[ino] = USTATE; ! 308: return (0); ! 309: } ! 310: dp->di_mode = type; ! 311: time(&dp->di_atime); ! 312: dp->di_mtime = dp->di_ctime = dp->di_atime; ! 313: dp->di_size = sblock.fs_fsize; ! 314: dp->di_blocks = btodb(sblock.fs_fsize); ! 315: n_files++; ! 316: inodirty(); ! 317: return (ino); ! 318: } ! 319: ! 320: /* ! 321: * deallocate an inode ! 322: */ ! 323: freeino(ino) ! 324: ino_t ino; ! 325: { ! 326: struct inodesc idesc; ! 327: extern int pass4check(); ! 328: DINODE *dp; ! 329: ! 330: bzero((char *)&idesc, sizeof(struct inodesc)); ! 331: idesc.id_type = ADDR; ! 332: idesc.id_func = pass4check; ! 333: idesc.id_number = ino; ! 334: dp = ginode(ino); ! 335: (void)ckinode(dp, &idesc); ! 336: zapino(dp); ! 337: inodirty(); ! 338: statemap[ino] = USTATE; ! 339: n_files--; ! 340: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.