xref: /csrg-svn/sbin/fsck/inode.c (revision 44934)
122046Sdist /*
239976Smckusick  * Copyright (c) 1980, 1986 The Regents of the University of California.
339976Smckusick  * All rights reserved.
439976Smckusick  *
542701Sbostic  * %sccs.include.redist.c%
622046Sdist  */
722046Sdist 
816261Smckusick #ifndef lint
9*44934Smckusick static char sccsid[] = "@(#)inode.c	5.16 (Berkeley) 07/20/90";
1039976Smckusick #endif /* not lint */
1116261Smckusick 
1216261Smckusick #include <sys/param.h>
1339383Smckusick #include <ufs/dinode.h>
1438336Smckusick #include <ufs/fs.h>
1538336Smckusick #include <ufs/dir.h>
1636963Sbostic #include <pwd.h>
17*44934Smckusick #include <stdlib.h>
18*44934Smckusick #include <string.h>
1916261Smckusick #include "fsck.h"
2016261Smckusick 
2140647Smckusick static ino_t startinum;
2234225Smckusick 
2316261Smckusick ckinode(dp, idesc)
2439973Smckusick 	struct dinode *dp;
2516261Smckusick 	register struct inodesc *idesc;
2616261Smckusick {
2716261Smckusick 	register daddr_t *ap;
2839973Smckusick 	long ret, n, ndb, offset;
2939973Smckusick 	struct dinode dino;
3016261Smckusick 
3118000Smckusick 	idesc->id_fix = DONTKNOW;
3218000Smckusick 	idesc->id_entryno = 0;
3318000Smckusick 	idesc->id_filesize = dp->di_size;
3439973Smckusick 	if ((dp->di_mode & IFMT) == IFBLK || (dp->di_mode & IFMT) == IFCHR)
3516261Smckusick 		return (KEEPON);
3616261Smckusick 	dino = *dp;
3716261Smckusick 	ndb = howmany(dino.di_size, sblock.fs_bsize);
3816261Smckusick 	for (ap = &dino.di_db[0]; ap < &dino.di_db[NDADDR]; ap++) {
3916261Smckusick 		if (--ndb == 0 && (offset = blkoff(&sblock, dino.di_size)) != 0)
4016261Smckusick 			idesc->id_numfrags =
4116261Smckusick 				numfrags(&sblock, fragroundup(&sblock, offset));
4216261Smckusick 		else
4316261Smckusick 			idesc->id_numfrags = sblock.fs_frag;
4416261Smckusick 		if (*ap == 0)
4516261Smckusick 			continue;
4616261Smckusick 		idesc->id_blkno = *ap;
4716261Smckusick 		if (idesc->id_type == ADDR)
4816261Smckusick 			ret = (*idesc->id_func)(idesc);
4916261Smckusick 		else
5016261Smckusick 			ret = dirscan(idesc);
5116261Smckusick 		if (ret & STOP)
5216261Smckusick 			return (ret);
5316261Smckusick 	}
5416261Smckusick 	idesc->id_numfrags = sblock.fs_frag;
5517930Smckusick 	for (ap = &dino.di_ib[0], n = 1; n <= NIADDR; ap++, n++) {
5616261Smckusick 		if (*ap) {
5716261Smckusick 			idesc->id_blkno = *ap;
5816261Smckusick 			ret = iblock(idesc, n,
5916261Smckusick 				dino.di_size - sblock.fs_bsize * NDADDR);
6016261Smckusick 			if (ret & STOP)
6116261Smckusick 				return (ret);
6216261Smckusick 		}
6316261Smckusick 	}
6416261Smckusick 	return (KEEPON);
6516261Smckusick }
6616261Smckusick 
6716261Smckusick iblock(idesc, ilevel, isize)
6816261Smckusick 	struct inodesc *idesc;
6939973Smckusick 	register long ilevel;
70*44934Smckusick 	u_long isize;
7116261Smckusick {
7216261Smckusick 	register daddr_t *ap;
7316261Smckusick 	register daddr_t *aplim;
7417930Smckusick 	int i, n, (*func)(), nif, sizepb;
7539973Smckusick 	register struct bufarea *bp;
7623876Smckusick 	char buf[BUFSIZ];
7733083Sbostic 	extern int dirscan(), pass1check();
7816261Smckusick 
7916261Smckusick 	if (idesc->id_type == ADDR) {
8016261Smckusick 		func = idesc->id_func;
8116261Smckusick 		if (((n = (*func)(idesc)) & KEEPON) == 0)
8216261Smckusick 			return (n);
8316261Smckusick 	} else
8416261Smckusick 		func = dirscan;
8539973Smckusick 	if (chkrange(idesc->id_blkno, idesc->id_numfrags))
8616261Smckusick 		return (SKIP);
8734225Smckusick 	bp = getdatablk(idesc->id_blkno, sblock.fs_bsize);
8816261Smckusick 	ilevel--;
8917930Smckusick 	for (sizepb = sblock.fs_bsize, i = 0; i < ilevel; i++)
9017930Smckusick 		sizepb *= NINDIR(&sblock);
9117930Smckusick 	nif = isize / sizepb + 1;
9216261Smckusick 	if (nif > NINDIR(&sblock))
9316261Smckusick 		nif = NINDIR(&sblock);
9417950Smckusick 	if (idesc->id_func == pass1check && nif < NINDIR(&sblock)) {
9534225Smckusick 		aplim = &bp->b_un.b_indir[NINDIR(&sblock)];
9634225Smckusick 		for (ap = &bp->b_un.b_indir[nif]; ap < aplim; ap++) {
9717950Smckusick 			if (*ap == 0)
9817950Smckusick 				continue;
99*44934Smckusick 			(void)sprintf(buf, "PARTIALLY TRUNCATED INODE I=%lu",
10023876Smckusick 				idesc->id_number);
10123876Smckusick 			if (dofix(idesc, buf)) {
10217950Smckusick 				*ap = 0;
10334225Smckusick 				dirty(bp);
10417950Smckusick 			}
10517950Smckusick 		}
10639973Smckusick 		flush(fswritefd, bp);
10717950Smckusick 	}
10834225Smckusick 	aplim = &bp->b_un.b_indir[nif];
10934225Smckusick 	for (ap = bp->b_un.b_indir, i = 1; ap < aplim; ap++, i++) {
11016261Smckusick 		if (*ap) {
11116261Smckusick 			idesc->id_blkno = *ap;
11216261Smckusick 			if (ilevel > 0)
11317930Smckusick 				n = iblock(idesc, ilevel, isize - i * sizepb);
11416261Smckusick 			else
11516261Smckusick 				n = (*func)(idesc);
11634225Smckusick 			if (n & STOP) {
11734225Smckusick 				bp->b_flags &= ~B_INUSE;
11816261Smckusick 				return (n);
11934225Smckusick 			}
12016261Smckusick 		}
12134225Smckusick 	}
12234225Smckusick 	bp->b_flags &= ~B_INUSE;
12316261Smckusick 	return (KEEPON);
12416261Smckusick }
12516261Smckusick 
12639973Smckusick /*
12739973Smckusick  * Check that a block in a legal block number.
12839973Smckusick  * Return 0 if in range, 1 if out of range.
12939973Smckusick  */
13039973Smckusick chkrange(blk, cnt)
13116261Smckusick 	daddr_t blk;
13216261Smckusick 	int cnt;
13316261Smckusick {
13416261Smckusick 	register int c;
13516261Smckusick 
13639973Smckusick 	if ((unsigned)(blk + cnt) > maxfsblock)
13716261Smckusick 		return (1);
13816261Smckusick 	c = dtog(&sblock, blk);
13916261Smckusick 	if (blk < cgdmin(&sblock, c)) {
14039973Smckusick 		if ((blk + cnt) > cgsblock(&sblock, c)) {
14116261Smckusick 			if (debug) {
142*44934Smckusick 				printf("blk %ld < cgdmin %ld;",
14316261Smckusick 				    blk, cgdmin(&sblock, c));
144*44934Smckusick 				printf(" blk + cnt %ld > cgsbase %ld\n",
14539973Smckusick 				    blk + cnt, cgsblock(&sblock, c));
14616261Smckusick 			}
14716261Smckusick 			return (1);
14816261Smckusick 		}
14916261Smckusick 	} else {
15039973Smckusick 		if ((blk + cnt) > cgbase(&sblock, c+1)) {
15116261Smckusick 			if (debug)  {
152*44934Smckusick 				printf("blk %ld >= cgdmin %ld;",
15316261Smckusick 				    blk, cgdmin(&sblock, c));
154*44934Smckusick 				printf(" blk + cnt %ld > sblock.fs_fpg %ld\n",
15516261Smckusick 				    blk+cnt, sblock.fs_fpg);
15616261Smckusick 			}
15716261Smckusick 			return (1);
15816261Smckusick 		}
15916261Smckusick 	}
16016261Smckusick 	return (0);
16116261Smckusick }
16216261Smckusick 
16340024Smckusick /*
16440024Smckusick  * General purpose interface for reading inodes.
16540024Smckusick  */
16639973Smckusick struct dinode *
16716261Smckusick ginode(inumber)
16816261Smckusick 	ino_t inumber;
16916261Smckusick {
17016261Smckusick 	daddr_t iblk;
17116261Smckusick 
17239973Smckusick 	if (inumber < ROOTINO || inumber > maxino)
17317943Smckusick 		errexit("bad inode number %d to ginode\n", inumber);
17416261Smckusick 	if (startinum == 0 ||
17516261Smckusick 	    inumber < startinum || inumber >= startinum + INOPB(&sblock)) {
17616261Smckusick 		iblk = itod(&sblock, inumber);
17734225Smckusick 		if (pbp != 0)
17834225Smckusick 			pbp->b_flags &= ~B_INUSE;
17934225Smckusick 		pbp = getdatablk(iblk, sblock.fs_bsize);
18016261Smckusick 		startinum = (inumber / INOPB(&sblock)) * INOPB(&sblock);
18116261Smckusick 	}
18234225Smckusick 	return (&pbp->b_un.b_dinode[inumber % INOPB(&sblock)]);
18316261Smckusick }
18416261Smckusick 
18540024Smckusick /*
18640024Smckusick  * Special purpose version of ginode used to optimize first pass
18740024Smckusick  * over all the inodes in numerical order.
18840024Smckusick  */
18940024Smckusick ino_t nextino, lastinum;
19040024Smckusick long readcnt, readpercg, fullcnt, inobufsize, partialcnt, partialsize;
19140024Smckusick struct dinode *inodebuf;
19240024Smckusick 
19340024Smckusick struct dinode *
19440024Smckusick getnextinode(inumber)
19540024Smckusick 	ino_t inumber;
19640024Smckusick {
19740024Smckusick 	long size;
19840024Smckusick 	daddr_t dblk;
19940024Smckusick 	static struct dinode *dp;
20040024Smckusick 
20140024Smckusick 	if (inumber != nextino++ || inumber > maxino)
20240024Smckusick 		errexit("bad inode number %d to nextinode\n", inumber);
20340024Smckusick 	if (inumber >= lastinum) {
20440024Smckusick 		readcnt++;
20540024Smckusick 		dblk = fsbtodb(&sblock, itod(&sblock, lastinum));
20640024Smckusick 		if (readcnt % readpercg == 0) {
20740024Smckusick 			size = partialsize;
20840024Smckusick 			lastinum += partialcnt;
20940024Smckusick 		} else {
21040024Smckusick 			size = inobufsize;
21140024Smckusick 			lastinum += fullcnt;
21240024Smckusick 		}
213*44934Smckusick 		(void)bread(fsreadfd, (char *)inodebuf, dblk, size); /* ??? */
21440024Smckusick 		dp = inodebuf;
21540024Smckusick 	}
21640024Smckusick 	return (dp++);
21740024Smckusick }
21840024Smckusick 
21940024Smckusick resetinodebuf()
22040024Smckusick {
22140024Smckusick 
22240647Smckusick 	startinum = 0;
22340024Smckusick 	nextino = 0;
22440024Smckusick 	lastinum = 0;
22540024Smckusick 	readcnt = 0;
22640024Smckusick 	inobufsize = blkroundup(&sblock, INOBUFSIZE);
22740024Smckusick 	fullcnt = inobufsize / sizeof(struct dinode);
22840024Smckusick 	readpercg = sblock.fs_ipg / fullcnt;
22940024Smckusick 	partialcnt = sblock.fs_ipg % fullcnt;
23040024Smckusick 	partialsize = partialcnt * sizeof(struct dinode);
23140024Smckusick 	if (partialcnt != 0) {
23240024Smckusick 		readpercg++;
23340024Smckusick 	} else {
23440024Smckusick 		partialcnt = fullcnt;
23540024Smckusick 		partialsize = inobufsize;
23640024Smckusick 	}
23740024Smckusick 	if (inodebuf == NULL &&
23840024Smckusick 	    (inodebuf = (struct dinode *)malloc((unsigned)inobufsize)) == NULL)
23940024Smckusick 		errexit("Cannot allocate space for inode buffer\n");
24040024Smckusick 	while (nextino < ROOTINO)
241*44934Smckusick 		(void)getnextinode(nextino);
24240024Smckusick }
24340024Smckusick 
24440024Smckusick freeinodebuf()
24540024Smckusick {
24640024Smckusick 
24740024Smckusick 	if (inodebuf != NULL)
24840024Smckusick 		free((char *)inodebuf);
24940024Smckusick 	inodebuf = NULL;
25040024Smckusick }
25140024Smckusick 
25240024Smckusick /*
25340024Smckusick  * Routines to maintain information about directory inodes.
25440024Smckusick  * This is built during the first pass and used during the
25540024Smckusick  * second and third passes.
25640024Smckusick  *
25740024Smckusick  * Enter inodes into the cache.
25840024Smckusick  */
25939980Smckusick cacheino(dp, inumber)
26039980Smckusick 	register struct dinode *dp;
26139980Smckusick 	ino_t inumber;
26239980Smckusick {
26339980Smckusick 	register struct inoinfo *inp;
26439980Smckusick 	struct inoinfo **inpp;
26539980Smckusick 	unsigned int blks;
26639980Smckusick 
26739980Smckusick 	blks = howmany(dp->di_size, sblock.fs_bsize);
26839980Smckusick 	if (blks > NDADDR)
26939980Smckusick 		blks = NDADDR + NIADDR;
27039980Smckusick 	inp = (struct inoinfo *)
27139980Smckusick 		malloc(sizeof(*inp) + (blks - 1) * sizeof(daddr_t));
27239980Smckusick 	if (inp == NULL)
27339980Smckusick 		return;
27440024Smckusick 	inpp = &inphead[inumber % numdirs];
27540024Smckusick 	inp->i_nexthash = *inpp;
27639980Smckusick 	*inpp = inp;
27740024Smckusick 	inp->i_parent = (ino_t)0;
27840024Smckusick 	inp->i_dotdot = (ino_t)0;
27939980Smckusick 	inp->i_number = inumber;
28040024Smckusick 	inp->i_isize = dp->di_size;
28139980Smckusick 	inp->i_numblks = blks * sizeof(daddr_t);
28240024Smckusick 	bcopy((char *)&dp->di_db[0], (char *)&inp->i_blks[0],
283*44934Smckusick 	    (size_t)inp->i_numblks);
28440024Smckusick 	if (inplast == listmax) {
28540024Smckusick 		listmax += 100;
28640024Smckusick 		inpsort = (struct inoinfo **)realloc((char *)inpsort,
28740024Smckusick 		    (unsigned)listmax * sizeof(struct inoinfo *));
28840024Smckusick 		if (inpsort == NULL)
28940024Smckusick 			errexit("cannot increase directory list");
29040024Smckusick 	}
29140024Smckusick 	inpsort[inplast++] = inp;
29239980Smckusick }
29339980Smckusick 
29440024Smckusick /*
29540024Smckusick  * Look up an inode cache structure.
29640024Smckusick  */
29740024Smckusick struct inoinfo *
29840024Smckusick getinoinfo(inumber)
29939980Smckusick 	ino_t inumber;
30039980Smckusick {
30139980Smckusick 	register struct inoinfo *inp;
30239980Smckusick 
30340024Smckusick 	for (inp = inphead[inumber % numdirs]; inp; inp = inp->i_nexthash) {
30439980Smckusick 		if (inp->i_number != inumber)
30539980Smckusick 			continue;
30640024Smckusick 		return (inp);
30739980Smckusick 	}
30840024Smckusick 	errexit("cannot find inode %d\n", inumber);
30940024Smckusick 	return ((struct inoinfo *)0);
31039980Smckusick }
31139980Smckusick 
31240024Smckusick /*
31340024Smckusick  * Clean up all the inode cache structure.
31440024Smckusick  */
31539980Smckusick inocleanup()
31639980Smckusick {
31740024Smckusick 	register struct inoinfo **inpp;
31839980Smckusick 
31939980Smckusick 	if (inphead == NULL)
32039980Smckusick 		return;
32140024Smckusick 	for (inpp = &inpsort[inplast - 1]; inpp >= inpsort; inpp--)
32240024Smckusick 		free((char *)(*inpp));
32340024Smckusick 	free((char *)inphead);
32440024Smckusick 	free((char *)inpsort);
32540024Smckusick 	inphead = inpsort = NULL;
32639980Smckusick }
32739980Smckusick 
32834225Smckusick inodirty()
32934225Smckusick {
33034225Smckusick 
33134225Smckusick 	dirty(pbp);
33234225Smckusick }
33334225Smckusick 
33439973Smckusick clri(idesc, type, flag)
33516261Smckusick 	register struct inodesc *idesc;
33639973Smckusick 	char *type;
33739973Smckusick 	int flag;
33816261Smckusick {
33939973Smckusick 	register struct dinode *dp;
34016261Smckusick 
34117943Smckusick 	dp = ginode(idesc->id_number);
34239973Smckusick 	if (flag == 1) {
34339973Smckusick 		pwarn("%s %s", type,
34439973Smckusick 		    (dp->di_mode & IFMT) == IFDIR ? "DIR" : "FILE");
34516261Smckusick 		pinode(idesc->id_number);
34616261Smckusick 	}
34716261Smckusick 	if (preen || reply("CLEAR") == 1) {
34816261Smckusick 		if (preen)
34916261Smckusick 			printf(" (CLEARED)\n");
35016261Smckusick 		n_files--;
35116261Smckusick 		(void)ckinode(dp, idesc);
35239973Smckusick 		clearinode(dp);
35316261Smckusick 		statemap[idesc->id_number] = USTATE;
35416261Smckusick 		inodirty();
35516261Smckusick 	}
35616261Smckusick }
35716261Smckusick 
35817991Smckusick findname(idesc)
35917991Smckusick 	struct inodesc *idesc;
36017991Smckusick {
36139973Smckusick 	register struct direct *dirp = idesc->id_dirp;
36217991Smckusick 
36317991Smckusick 	if (dirp->d_ino != idesc->id_parent)
36417991Smckusick 		return (KEEPON);
365*44934Smckusick 	bcopy(dirp->d_name, idesc->id_name, (size_t)dirp->d_namlen + 1);
36630354Smckusick 	return (STOP|FOUND);
36717991Smckusick }
36817991Smckusick 
36916261Smckusick findino(idesc)
37016261Smckusick 	struct inodesc *idesc;
37116261Smckusick {
37239973Smckusick 	register struct direct *dirp = idesc->id_dirp;
37316261Smckusick 
37416261Smckusick 	if (dirp->d_ino == 0)
37516261Smckusick 		return (KEEPON);
37617991Smckusick 	if (strcmp(dirp->d_name, idesc->id_name) == 0 &&
37739973Smckusick 	    dirp->d_ino >= ROOTINO && dirp->d_ino <= maxino) {
37817991Smckusick 		idesc->id_parent = dirp->d_ino;
37930354Smckusick 		return (STOP|FOUND);
38016261Smckusick 	}
38116261Smckusick 	return (KEEPON);
38216261Smckusick }
38316261Smckusick 
38416261Smckusick pinode(ino)
38516261Smckusick 	ino_t ino;
38616261Smckusick {
38739973Smckusick 	register struct dinode *dp;
38816261Smckusick 	register char *p;
38918102Smckusick 	struct passwd *pw;
39016261Smckusick 	char *ctime();
39116261Smckusick 
392*44934Smckusick 	printf(" I=%lu ", ino);
39339973Smckusick 	if (ino < ROOTINO || ino > maxino)
39416261Smckusick 		return;
39517943Smckusick 	dp = ginode(ino);
39616261Smckusick 	printf(" OWNER=");
39718102Smckusick 	if ((pw = getpwuid((int)dp->di_uid)) != 0)
39818102Smckusick 		printf("%s ", pw->pw_name);
39918102Smckusick 	else
400*44934Smckusick 		printf("%u ", (unsigned)dp->di_uid);
40116261Smckusick 	printf("MODE=%o\n", dp->di_mode);
40216261Smckusick 	if (preen)
40316261Smckusick 		printf("%s: ", devname);
404*44934Smckusick 	printf("SIZE=%lu ", dp->di_size);
40516261Smckusick 	p = ctime(&dp->di_mtime);
40639973Smckusick 	printf("MTIME=%12.12s %4.4s ", p + 4, p + 20);
40716261Smckusick }
40816261Smckusick 
40939973Smckusick blkerror(ino, type, blk)
41016261Smckusick 	ino_t ino;
41139973Smckusick 	char *type;
41216261Smckusick 	daddr_t blk;
41316261Smckusick {
41416261Smckusick 
415*44934Smckusick 	pfatal("%ld %s I=%lu", blk, type, ino);
41616261Smckusick 	printf("\n");
41717936Smckusick 	switch (statemap[ino]) {
41817936Smckusick 
41917936Smckusick 	case FSTATE:
42017936Smckusick 		statemap[ino] = FCLEAR;
42117936Smckusick 		return;
42217936Smckusick 
42317936Smckusick 	case DSTATE:
42417936Smckusick 		statemap[ino] = DCLEAR;
42517936Smckusick 		return;
42617936Smckusick 
42717936Smckusick 	case FCLEAR:
42817936Smckusick 	case DCLEAR:
42917936Smckusick 		return;
43017936Smckusick 
43117936Smckusick 	default:
43217936Smckusick 		errexit("BAD STATE %d TO BLKERR", statemap[ino]);
43317936Smckusick 		/* NOTREACHED */
43417936Smckusick 	}
43516261Smckusick }
43617955Smckusick 
43717955Smckusick /*
43817955Smckusick  * allocate an unused inode
43917955Smckusick  */
44017955Smckusick ino_t
44117955Smckusick allocino(request, type)
44217955Smckusick 	ino_t request;
44317955Smckusick 	int type;
44417955Smckusick {
44517955Smckusick 	register ino_t ino;
44639973Smckusick 	register struct dinode *dp;
44717955Smckusick 
44817955Smckusick 	if (request == 0)
44917955Smckusick 		request = ROOTINO;
45017955Smckusick 	else if (statemap[request] != USTATE)
45117955Smckusick 		return (0);
45239973Smckusick 	for (ino = request; ino < maxino; ino++)
45317955Smckusick 		if (statemap[ino] == USTATE)
45417955Smckusick 			break;
45539973Smckusick 	if (ino == maxino)
45617955Smckusick 		return (0);
45717955Smckusick 	switch (type & IFMT) {
45817955Smckusick 	case IFDIR:
45917955Smckusick 		statemap[ino] = DSTATE;
46017955Smckusick 		break;
46117955Smckusick 	case IFREG:
46217955Smckusick 	case IFLNK:
46317955Smckusick 		statemap[ino] = FSTATE;
46417955Smckusick 		break;
46517955Smckusick 	default:
46617955Smckusick 		return (0);
46717955Smckusick 	}
46817955Smckusick 	dp = ginode(ino);
46939973Smckusick 	dp->di_db[0] = allocblk((long)1);
47017955Smckusick 	if (dp->di_db[0] == 0) {
47117955Smckusick 		statemap[ino] = USTATE;
47217955Smckusick 		return (0);
47317955Smckusick 	}
47417955Smckusick 	dp->di_mode = type;
475*44934Smckusick 	(void)time(&dp->di_atime);
47617955Smckusick 	dp->di_mtime = dp->di_ctime = dp->di_atime;
47717955Smckusick 	dp->di_size = sblock.fs_fsize;
47817955Smckusick 	dp->di_blocks = btodb(sblock.fs_fsize);
47917955Smckusick 	n_files++;
48017955Smckusick 	inodirty();
48117955Smckusick 	return (ino);
48217955Smckusick }
48317955Smckusick 
48417955Smckusick /*
48517955Smckusick  * deallocate an inode
48617955Smckusick  */
48717955Smckusick freeino(ino)
48817955Smckusick 	ino_t ino;
48917955Smckusick {
49017955Smckusick 	struct inodesc idesc;
49117955Smckusick 	extern int pass4check();
49239973Smckusick 	struct dinode *dp;
49317955Smckusick 
49417955Smckusick 	bzero((char *)&idesc, sizeof(struct inodesc));
49517955Smckusick 	idesc.id_type = ADDR;
49617955Smckusick 	idesc.id_func = pass4check;
49717955Smckusick 	idesc.id_number = ino;
49817955Smckusick 	dp = ginode(ino);
49917955Smckusick 	(void)ckinode(dp, &idesc);
50039973Smckusick 	clearinode(dp);
50117955Smckusick 	inodirty();
50217955Smckusick 	statemap[ino] = USTATE;
50317955Smckusick 	n_files--;
50417955Smckusick }
505