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