xref: /csrg-svn/sbin/fsck/inode.c (revision 68908)
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*68908Smckusick static char sccsid[] = "@(#)inode.c	8.7 (Berkeley) 04/27/95";
1039976Smckusick #endif /* not lint */
1116261Smckusick 
1216261Smckusick #include <sys/param.h>
1353821Smckusick #include <sys/time.h>
14*68908Smckusick 
1551532Sbostic #include <ufs/ufs/dinode.h>
1651532Sbostic #include <ufs/ufs/dir.h>
1751532Sbostic #include <ufs/ffs/fs.h>
18*68908Smckusick 
19*68908Smckusick #include <err.h>
2036963Sbostic #include <pwd.h>
2144934Smckusick #include <string.h>
22*68908Smckusick 
2316261Smckusick #include "fsck.h"
2416261Smckusick 
2540647Smckusick static ino_t startinum;
2634225Smckusick 
27*68908Smckusick static int iblock __P((struct inodesc *, long ilevel, quad_t isize));
28*68908Smckusick 
29*68908Smckusick int
3016261Smckusick ckinode(dp, idesc)
3139973Smckusick 	struct dinode *dp;
3216261Smckusick 	register struct inodesc *idesc;
3316261Smckusick {
3468548Smckusick 	ufs_daddr_t *ap;
3539973Smckusick 	long ret, n, ndb, offset;
3639973Smckusick 	struct dinode dino;
3753825Smckusick 	quad_t remsize, sizepb;
3854599Smckusick 	mode_t mode;
3916261Smckusick 
4044998Smckusick 	if (idesc->id_fix != IGNORE)
4144998Smckusick 		idesc->id_fix = DONTKNOW;
4218000Smckusick 	idesc->id_entryno = 0;
4318000Smckusick 	idesc->id_filesize = dp->di_size;
4454599Smckusick 	mode = dp->di_mode & IFMT;
4554599Smckusick 	if (mode == IFBLK || mode == IFCHR || (mode == IFLNK &&
4654599Smckusick 	    dp->di_size < sblock.fs_maxsymlinklen))
4716261Smckusick 		return (KEEPON);
4816261Smckusick 	dino = *dp;
4916261Smckusick 	ndb = howmany(dino.di_size, sblock.fs_bsize);
5016261Smckusick 	for (ap = &dino.di_db[0]; ap < &dino.di_db[NDADDR]; ap++) {
5116261Smckusick 		if (--ndb == 0 && (offset = blkoff(&sblock, dino.di_size)) != 0)
5216261Smckusick 			idesc->id_numfrags =
5316261Smckusick 				numfrags(&sblock, fragroundup(&sblock, offset));
5416261Smckusick 		else
5516261Smckusick 			idesc->id_numfrags = sblock.fs_frag;
5616261Smckusick 		if (*ap == 0)
5716261Smckusick 			continue;
5816261Smckusick 		idesc->id_blkno = *ap;
5916261Smckusick 		if (idesc->id_type == ADDR)
6016261Smckusick 			ret = (*idesc->id_func)(idesc);
6116261Smckusick 		else
6216261Smckusick 			ret = dirscan(idesc);
6316261Smckusick 		if (ret & STOP)
6416261Smckusick 			return (ret);
6516261Smckusick 	}
6616261Smckusick 	idesc->id_numfrags = sblock.fs_frag;
6753825Smckusick 	remsize = dino.di_size - sblock.fs_bsize * NDADDR;
6853825Smckusick 	sizepb = sblock.fs_bsize;
6917930Smckusick 	for (ap = &dino.di_ib[0], n = 1; n <= NIADDR; ap++, n++) {
7016261Smckusick 		if (*ap) {
7116261Smckusick 			idesc->id_blkno = *ap;
7253825Smckusick 			ret = iblock(idesc, n, remsize);
7316261Smckusick 			if (ret & STOP)
7416261Smckusick 				return (ret);
7516261Smckusick 		}
7653825Smckusick 		sizepb *= NINDIR(&sblock);
7753825Smckusick 		remsize -= sizepb;
7816261Smckusick 	}
7916261Smckusick 	return (KEEPON);
8016261Smckusick }
8116261Smckusick 
82*68908Smckusick static int
8316261Smckusick iblock(idesc, ilevel, isize)
8416261Smckusick 	struct inodesc *idesc;
8553825Smckusick 	long ilevel;
8652983Smckusick 	quad_t isize;
8716261Smckusick {
8868548Smckusick 	ufs_daddr_t *ap;
8968548Smckusick 	ufs_daddr_t *aplim;
9068548Smckusick 	struct bufarea *bp;
9153821Smckusick 	int i, n, (*func)(), nif;
9253821Smckusick 	quad_t sizepb;
9323876Smckusick 	char buf[BUFSIZ];
9416261Smckusick 
9516261Smckusick 	if (idesc->id_type == ADDR) {
9616261Smckusick 		func = idesc->id_func;
9716261Smckusick 		if (((n = (*func)(idesc)) & KEEPON) == 0)
9816261Smckusick 			return (n);
9916261Smckusick 	} else
10016261Smckusick 		func = dirscan;
10139973Smckusick 	if (chkrange(idesc->id_blkno, idesc->id_numfrags))
10216261Smckusick 		return (SKIP);
10334225Smckusick 	bp = getdatablk(idesc->id_blkno, sblock.fs_bsize);
10416261Smckusick 	ilevel--;
10517930Smckusick 	for (sizepb = sblock.fs_bsize, i = 0; i < ilevel; i++)
10617930Smckusick 		sizepb *= NINDIR(&sblock);
10753825Smckusick 	nif = howmany(isize , sizepb);
10816261Smckusick 	if (nif > NINDIR(&sblock))
10916261Smckusick 		nif = NINDIR(&sblock);
11017950Smckusick 	if (idesc->id_func == pass1check && nif < NINDIR(&sblock)) {
11134225Smckusick 		aplim = &bp->b_un.b_indir[NINDIR(&sblock)];
11234225Smckusick 		for (ap = &bp->b_un.b_indir[nif]; ap < aplim; ap++) {
11317950Smckusick 			if (*ap == 0)
11417950Smckusick 				continue;
11544934Smckusick 			(void)sprintf(buf, "PARTIALLY TRUNCATED INODE I=%lu",
11623876Smckusick 				idesc->id_number);
11723876Smckusick 			if (dofix(idesc, buf)) {
11817950Smckusick 				*ap = 0;
11934225Smckusick 				dirty(bp);
12017950Smckusick 			}
12117950Smckusick 		}
12239973Smckusick 		flush(fswritefd, bp);
12317950Smckusick 	}
12434225Smckusick 	aplim = &bp->b_un.b_indir[nif];
12553825Smckusick 	for (ap = bp->b_un.b_indir; ap < aplim; ap++) {
12616261Smckusick 		if (*ap) {
12716261Smckusick 			idesc->id_blkno = *ap;
12866898Smckusick 			if (ilevel == 0)
12916261Smckusick 				n = (*func)(idesc);
13066898Smckusick 			else
13153825Smckusick 				n = iblock(idesc, ilevel, isize);
13234225Smckusick 			if (n & STOP) {
13334225Smckusick 				bp->b_flags &= ~B_INUSE;
13416261Smckusick 				return (n);
13534225Smckusick 			}
13616261Smckusick 		}
13766898Smckusick 		isize -= sizepb;
13834225Smckusick 	}
13934225Smckusick 	bp->b_flags &= ~B_INUSE;
14016261Smckusick 	return (KEEPON);
14116261Smckusick }
14216261Smckusick 
14339973Smckusick /*
14439973Smckusick  * Check that a block in a legal block number.
14539973Smckusick  * Return 0 if in range, 1 if out of range.
14639973Smckusick  */
147*68908Smckusick int
14839973Smckusick chkrange(blk, cnt)
14968548Smckusick 	ufs_daddr_t blk;
15016261Smckusick 	int cnt;
15116261Smckusick {
15216261Smckusick 	register int c;
15316261Smckusick 
15439973Smckusick 	if ((unsigned)(blk + cnt) > maxfsblock)
15516261Smckusick 		return (1);
15616261Smckusick 	c = dtog(&sblock, blk);
15716261Smckusick 	if (blk < cgdmin(&sblock, c)) {
15839973Smckusick 		if ((blk + cnt) > cgsblock(&sblock, c)) {
15916261Smckusick 			if (debug) {
16044934Smckusick 				printf("blk %ld < cgdmin %ld;",
16116261Smckusick 				    blk, cgdmin(&sblock, c));
16244934Smckusick 				printf(" blk + cnt %ld > cgsbase %ld\n",
16339973Smckusick 				    blk + cnt, cgsblock(&sblock, c));
16416261Smckusick 			}
16516261Smckusick 			return (1);
16616261Smckusick 		}
16716261Smckusick 	} else {
16839973Smckusick 		if ((blk + cnt) > cgbase(&sblock, c+1)) {
16916261Smckusick 			if (debug)  {
17044934Smckusick 				printf("blk %ld >= cgdmin %ld;",
17116261Smckusick 				    blk, cgdmin(&sblock, c));
17244934Smckusick 				printf(" blk + cnt %ld > sblock.fs_fpg %ld\n",
17316261Smckusick 				    blk+cnt, sblock.fs_fpg);
17416261Smckusick 			}
17516261Smckusick 			return (1);
17616261Smckusick 		}
17716261Smckusick 	}
17816261Smckusick 	return (0);
17916261Smckusick }
18016261Smckusick 
18140024Smckusick /*
18240024Smckusick  * General purpose interface for reading inodes.
18340024Smckusick  */
18439973Smckusick struct dinode *
18516261Smckusick ginode(inumber)
18616261Smckusick 	ino_t inumber;
18716261Smckusick {
18868548Smckusick 	ufs_daddr_t iblk;
18916261Smckusick 
19039973Smckusick 	if (inumber < ROOTINO || inumber > maxino)
191*68908Smckusick 		errx(EEXIT, "bad inode number %d to ginode", inumber);
19216261Smckusick 	if (startinum == 0 ||
19316261Smckusick 	    inumber < startinum || inumber >= startinum + INOPB(&sblock)) {
19464639Sbostic 		iblk = ino_to_fsba(&sblock, inumber);
19534225Smckusick 		if (pbp != 0)
19634225Smckusick 			pbp->b_flags &= ~B_INUSE;
19734225Smckusick 		pbp = getdatablk(iblk, sblock.fs_bsize);
19816261Smckusick 		startinum = (inumber / INOPB(&sblock)) * INOPB(&sblock);
19916261Smckusick 	}
20034225Smckusick 	return (&pbp->b_un.b_dinode[inumber % INOPB(&sblock)]);
20116261Smckusick }
20216261Smckusick 
20340024Smckusick /*
20440024Smckusick  * Special purpose version of ginode used to optimize first pass
20540024Smckusick  * over all the inodes in numerical order.
20640024Smckusick  */
20740024Smckusick ino_t nextino, lastinum;
20840024Smckusick long readcnt, readpercg, fullcnt, inobufsize, partialcnt, partialsize;
20940024Smckusick struct dinode *inodebuf;
21040024Smckusick 
21140024Smckusick struct dinode *
21240024Smckusick getnextinode(inumber)
21340024Smckusick 	ino_t inumber;
21440024Smckusick {
21540024Smckusick 	long size;
21668548Smckusick 	ufs_daddr_t dblk;
21740024Smckusick 	static struct dinode *dp;
21840024Smckusick 
21940024Smckusick 	if (inumber != nextino++ || inumber > maxino)
220*68908Smckusick 		errx(EEXIT, "bad inode number %d to nextinode", inumber);
22140024Smckusick 	if (inumber >= lastinum) {
22240024Smckusick 		readcnt++;
22364639Sbostic 		dblk = fsbtodb(&sblock, ino_to_fsba(&sblock, lastinum));
22440024Smckusick 		if (readcnt % readpercg == 0) {
22540024Smckusick 			size = partialsize;
22640024Smckusick 			lastinum += partialcnt;
22740024Smckusick 		} else {
22840024Smckusick 			size = inobufsize;
22940024Smckusick 			lastinum += fullcnt;
23040024Smckusick 		}
23144934Smckusick 		(void)bread(fsreadfd, (char *)inodebuf, dblk, size); /* ??? */
23240024Smckusick 		dp = inodebuf;
23340024Smckusick 	}
23440024Smckusick 	return (dp++);
23540024Smckusick }
23640024Smckusick 
237*68908Smckusick void
23840024Smckusick resetinodebuf()
23940024Smckusick {
24040024Smckusick 
24140647Smckusick 	startinum = 0;
24240024Smckusick 	nextino = 0;
24340024Smckusick 	lastinum = 0;
24440024Smckusick 	readcnt = 0;
24540024Smckusick 	inobufsize = blkroundup(&sblock, INOBUFSIZE);
24640024Smckusick 	fullcnt = inobufsize / sizeof(struct dinode);
24740024Smckusick 	readpercg = sblock.fs_ipg / fullcnt;
24840024Smckusick 	partialcnt = sblock.fs_ipg % fullcnt;
24940024Smckusick 	partialsize = partialcnt * sizeof(struct dinode);
25040024Smckusick 	if (partialcnt != 0) {
25140024Smckusick 		readpercg++;
25240024Smckusick 	} else {
25340024Smckusick 		partialcnt = fullcnt;
25440024Smckusick 		partialsize = inobufsize;
25540024Smckusick 	}
25640024Smckusick 	if (inodebuf == NULL &&
25740024Smckusick 	    (inodebuf = (struct dinode *)malloc((unsigned)inobufsize)) == NULL)
258*68908Smckusick 		errx(EEXIT, "Cannot allocate space for inode buffer");
25940024Smckusick 	while (nextino < ROOTINO)
26044934Smckusick 		(void)getnextinode(nextino);
26140024Smckusick }
26240024Smckusick 
263*68908Smckusick void
26440024Smckusick freeinodebuf()
26540024Smckusick {
26640024Smckusick 
26740024Smckusick 	if (inodebuf != NULL)
26840024Smckusick 		free((char *)inodebuf);
26940024Smckusick 	inodebuf = NULL;
27040024Smckusick }
27140024Smckusick 
27240024Smckusick /*
27340024Smckusick  * Routines to maintain information about directory inodes.
27440024Smckusick  * This is built during the first pass and used during the
27540024Smckusick  * second and third passes.
27640024Smckusick  *
27740024Smckusick  * Enter inodes into the cache.
27840024Smckusick  */
279*68908Smckusick void
28039980Smckusick cacheino(dp, inumber)
28139980Smckusick 	register struct dinode *dp;
28239980Smckusick 	ino_t inumber;
28339980Smckusick {
28439980Smckusick 	register struct inoinfo *inp;
28539980Smckusick 	struct inoinfo **inpp;
28639980Smckusick 	unsigned int blks;
28739980Smckusick 
28839980Smckusick 	blks = howmany(dp->di_size, sblock.fs_bsize);
28939980Smckusick 	if (blks > NDADDR)
29039980Smckusick 		blks = NDADDR + NIADDR;
29139980Smckusick 	inp = (struct inoinfo *)
29268548Smckusick 		malloc(sizeof(*inp) + (blks - 1) * sizeof(ufs_daddr_t));
29339980Smckusick 	if (inp == NULL)
29439980Smckusick 		return;
29540024Smckusick 	inpp = &inphead[inumber % numdirs];
29640024Smckusick 	inp->i_nexthash = *inpp;
29739980Smckusick 	*inpp = inp;
29868249Smckusick 	if (inumber == ROOTINO)
29968249Smckusick 		inp->i_parent = ROOTINO;
30068249Smckusick 	else
30168249Smckusick 		inp->i_parent = (ino_t)0;
30240024Smckusick 	inp->i_dotdot = (ino_t)0;
30339980Smckusick 	inp->i_number = inumber;
30440024Smckusick 	inp->i_isize = dp->di_size;
30568548Smckusick 	inp->i_numblks = blks * sizeof(ufs_daddr_t);
30640024Smckusick 	bcopy((char *)&dp->di_db[0], (char *)&inp->i_blks[0],
30744934Smckusick 	    (size_t)inp->i_numblks);
30840024Smckusick 	if (inplast == listmax) {
30940024Smckusick 		listmax += 100;
31040024Smckusick 		inpsort = (struct inoinfo **)realloc((char *)inpsort,
31140024Smckusick 		    (unsigned)listmax * sizeof(struct inoinfo *));
31240024Smckusick 		if (inpsort == NULL)
313*68908Smckusick 			errx(EEXIT, "cannot increase directory list");
31440024Smckusick 	}
31540024Smckusick 	inpsort[inplast++] = inp;
31639980Smckusick }
31739980Smckusick 
31840024Smckusick /*
31940024Smckusick  * Look up an inode cache structure.
32040024Smckusick  */
32140024Smckusick struct inoinfo *
32240024Smckusick getinoinfo(inumber)
32339980Smckusick 	ino_t inumber;
32439980Smckusick {
32539980Smckusick 	register struct inoinfo *inp;
32639980Smckusick 
32740024Smckusick 	for (inp = inphead[inumber % numdirs]; inp; inp = inp->i_nexthash) {
32839980Smckusick 		if (inp->i_number != inumber)
32939980Smckusick 			continue;
33040024Smckusick 		return (inp);
33139980Smckusick 	}
332*68908Smckusick 	errx(EEXIT, "cannot find inode %d", inumber);
33340024Smckusick 	return ((struct inoinfo *)0);
33439980Smckusick }
33539980Smckusick 
33640024Smckusick /*
33740024Smckusick  * Clean up all the inode cache structure.
33840024Smckusick  */
339*68908Smckusick void
34039980Smckusick inocleanup()
34139980Smckusick {
34240024Smckusick 	register struct inoinfo **inpp;
34339980Smckusick 
34439980Smckusick 	if (inphead == NULL)
34539980Smckusick 		return;
34640024Smckusick 	for (inpp = &inpsort[inplast - 1]; inpp >= inpsort; inpp--)
34740024Smckusick 		free((char *)(*inpp));
34840024Smckusick 	free((char *)inphead);
34940024Smckusick 	free((char *)inpsort);
35040024Smckusick 	inphead = inpsort = NULL;
35139980Smckusick }
35239980Smckusick 
353*68908Smckusick void
35434225Smckusick inodirty()
35534225Smckusick {
35634225Smckusick 
35734225Smckusick 	dirty(pbp);
35834225Smckusick }
35934225Smckusick 
360*68908Smckusick void
36139973Smckusick clri(idesc, type, flag)
36216261Smckusick 	register struct inodesc *idesc;
36339973Smckusick 	char *type;
36439973Smckusick 	int flag;
36516261Smckusick {
36639973Smckusick 	register struct dinode *dp;
36716261Smckusick 
36817943Smckusick 	dp = ginode(idesc->id_number);
36939973Smckusick 	if (flag == 1) {
37039973Smckusick 		pwarn("%s %s", type,
37139973Smckusick 		    (dp->di_mode & IFMT) == IFDIR ? "DIR" : "FILE");
37216261Smckusick 		pinode(idesc->id_number);
37316261Smckusick 	}
37416261Smckusick 	if (preen || reply("CLEAR") == 1) {
37516261Smckusick 		if (preen)
37616261Smckusick 			printf(" (CLEARED)\n");
37716261Smckusick 		n_files--;
37816261Smckusick 		(void)ckinode(dp, idesc);
37939973Smckusick 		clearinode(dp);
38016261Smckusick 		statemap[idesc->id_number] = USTATE;
38116261Smckusick 		inodirty();
38216261Smckusick 	}
38316261Smckusick }
38416261Smckusick 
385*68908Smckusick int
38617991Smckusick findname(idesc)
38717991Smckusick 	struct inodesc *idesc;
38817991Smckusick {
38939973Smckusick 	register struct direct *dirp = idesc->id_dirp;
39017991Smckusick 
39117991Smckusick 	if (dirp->d_ino != idesc->id_parent)
39217991Smckusick 		return (KEEPON);
39344934Smckusick 	bcopy(dirp->d_name, idesc->id_name, (size_t)dirp->d_namlen + 1);
39430354Smckusick 	return (STOP|FOUND);
39517991Smckusick }
39617991Smckusick 
397*68908Smckusick int
39816261Smckusick findino(idesc)
39916261Smckusick 	struct inodesc *idesc;
40016261Smckusick {
40139973Smckusick 	register struct direct *dirp = idesc->id_dirp;
40216261Smckusick 
40316261Smckusick 	if (dirp->d_ino == 0)
40416261Smckusick 		return (KEEPON);
40517991Smckusick 	if (strcmp(dirp->d_name, idesc->id_name) == 0 &&
40639973Smckusick 	    dirp->d_ino >= ROOTINO && dirp->d_ino <= maxino) {
40717991Smckusick 		idesc->id_parent = dirp->d_ino;
40830354Smckusick 		return (STOP|FOUND);
40916261Smckusick 	}
41016261Smckusick 	return (KEEPON);
41116261Smckusick }
41216261Smckusick 
413*68908Smckusick void
41416261Smckusick pinode(ino)
41516261Smckusick 	ino_t ino;
41616261Smckusick {
41739973Smckusick 	register struct dinode *dp;
41816261Smckusick 	register char *p;
41918102Smckusick 	struct passwd *pw;
42016261Smckusick 	char *ctime();
42116261Smckusick 
42244934Smckusick 	printf(" I=%lu ", ino);
42339973Smckusick 	if (ino < ROOTINO || ino > maxino)
42416261Smckusick 		return;
42517943Smckusick 	dp = ginode(ino);
42616261Smckusick 	printf(" OWNER=");
42718102Smckusick 	if ((pw = getpwuid((int)dp->di_uid)) != 0)
42818102Smckusick 		printf("%s ", pw->pw_name);
42918102Smckusick 	else
43044934Smckusick 		printf("%u ", (unsigned)dp->di_uid);
43116261Smckusick 	printf("MODE=%o\n", dp->di_mode);
43216261Smckusick 	if (preen)
43361110Sbostic 		printf("%s: ", cdevname);
43453821Smckusick 	printf("SIZE=%qu ", dp->di_size);
43568548Smckusick 	p = ctime(&dp->di_mtime);
43647579Smckusick 	printf("MTIME=%12.12s %4.4s ", &p[4], &p[20]);
43716261Smckusick }
43816261Smckusick 
439*68908Smckusick void
44039973Smckusick blkerror(ino, type, blk)
44116261Smckusick 	ino_t ino;
44239973Smckusick 	char *type;
44368548Smckusick 	ufs_daddr_t blk;
44416261Smckusick {
44516261Smckusick 
44644934Smckusick 	pfatal("%ld %s I=%lu", blk, type, ino);
44716261Smckusick 	printf("\n");
44817936Smckusick 	switch (statemap[ino]) {
44917936Smckusick 
45017936Smckusick 	case FSTATE:
45117936Smckusick 		statemap[ino] = FCLEAR;
45217936Smckusick 		return;
45317936Smckusick 
45417936Smckusick 	case DSTATE:
45517936Smckusick 		statemap[ino] = DCLEAR;
45617936Smckusick 		return;
45717936Smckusick 
45817936Smckusick 	case FCLEAR:
45917936Smckusick 	case DCLEAR:
46017936Smckusick 		return;
46117936Smckusick 
46217936Smckusick 	default:
463*68908Smckusick 		errx(EEXIT, "BAD STATE %d TO BLKERR", statemap[ino]);
46417936Smckusick 		/* NOTREACHED */
46517936Smckusick 	}
46616261Smckusick }
46717955Smckusick 
46817955Smckusick /*
46917955Smckusick  * allocate an unused inode
47017955Smckusick  */
47117955Smckusick ino_t
47217955Smckusick allocino(request, type)
47317955Smckusick 	ino_t request;
47417955Smckusick 	int type;
47517955Smckusick {
47617955Smckusick 	register ino_t ino;
47739973Smckusick 	register struct dinode *dp;
47817955Smckusick 
47917955Smckusick 	if (request == 0)
48017955Smckusick 		request = ROOTINO;
48117955Smckusick 	else if (statemap[request] != USTATE)
48217955Smckusick 		return (0);
48339973Smckusick 	for (ino = request; ino < maxino; ino++)
48417955Smckusick 		if (statemap[ino] == USTATE)
48517955Smckusick 			break;
48639973Smckusick 	if (ino == maxino)
48717955Smckusick 		return (0);
48817955Smckusick 	switch (type & IFMT) {
48917955Smckusick 	case IFDIR:
49017955Smckusick 		statemap[ino] = DSTATE;
49117955Smckusick 		break;
49217955Smckusick 	case IFREG:
49317955Smckusick 	case IFLNK:
49417955Smckusick 		statemap[ino] = FSTATE;
49517955Smckusick 		break;
49617955Smckusick 	default:
49717955Smckusick 		return (0);
49817955Smckusick 	}
49917955Smckusick 	dp = ginode(ino);
50039973Smckusick 	dp->di_db[0] = allocblk((long)1);
50117955Smckusick 	if (dp->di_db[0] == 0) {
50217955Smckusick 		statemap[ino] = USTATE;
50317955Smckusick 		return (0);
50417955Smckusick 	}
50517955Smckusick 	dp->di_mode = type;
50668548Smckusick 	(void)time(&dp->di_atime);
50717955Smckusick 	dp->di_mtime = dp->di_ctime = dp->di_atime;
50817955Smckusick 	dp->di_size = sblock.fs_fsize;
50917955Smckusick 	dp->di_blocks = btodb(sblock.fs_fsize);
51017955Smckusick 	n_files++;
51117955Smckusick 	inodirty();
51266277Smkm 	if (newinofmt)
51366277Smkm 		typemap[ino] = IFTODT(type);
51417955Smckusick 	return (ino);
51517955Smckusick }
51617955Smckusick 
51717955Smckusick /*
51817955Smckusick  * deallocate an inode
51917955Smckusick  */
520*68908Smckusick void
52117955Smckusick freeino(ino)
52217955Smckusick 	ino_t ino;
52317955Smckusick {
52417955Smckusick 	struct inodesc idesc;
52539973Smckusick 	struct dinode *dp;
52617955Smckusick 
52717955Smckusick 	bzero((char *)&idesc, sizeof(struct inodesc));
52817955Smckusick 	idesc.id_type = ADDR;
52917955Smckusick 	idesc.id_func = pass4check;
53017955Smckusick 	idesc.id_number = ino;
53117955Smckusick 	dp = ginode(ino);
53217955Smckusick 	(void)ckinode(dp, &idesc);
53339973Smckusick 	clearinode(dp);
53417955Smckusick 	inodirty();
53517955Smckusick 	statemap[ino] = USTATE;
53617955Smckusick 	n_files--;
53717955Smckusick }
538