xref: /csrg-svn/sbin/fsck/inode.c (revision 17930)
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