116261Smckusick #ifndef lint 2*17930Smckusick static char version[] = "@(#)inode.c 3.2 (Berkeley) 02/07/85"; 316261Smckusick #endif 416261Smckusick 516261Smckusick #include <sys/param.h> 616261Smckusick #include <sys/inode.h> 716261Smckusick #include <sys/fs.h> 816261Smckusick #include <sys/dir.h> 916261Smckusick #include "fsck.h" 1016261Smckusick 1116261Smckusick ckinode(dp, idesc) 1216261Smckusick DINODE *dp; 1316261Smckusick register struct inodesc *idesc; 1416261Smckusick { 1516261Smckusick register daddr_t *ap; 1616261Smckusick int ret, n, ndb, offset; 1716261Smckusick DINODE dino; 1816261Smckusick 19*17930Smckusick if (SPECIAL(dp)) 2016261Smckusick return (KEEPON); 2116261Smckusick dino = *dp; 2216261Smckusick idesc->id_fix = DONTKNOW; 2316261Smckusick idesc->id_entryno = 0; 2416261Smckusick ndb = howmany(dino.di_size, sblock.fs_bsize); 2516261Smckusick for (ap = &dino.di_db[0]; ap < &dino.di_db[NDADDR]; ap++) { 2616261Smckusick if (--ndb == 0 && (offset = blkoff(&sblock, dino.di_size)) != 0) 2716261Smckusick idesc->id_numfrags = 2816261Smckusick numfrags(&sblock, fragroundup(&sblock, offset)); 2916261Smckusick else 3016261Smckusick idesc->id_numfrags = sblock.fs_frag; 3116261Smckusick if (*ap == 0) 3216261Smckusick continue; 3316261Smckusick idesc->id_blkno = *ap; 3416261Smckusick if (idesc->id_type == ADDR) 3516261Smckusick ret = (*idesc->id_func)(idesc); 3616261Smckusick else 3716261Smckusick ret = dirscan(idesc); 3816261Smckusick if (ret & STOP) 3916261Smckusick return (ret); 4016261Smckusick } 4116261Smckusick idesc->id_numfrags = sblock.fs_frag; 42*17930Smckusick for (ap = &dino.di_ib[0], n = 1; n <= NIADDR; ap++, n++) { 4316261Smckusick if (*ap) { 4416261Smckusick idesc->id_blkno = *ap; 4516261Smckusick ret = iblock(idesc, n, 4616261Smckusick dino.di_size - sblock.fs_bsize * NDADDR); 4716261Smckusick if (ret & STOP) 4816261Smckusick return (ret); 4916261Smckusick } 5016261Smckusick } 5116261Smckusick return (KEEPON); 5216261Smckusick } 5316261Smckusick 5416261Smckusick iblock(idesc, ilevel, isize) 5516261Smckusick struct inodesc *idesc; 5616261Smckusick register ilevel; 5716261Smckusick long isize; 5816261Smckusick { 5916261Smckusick register daddr_t *ap; 6016261Smckusick register daddr_t *aplim; 61*17930Smckusick int i, n, (*func)(), nif, sizepb; 6216261Smckusick BUFAREA ib; 6316261Smckusick 6416261Smckusick if (idesc->id_type == ADDR) { 6516261Smckusick func = idesc->id_func; 6616261Smckusick if (((n = (*func)(idesc)) & KEEPON) == 0) 6716261Smckusick return (n); 6816261Smckusick } else 6916261Smckusick func = dirscan; 7016261Smckusick if (outrange(idesc->id_blkno, idesc->id_numfrags)) /* protect thyself */ 7116261Smckusick return (SKIP); 7216261Smckusick initbarea(&ib); 7316261Smckusick if (getblk(&ib, idesc->id_blkno, sblock.fs_bsize) == NULL) 7416261Smckusick return (SKIP); 7516261Smckusick ilevel--; 76*17930Smckusick for (sizepb = sblock.fs_bsize, i = 0; i < ilevel; i++) 77*17930Smckusick sizepb *= NINDIR(&sblock); 78*17930Smckusick nif = isize / sizepb + 1; 7916261Smckusick if (nif > NINDIR(&sblock)) 8016261Smckusick nif = NINDIR(&sblock); 8116261Smckusick aplim = &ib.b_un.b_indir[nif]; 8216261Smckusick for (ap = ib.b_un.b_indir, i = 1; ap < aplim; ap++, i++) 8316261Smckusick if (*ap) { 8416261Smckusick idesc->id_blkno = *ap; 8516261Smckusick if (ilevel > 0) 86*17930Smckusick n = iblock(idesc, ilevel, isize - i * sizepb); 8716261Smckusick else 8816261Smckusick n = (*func)(idesc); 8916261Smckusick if (n & STOP) 9016261Smckusick return (n); 9116261Smckusick } 9216261Smckusick return (KEEPON); 9316261Smckusick } 9416261Smckusick 9516261Smckusick outrange(blk, cnt) 9616261Smckusick daddr_t blk; 9716261Smckusick int cnt; 9816261Smckusick { 9916261Smckusick register int c; 10016261Smckusick 10116261Smckusick if ((unsigned)(blk+cnt) > fmax) 10216261Smckusick return (1); 10316261Smckusick c = dtog(&sblock, blk); 10416261Smckusick if (blk < cgdmin(&sblock, c)) { 10516261Smckusick if ((blk+cnt) > cgsblock(&sblock, c)) { 10616261Smckusick if (debug) { 10716261Smckusick printf("blk %d < cgdmin %d;", 10816261Smckusick blk, cgdmin(&sblock, c)); 10916261Smckusick printf(" blk+cnt %d > cgsbase %d\n", 11016261Smckusick blk+cnt, cgsblock(&sblock, c)); 11116261Smckusick } 11216261Smckusick return (1); 11316261Smckusick } 11416261Smckusick } else { 11516261Smckusick if ((blk+cnt) > cgbase(&sblock, c+1)) { 11616261Smckusick if (debug) { 11716261Smckusick printf("blk %d >= cgdmin %d;", 11816261Smckusick blk, cgdmin(&sblock, c)); 11916261Smckusick printf(" blk+cnt %d > sblock.fs_fpg %d\n", 12016261Smckusick blk+cnt, sblock.fs_fpg); 12116261Smckusick } 12216261Smckusick return (1); 12316261Smckusick } 12416261Smckusick } 12516261Smckusick return (0); 12616261Smckusick } 12716261Smckusick 12816261Smckusick DINODE * 12916261Smckusick ginode(inumber) 13016261Smckusick ino_t inumber; 13116261Smckusick { 13216261Smckusick daddr_t iblk; 13316261Smckusick static ino_t startinum = 0; /* blk num of first in raw area */ 13416261Smckusick 13516261Smckusick 13616261Smckusick if (inumber < ROOTINO || inumber > imax) { 13716261Smckusick if (debug && inumber > imax) 13816261Smckusick printf("inumber out of range (%d)\n", inumber); 13916261Smckusick return (NULL); 14016261Smckusick } 14116261Smckusick if (startinum == 0 || 14216261Smckusick inumber < startinum || inumber >= startinum + INOPB(&sblock)) { 14316261Smckusick iblk = itod(&sblock, inumber); 14416261Smckusick if (getblk(&inoblk, iblk, sblock.fs_bsize) == NULL) { 14516261Smckusick return (NULL); 14616261Smckusick } 14716261Smckusick startinum = (inumber / INOPB(&sblock)) * INOPB(&sblock); 14816261Smckusick } 14916261Smckusick return (&inoblk.b_un.b_dinode[inumber % INOPB(&sblock)]); 15016261Smckusick } 15116261Smckusick 15216261Smckusick clri(idesc, s, flg) 15316261Smckusick register struct inodesc *idesc; 15416261Smckusick char *s; 15516261Smckusick int flg; 15616261Smckusick { 15716261Smckusick register DINODE *dp; 15816261Smckusick 15916261Smckusick if ((dp = ginode(idesc->id_number)) == NULL) 16016261Smckusick return; 16116261Smckusick if (flg == 1) { 162*17930Smckusick pwarn("%s %s", s, DIRCT(dp) ? "DIR" : "FILE"); 16316261Smckusick pinode(idesc->id_number); 16416261Smckusick } 16516261Smckusick if (preen || reply("CLEAR") == 1) { 16616261Smckusick if (preen) 16716261Smckusick printf(" (CLEARED)\n"); 16816261Smckusick n_files--; 16916261Smckusick (void)ckinode(dp, idesc); 17016261Smckusick zapino(dp); 17116261Smckusick statemap[idesc->id_number] = USTATE; 17216261Smckusick inodirty(); 17316261Smckusick inosumbad++; 17416261Smckusick } 17516261Smckusick } 17616261Smckusick 17716261Smckusick findino(idesc) 17816261Smckusick struct inodesc *idesc; 17916261Smckusick { 18016261Smckusick register DIRECT *dirp = idesc->id_dirp; 18116261Smckusick 18216261Smckusick if (dirp->d_ino == 0) 18316261Smckusick return (KEEPON); 184*17930Smckusick if (!strcmp(dirp->d_name, idesc->id_name)) { 18516261Smckusick if (dirp->d_ino >= ROOTINO && dirp->d_ino <= imax) 18616261Smckusick idesc->id_parent = dirp->d_ino; 18716261Smckusick return (STOP); 18816261Smckusick } 18916261Smckusick return (KEEPON); 19016261Smckusick } 19116261Smckusick 19216261Smckusick pinode(ino) 19316261Smckusick ino_t ino; 19416261Smckusick { 19516261Smckusick register DINODE *dp; 19616261Smckusick register char *p; 19716261Smckusick char uidbuf[BUFSIZ]; 19816261Smckusick char *ctime(); 19916261Smckusick 20016261Smckusick printf(" I=%u ", ino); 20116261Smckusick if ((dp = ginode(ino)) == NULL) 20216261Smckusick return; 20316261Smckusick printf(" OWNER="); 20416261Smckusick if (getpw((int)dp->di_uid, uidbuf) == 0) { 20516261Smckusick for (p = uidbuf; *p != ':'; p++); 20616261Smckusick *p = 0; 20716261Smckusick printf("%s ", uidbuf); 20816261Smckusick } 20916261Smckusick else { 21016261Smckusick printf("%d ", dp->di_uid); 21116261Smckusick } 21216261Smckusick printf("MODE=%o\n", dp->di_mode); 21316261Smckusick if (preen) 21416261Smckusick printf("%s: ", devname); 21516261Smckusick printf("SIZE=%ld ", dp->di_size); 21616261Smckusick p = ctime(&dp->di_mtime); 21716261Smckusick printf("MTIME=%12.12s %4.4s ", p+4, p+20); 21816261Smckusick } 21916261Smckusick 22016261Smckusick blkerr(ino, s, blk) 22116261Smckusick ino_t ino; 22216261Smckusick char *s; 22316261Smckusick daddr_t blk; 22416261Smckusick { 22516261Smckusick 22616261Smckusick pfatal("%ld %s I=%u", blk, s, ino); 22716261Smckusick printf("\n"); 22816261Smckusick statemap[ino] = CLEAR; 22916261Smckusick } 230