xref: /csrg-svn/sbin/fsck/inode.c (revision 66898)
122046Sdist /*
261492Sbostic  * Copyright (c) 1980, 1986, 1993
361492Sbostic  *	The Regents of the University of California.  All rights reserved.
439976Smckusick  *
542701Sbostic  * %sccs.include.redist.c%
622046Sdist  */
722046Sdist 
816261Smckusick #ifndef lint
9*66898Smckusick static char sccsid[] = "@(#)inode.c	8.4 (Berkeley) 04/18/94";
1039976Smckusick #endif /* not lint */
1116261Smckusick 
1216261Smckusick #include <sys/param.h>
1353821Smckusick #include <sys/time.h>
1451532Sbostic #include <ufs/ufs/dinode.h>
1551532Sbostic #include <ufs/ufs/dir.h>
1651532Sbostic #include <ufs/ffs/fs.h>
1736963Sbostic #include <pwd.h>
1844934Smckusick #include <stdlib.h>
1944934Smckusick #include <string.h>
2016261Smckusick #include "fsck.h"
2116261Smckusick 
2240647Smckusick static ino_t startinum;
2334225Smckusick 
2416261Smckusick ckinode(dp, idesc)
2539973Smckusick 	struct dinode *dp;
2616261Smckusick 	register struct inodesc *idesc;
2716261Smckusick {
2816261Smckusick 	register daddr_t *ap;
2939973Smckusick 	long ret, n, ndb, offset;
3039973Smckusick 	struct dinode dino;
3153825Smckusick 	quad_t remsize, sizepb;
3254599Smckusick 	mode_t mode;
3316261Smckusick 
3444998Smckusick 	if (idesc->id_fix != IGNORE)
3544998Smckusick 		idesc->id_fix = DONTKNOW;
3618000Smckusick 	idesc->id_entryno = 0;
3718000Smckusick 	idesc->id_filesize = dp->di_size;
3854599Smckusick 	mode = dp->di_mode & IFMT;
3954599Smckusick 	if (mode == IFBLK || mode == IFCHR || (mode == IFLNK &&
4054599Smckusick 	    dp->di_size < sblock.fs_maxsymlinklen))
4116261Smckusick 		return (KEEPON);
4216261Smckusick 	dino = *dp;
4316261Smckusick 	ndb = howmany(dino.di_size, sblock.fs_bsize);
4416261Smckusick 	for (ap = &dino.di_db[0]; ap < &dino.di_db[NDADDR]; ap++) {
4516261Smckusick 		if (--ndb == 0 && (offset = blkoff(&sblock, dino.di_size)) != 0)
4616261Smckusick 			idesc->id_numfrags =
4716261Smckusick 				numfrags(&sblock, fragroundup(&sblock, offset));
4816261Smckusick 		else
4916261Smckusick 			idesc->id_numfrags = sblock.fs_frag;
5016261Smckusick 		if (*ap == 0)
5116261Smckusick 			continue;
5216261Smckusick 		idesc->id_blkno = *ap;
5316261Smckusick 		if (idesc->id_type == ADDR)
5416261Smckusick 			ret = (*idesc->id_func)(idesc);
5516261Smckusick 		else
5616261Smckusick 			ret = dirscan(idesc);
5716261Smckusick 		if (ret & STOP)
5816261Smckusick 			return (ret);
5916261Smckusick 	}
6016261Smckusick 	idesc->id_numfrags = sblock.fs_frag;
6153825Smckusick 	remsize = dino.di_size - sblock.fs_bsize * NDADDR;
6253825Smckusick 	sizepb = sblock.fs_bsize;
6317930Smckusick 	for (ap = &dino.di_ib[0], n = 1; n <= NIADDR; ap++, n++) {
6416261Smckusick 		if (*ap) {
6516261Smckusick 			idesc->id_blkno = *ap;
6653825Smckusick 			ret = iblock(idesc, n, remsize);
6716261Smckusick 			if (ret & STOP)
6816261Smckusick 				return (ret);
6916261Smckusick 		}
7053825Smckusick 		sizepb *= NINDIR(&sblock);
7153825Smckusick 		remsize -= sizepb;
7216261Smckusick 	}
7316261Smckusick 	return (KEEPON);
7416261Smckusick }
7516261Smckusick 
7616261Smckusick iblock(idesc, ilevel, isize)
7716261Smckusick 	struct inodesc *idesc;
7853825Smckusick 	long ilevel;
7952983Smckusick 	quad_t isize;
8016261Smckusick {
8116261Smckusick 	register daddr_t *ap;
8216261Smckusick 	register daddr_t *aplim;
8339973Smckusick 	register struct bufarea *bp;
8453821Smckusick 	int i, n, (*func)(), nif;
8553821Smckusick 	quad_t sizepb;
8623876Smckusick 	char buf[BUFSIZ];
8733083Sbostic 	extern int dirscan(), pass1check();
8816261Smckusick 
8916261Smckusick 	if (idesc->id_type == ADDR) {
9016261Smckusick 		func = idesc->id_func;
9116261Smckusick 		if (((n = (*func)(idesc)) & KEEPON) == 0)
9216261Smckusick 			return (n);
9316261Smckusick 	} else
9416261Smckusick 		func = dirscan;
9539973Smckusick 	if (chkrange(idesc->id_blkno, idesc->id_numfrags))
9616261Smckusick 		return (SKIP);
9734225Smckusick 	bp = getdatablk(idesc->id_blkno, sblock.fs_bsize);
9816261Smckusick 	ilevel--;
9917930Smckusick 	for (sizepb = sblock.fs_bsize, i = 0; i < ilevel; i++)
10017930Smckusick 		sizepb *= NINDIR(&sblock);
10153825Smckusick 	nif = howmany(isize , sizepb);
10216261Smckusick 	if (nif > NINDIR(&sblock))
10316261Smckusick 		nif = NINDIR(&sblock);
10417950Smckusick 	if (idesc->id_func == pass1check && nif < NINDIR(&sblock)) {
10534225Smckusick 		aplim = &bp->b_un.b_indir[NINDIR(&sblock)];
10634225Smckusick 		for (ap = &bp->b_un.b_indir[nif]; ap < aplim; ap++) {
10717950Smckusick 			if (*ap == 0)
10817950Smckusick 				continue;
10944934Smckusick 			(void)sprintf(buf, "PARTIALLY TRUNCATED INODE I=%lu",
11023876Smckusick 				idesc->id_number);
11123876Smckusick 			if (dofix(idesc, buf)) {
11217950Smckusick 				*ap = 0;
11334225Smckusick 				dirty(bp);
11417950Smckusick 			}
11517950Smckusick 		}
11639973Smckusick 		flush(fswritefd, bp);
11717950Smckusick 	}
11834225Smckusick 	aplim = &bp->b_un.b_indir[nif];
11953825Smckusick 	for (ap = bp->b_un.b_indir; ap < aplim; ap++) {
12016261Smckusick 		if (*ap) {
12116261Smckusick 			idesc->id_blkno = *ap;
122*66898Smckusick 			if (ilevel == 0)
12316261Smckusick 				n = (*func)(idesc);
124*66898Smckusick 			else
12553825Smckusick 				n = iblock(idesc, ilevel, isize);
12634225Smckusick 			if (n & STOP) {
12734225Smckusick 				bp->b_flags &= ~B_INUSE;
12816261Smckusick 				return (n);
12934225Smckusick 			}
13016261Smckusick 		}
131*66898Smckusick 		isize -= sizepb;
13234225Smckusick 	}
13334225Smckusick 	bp->b_flags &= ~B_INUSE;
13416261Smckusick 	return (KEEPON);
13516261Smckusick }
13616261Smckusick 
13739973Smckusick /*
13839973Smckusick  * Check that a block in a legal block number.
13939973Smckusick  * Return 0 if in range, 1 if out of range.
14039973Smckusick  */
14139973Smckusick chkrange(blk, cnt)
14216261Smckusick 	daddr_t blk;
14316261Smckusick 	int cnt;
14416261Smckusick {
14516261Smckusick 	register int c;
14616261Smckusick 
14739973Smckusick 	if ((unsigned)(blk + cnt) > maxfsblock)
14816261Smckusick 		return (1);
14916261Smckusick 	c = dtog(&sblock, blk);
15016261Smckusick 	if (blk < cgdmin(&sblock, c)) {
15139973Smckusick 		if ((blk + cnt) > cgsblock(&sblock, c)) {
15216261Smckusick 			if (debug) {
15344934Smckusick 				printf("blk %ld < cgdmin %ld;",
15416261Smckusick 				    blk, cgdmin(&sblock, c));
15544934Smckusick 				printf(" blk + cnt %ld > cgsbase %ld\n",
15639973Smckusick 				    blk + cnt, cgsblock(&sblock, c));
15716261Smckusick 			}
15816261Smckusick 			return (1);
15916261Smckusick 		}
16016261Smckusick 	} else {
16139973Smckusick 		if ((blk + cnt) > cgbase(&sblock, c+1)) {
16216261Smckusick 			if (debug)  {
16344934Smckusick 				printf("blk %ld >= cgdmin %ld;",
16416261Smckusick 				    blk, cgdmin(&sblock, c));
16544934Smckusick 				printf(" blk + cnt %ld > sblock.fs_fpg %ld\n",
16616261Smckusick 				    blk+cnt, sblock.fs_fpg);
16716261Smckusick 			}
16816261Smckusick 			return (1);
16916261Smckusick 		}
17016261Smckusick 	}
17116261Smckusick 	return (0);
17216261Smckusick }
17316261Smckusick 
17440024Smckusick /*
17540024Smckusick  * General purpose interface for reading inodes.
17640024Smckusick  */
17739973Smckusick struct dinode *
17816261Smckusick ginode(inumber)
17916261Smckusick 	ino_t inumber;
18016261Smckusick {
18116261Smckusick 	daddr_t iblk;
18216261Smckusick 
18339973Smckusick 	if (inumber < ROOTINO || inumber > maxino)
18417943Smckusick 		errexit("bad inode number %d to ginode\n", inumber);
18516261Smckusick 	if (startinum == 0 ||
18616261Smckusick 	    inumber < startinum || inumber >= startinum + INOPB(&sblock)) {
18764639Sbostic 		iblk = ino_to_fsba(&sblock, inumber);
18834225Smckusick 		if (pbp != 0)
18934225Smckusick 			pbp->b_flags &= ~B_INUSE;
19034225Smckusick 		pbp = getdatablk(iblk, sblock.fs_bsize);
19116261Smckusick 		startinum = (inumber / INOPB(&sblock)) * INOPB(&sblock);
19216261Smckusick 	}
19334225Smckusick 	return (&pbp->b_un.b_dinode[inumber % INOPB(&sblock)]);
19416261Smckusick }
19516261Smckusick 
19640024Smckusick /*
19740024Smckusick  * Special purpose version of ginode used to optimize first pass
19840024Smckusick  * over all the inodes in numerical order.
19940024Smckusick  */
20040024Smckusick ino_t nextino, lastinum;
20140024Smckusick long readcnt, readpercg, fullcnt, inobufsize, partialcnt, partialsize;
20240024Smckusick struct dinode *inodebuf;
20340024Smckusick 
20440024Smckusick struct dinode *
20540024Smckusick getnextinode(inumber)
20640024Smckusick 	ino_t inumber;
20740024Smckusick {
20840024Smckusick 	long size;
20940024Smckusick 	daddr_t dblk;
21040024Smckusick 	static struct dinode *dp;
21140024Smckusick 
21240024Smckusick 	if (inumber != nextino++ || inumber > maxino)
21340024Smckusick 		errexit("bad inode number %d to nextinode\n", inumber);
21440024Smckusick 	if (inumber >= lastinum) {
21540024Smckusick 		readcnt++;
21664639Sbostic 		dblk = fsbtodb(&sblock, ino_to_fsba(&sblock, lastinum));
21740024Smckusick 		if (readcnt % readpercg == 0) {
21840024Smckusick 			size = partialsize;
21940024Smckusick 			lastinum += partialcnt;
22040024Smckusick 		} else {
22140024Smckusick 			size = inobufsize;
22240024Smckusick 			lastinum += fullcnt;
22340024Smckusick 		}
22444934Smckusick 		(void)bread(fsreadfd, (char *)inodebuf, dblk, size); /* ??? */
22540024Smckusick 		dp = inodebuf;
22640024Smckusick 	}
22740024Smckusick 	return (dp++);
22840024Smckusick }
22940024Smckusick 
23040024Smckusick resetinodebuf()
23140024Smckusick {
23240024Smckusick 
23340647Smckusick 	startinum = 0;
23440024Smckusick 	nextino = 0;
23540024Smckusick 	lastinum = 0;
23640024Smckusick 	readcnt = 0;
23740024Smckusick 	inobufsize = blkroundup(&sblock, INOBUFSIZE);
23840024Smckusick 	fullcnt = inobufsize / sizeof(struct dinode);
23940024Smckusick 	readpercg = sblock.fs_ipg / fullcnt;
24040024Smckusick 	partialcnt = sblock.fs_ipg % fullcnt;
24140024Smckusick 	partialsize = partialcnt * sizeof(struct dinode);
24240024Smckusick 	if (partialcnt != 0) {
24340024Smckusick 		readpercg++;
24440024Smckusick 	} else {
24540024Smckusick 		partialcnt = fullcnt;
24640024Smckusick 		partialsize = inobufsize;
24740024Smckusick 	}
24840024Smckusick 	if (inodebuf == NULL &&
24940024Smckusick 	    (inodebuf = (struct dinode *)malloc((unsigned)inobufsize)) == NULL)
25040024Smckusick 		errexit("Cannot allocate space for inode buffer\n");
25140024Smckusick 	while (nextino < ROOTINO)
25244934Smckusick 		(void)getnextinode(nextino);
25340024Smckusick }
25440024Smckusick 
25540024Smckusick freeinodebuf()
25640024Smckusick {
25740024Smckusick 
25840024Smckusick 	if (inodebuf != NULL)
25940024Smckusick 		free((char *)inodebuf);
26040024Smckusick 	inodebuf = NULL;
26140024Smckusick }
26240024Smckusick 
26340024Smckusick /*
26440024Smckusick  * Routines to maintain information about directory inodes.
26540024Smckusick  * This is built during the first pass and used during the
26640024Smckusick  * second and third passes.
26740024Smckusick  *
26840024Smckusick  * Enter inodes into the cache.
26940024Smckusick  */
27039980Smckusick cacheino(dp, inumber)
27139980Smckusick 	register struct dinode *dp;
27239980Smckusick 	ino_t inumber;
27339980Smckusick {
27439980Smckusick 	register struct inoinfo *inp;
27539980Smckusick 	struct inoinfo **inpp;
27639980Smckusick 	unsigned int blks;
27739980Smckusick 
27839980Smckusick 	blks = howmany(dp->di_size, sblock.fs_bsize);
27939980Smckusick 	if (blks > NDADDR)
28039980Smckusick 		blks = NDADDR + NIADDR;
28139980Smckusick 	inp = (struct inoinfo *)
28239980Smckusick 		malloc(sizeof(*inp) + (blks - 1) * sizeof(daddr_t));
28339980Smckusick 	if (inp == NULL)
28439980Smckusick 		return;
28540024Smckusick 	inpp = &inphead[inumber % numdirs];
28640024Smckusick 	inp->i_nexthash = *inpp;
28739980Smckusick 	*inpp = inp;
28840024Smckusick 	inp->i_parent = (ino_t)0;
28940024Smckusick 	inp->i_dotdot = (ino_t)0;
29039980Smckusick 	inp->i_number = inumber;
29140024Smckusick 	inp->i_isize = dp->di_size;
29239980Smckusick 	inp->i_numblks = blks * sizeof(daddr_t);
29340024Smckusick 	bcopy((char *)&dp->di_db[0], (char *)&inp->i_blks[0],
29444934Smckusick 	    (size_t)inp->i_numblks);
29540024Smckusick 	if (inplast == listmax) {
29640024Smckusick 		listmax += 100;
29740024Smckusick 		inpsort = (struct inoinfo **)realloc((char *)inpsort,
29840024Smckusick 		    (unsigned)listmax * sizeof(struct inoinfo *));
29940024Smckusick 		if (inpsort == NULL)
30040024Smckusick 			errexit("cannot increase directory list");
30140024Smckusick 	}
30240024Smckusick 	inpsort[inplast++] = inp;
30339980Smckusick }
30439980Smckusick 
30540024Smckusick /*
30640024Smckusick  * Look up an inode cache structure.
30740024Smckusick  */
30840024Smckusick struct inoinfo *
30940024Smckusick getinoinfo(inumber)
31039980Smckusick 	ino_t inumber;
31139980Smckusick {
31239980Smckusick 	register struct inoinfo *inp;
31339980Smckusick 
31440024Smckusick 	for (inp = inphead[inumber % numdirs]; inp; inp = inp->i_nexthash) {
31539980Smckusick 		if (inp->i_number != inumber)
31639980Smckusick 			continue;
31740024Smckusick 		return (inp);
31839980Smckusick 	}
31940024Smckusick 	errexit("cannot find inode %d\n", inumber);
32040024Smckusick 	return ((struct inoinfo *)0);
32139980Smckusick }
32239980Smckusick 
32340024Smckusick /*
32440024Smckusick  * Clean up all the inode cache structure.
32540024Smckusick  */
32639980Smckusick inocleanup()
32739980Smckusick {
32840024Smckusick 	register struct inoinfo **inpp;
32939980Smckusick 
33039980Smckusick 	if (inphead == NULL)
33139980Smckusick 		return;
33240024Smckusick 	for (inpp = &inpsort[inplast - 1]; inpp >= inpsort; inpp--)
33340024Smckusick 		free((char *)(*inpp));
33440024Smckusick 	free((char *)inphead);
33540024Smckusick 	free((char *)inpsort);
33640024Smckusick 	inphead = inpsort = NULL;
33739980Smckusick }
33839980Smckusick 
33934225Smckusick inodirty()
34034225Smckusick {
34134225Smckusick 
34234225Smckusick 	dirty(pbp);
34334225Smckusick }
34434225Smckusick 
34539973Smckusick clri(idesc, type, flag)
34616261Smckusick 	register struct inodesc *idesc;
34739973Smckusick 	char *type;
34839973Smckusick 	int flag;
34916261Smckusick {
35039973Smckusick 	register struct dinode *dp;
35116261Smckusick 
35217943Smckusick 	dp = ginode(idesc->id_number);
35339973Smckusick 	if (flag == 1) {
35439973Smckusick 		pwarn("%s %s", type,
35539973Smckusick 		    (dp->di_mode & IFMT) == IFDIR ? "DIR" : "FILE");
35616261Smckusick 		pinode(idesc->id_number);
35716261Smckusick 	}
35816261Smckusick 	if (preen || reply("CLEAR") == 1) {
35916261Smckusick 		if (preen)
36016261Smckusick 			printf(" (CLEARED)\n");
36116261Smckusick 		n_files--;
36216261Smckusick 		(void)ckinode(dp, idesc);
36339973Smckusick 		clearinode(dp);
36416261Smckusick 		statemap[idesc->id_number] = USTATE;
36516261Smckusick 		inodirty();
36616261Smckusick 	}
36716261Smckusick }
36816261Smckusick 
36917991Smckusick findname(idesc)
37017991Smckusick 	struct inodesc *idesc;
37117991Smckusick {
37239973Smckusick 	register struct direct *dirp = idesc->id_dirp;
37317991Smckusick 
37417991Smckusick 	if (dirp->d_ino != idesc->id_parent)
37517991Smckusick 		return (KEEPON);
37644934Smckusick 	bcopy(dirp->d_name, idesc->id_name, (size_t)dirp->d_namlen + 1);
37730354Smckusick 	return (STOP|FOUND);
37817991Smckusick }
37917991Smckusick 
38016261Smckusick findino(idesc)
38116261Smckusick 	struct inodesc *idesc;
38216261Smckusick {
38339973Smckusick 	register struct direct *dirp = idesc->id_dirp;
38416261Smckusick 
38516261Smckusick 	if (dirp->d_ino == 0)
38616261Smckusick 		return (KEEPON);
38717991Smckusick 	if (strcmp(dirp->d_name, idesc->id_name) == 0 &&
38839973Smckusick 	    dirp->d_ino >= ROOTINO && dirp->d_ino <= maxino) {
38917991Smckusick 		idesc->id_parent = dirp->d_ino;
39030354Smckusick 		return (STOP|FOUND);
39116261Smckusick 	}
39216261Smckusick 	return (KEEPON);
39316261Smckusick }
39416261Smckusick 
39516261Smckusick pinode(ino)
39616261Smckusick 	ino_t ino;
39716261Smckusick {
39839973Smckusick 	register struct dinode *dp;
39916261Smckusick 	register char *p;
40018102Smckusick 	struct passwd *pw;
40116261Smckusick 	char *ctime();
40216261Smckusick 
40344934Smckusick 	printf(" I=%lu ", ino);
40439973Smckusick 	if (ino < ROOTINO || ino > maxino)
40516261Smckusick 		return;
40617943Smckusick 	dp = ginode(ino);
40716261Smckusick 	printf(" OWNER=");
40818102Smckusick 	if ((pw = getpwuid((int)dp->di_uid)) != 0)
40918102Smckusick 		printf("%s ", pw->pw_name);
41018102Smckusick 	else
41144934Smckusick 		printf("%u ", (unsigned)dp->di_uid);
41216261Smckusick 	printf("MODE=%o\n", dp->di_mode);
41316261Smckusick 	if (preen)
41461110Sbostic 		printf("%s: ", cdevname);
41553821Smckusick 	printf("SIZE=%qu ", dp->di_size);
41654068Smckusick 	p = ctime(&dp->di_mtime.ts_sec);
41747579Smckusick 	printf("MTIME=%12.12s %4.4s ", &p[4], &p[20]);
41816261Smckusick }
41916261Smckusick 
42039973Smckusick blkerror(ino, type, blk)
42116261Smckusick 	ino_t ino;
42239973Smckusick 	char *type;
42316261Smckusick 	daddr_t blk;
42416261Smckusick {
42516261Smckusick 
42644934Smckusick 	pfatal("%ld %s I=%lu", blk, type, ino);
42716261Smckusick 	printf("\n");
42817936Smckusick 	switch (statemap[ino]) {
42917936Smckusick 
43017936Smckusick 	case FSTATE:
43117936Smckusick 		statemap[ino] = FCLEAR;
43217936Smckusick 		return;
43317936Smckusick 
43417936Smckusick 	case DSTATE:
43517936Smckusick 		statemap[ino] = DCLEAR;
43617936Smckusick 		return;
43717936Smckusick 
43817936Smckusick 	case FCLEAR:
43917936Smckusick 	case DCLEAR:
44017936Smckusick 		return;
44117936Smckusick 
44217936Smckusick 	default:
44317936Smckusick 		errexit("BAD STATE %d TO BLKERR", statemap[ino]);
44417936Smckusick 		/* NOTREACHED */
44517936Smckusick 	}
44616261Smckusick }
44717955Smckusick 
44817955Smckusick /*
44917955Smckusick  * allocate an unused inode
45017955Smckusick  */
45117955Smckusick ino_t
45217955Smckusick allocino(request, type)
45317955Smckusick 	ino_t request;
45417955Smckusick 	int type;
45517955Smckusick {
45617955Smckusick 	register ino_t ino;
45739973Smckusick 	register struct dinode *dp;
45817955Smckusick 
45917955Smckusick 	if (request == 0)
46017955Smckusick 		request = ROOTINO;
46117955Smckusick 	else if (statemap[request] != USTATE)
46217955Smckusick 		return (0);
46339973Smckusick 	for (ino = request; ino < maxino; ino++)
46417955Smckusick 		if (statemap[ino] == USTATE)
46517955Smckusick 			break;
46639973Smckusick 	if (ino == maxino)
46717955Smckusick 		return (0);
46817955Smckusick 	switch (type & IFMT) {
46917955Smckusick 	case IFDIR:
47017955Smckusick 		statemap[ino] = DSTATE;
47117955Smckusick 		break;
47217955Smckusick 	case IFREG:
47317955Smckusick 	case IFLNK:
47417955Smckusick 		statemap[ino] = FSTATE;
47517955Smckusick 		break;
47617955Smckusick 	default:
47717955Smckusick 		return (0);
47817955Smckusick 	}
47917955Smckusick 	dp = ginode(ino);
48039973Smckusick 	dp->di_db[0] = allocblk((long)1);
48117955Smckusick 	if (dp->di_db[0] == 0) {
48217955Smckusick 		statemap[ino] = USTATE;
48317955Smckusick 		return (0);
48417955Smckusick 	}
48517955Smckusick 	dp->di_mode = type;
48654068Smckusick 	(void)time(&dp->di_atime.ts_sec);
48717955Smckusick 	dp->di_mtime = dp->di_ctime = dp->di_atime;
48817955Smckusick 	dp->di_size = sblock.fs_fsize;
48917955Smckusick 	dp->di_blocks = btodb(sblock.fs_fsize);
49017955Smckusick 	n_files++;
49117955Smckusick 	inodirty();
49266277Smkm 	if (newinofmt)
49366277Smkm 		typemap[ino] = IFTODT(type);
49417955Smckusick 	return (ino);
49517955Smckusick }
49617955Smckusick 
49717955Smckusick /*
49817955Smckusick  * deallocate an inode
49917955Smckusick  */
50017955Smckusick freeino(ino)
50117955Smckusick 	ino_t ino;
50217955Smckusick {
50317955Smckusick 	struct inodesc idesc;
50417955Smckusick 	extern int pass4check();
50539973Smckusick 	struct dinode *dp;
50617955Smckusick 
50717955Smckusick 	bzero((char *)&idesc, sizeof(struct inodesc));
50817955Smckusick 	idesc.id_type = ADDR;
50917955Smckusick 	idesc.id_func = pass4check;
51017955Smckusick 	idesc.id_number = ino;
51117955Smckusick 	dp = ginode(ino);
51217955Smckusick 	(void)ckinode(dp, &idesc);
51339973Smckusick 	clearinode(dp);
51417955Smckusick 	inodirty();
51517955Smckusick 	statemap[ino] = USTATE;
51617955Smckusick 	n_files--;
51717955Smckusick }
518