xref: /csrg-svn/sys/ufs/ffs/ufs_inode.c (revision 67406)
123399Smckusick /*
263376Sbostic  * Copyright (c) 1991, 1993
363376Sbostic  *	The Regents of the University of California.  All rights reserved.
465774Sbostic  * (c) UNIX System Laboratories, Inc.
565774Sbostic  * All or some portions of this file are derived from material licensed
665774Sbostic  * to the University of California by American Telephone and Telegraph
765774Sbostic  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
865774Sbostic  * the permission of UNIX System Laboratories, Inc.
923399Smckusick  *
1044537Sbostic  * %sccs.include.redist.c%
1137736Smckusick  *
12*67406Smckusick  *	@(#)ufs_inode.c	8.6 (Berkeley) 06/16/94
1323399Smckusick  */
1424Sbill 
1551509Sbostic #include <sys/param.h>
1651509Sbostic #include <sys/systm.h>
1751509Sbostic #include <sys/proc.h>
1851509Sbostic #include <sys/vnode.h>
1951509Sbostic #include <sys/mount.h>
2051509Sbostic #include <sys/kernel.h>
2151987Smckusick #include <sys/malloc.h>
2224Sbill 
2351509Sbostic #include <ufs/ufs/quota.h>
2451509Sbostic #include <ufs/ufs/inode.h>
2551509Sbostic #include <ufs/ufs/ufsmount.h>
2651509Sbostic #include <ufs/ufs/ufs_extern.h>
2747571Skarels 
2851509Sbostic u_long	nextgennumber;		/* Next generation number to assign. */
2951547Smckusick int	prtactive = 0;		/* 1 => print out reclaim of active vnodes */
3024Sbill 
3151509Sbostic int
ufs_init()3239440Smckusick ufs_init()
3324Sbill {
3451509Sbostic 	static int first = 1;
3524Sbill 
3651509Sbostic 	if (!first)
3751509Sbostic 		return (0);
3851509Sbostic 	first = 0;
3951509Sbostic 
4051509Sbostic #ifdef DIAGNOSTIC
4151987Smckusick 	if ((sizeof(struct inode) - 1) & sizeof(struct inode))
4251987Smckusick 		printf("ufs_init: bad size %d\n", sizeof(struct inode));
4351509Sbostic #endif
4451509Sbostic 	ufs_ihashinit();
4567393Smkm #ifdef QUOTA
4641313Smckusick 	dqinit();
4767393Smkm #endif
4837736Smckusick 	return (0);
4937736Smckusick }
507334Skre 
5137736Smckusick /*
5264598Sbostic  * Last reference to an inode.  If necessary, write or delete it.
5356746Smckusick  */
5456746Smckusick int
ufs_inactive(ap)5556746Smckusick ufs_inactive(ap)
5656746Smckusick 	struct vop_inactive_args /* {
5756746Smckusick 		struct vnode *a_vp;
5856746Smckusick 	} */ *ap;
5956746Smckusick {
6056746Smckusick 	register struct vnode *vp = ap->a_vp;
6156746Smckusick 	register struct inode *ip = VTOI(vp);
6256746Smckusick 	struct timeval tv;
6356746Smckusick 	int mode, error;
6456746Smckusick 	extern int prtactive;
6556746Smckusick 
6656746Smckusick 	if (prtactive && vp->v_usecount != 0)
6756746Smckusick 		vprint("ffs_inactive: pushing active", vp);
6856746Smckusick 
6956746Smckusick 	/* Get rid of inodes related to stale file handles. */
7056746Smckusick 	if (ip->i_mode == 0) {
7156746Smckusick 		if ((vp->v_flag & VXLOCK) == 0)
7256746Smckusick 			vgone(vp);
7356746Smckusick 		return (0);
7456746Smckusick 	}
7556746Smckusick 
7656746Smckusick 	error = 0;
7756746Smckusick #ifdef DIAGNOSTIC
7856746Smckusick 	if (VOP_ISLOCKED(vp))
7956746Smckusick 		panic("ffs_inactive: locked inode");
8057052Smckusick 	if (curproc)
8157052Smckusick 		ip->i_lockholder = curproc->p_pid;
8257052Smckusick 	else
8357052Smckusick 		ip->i_lockholder = -1;
8456746Smckusick #endif
8564598Sbostic 	ip->i_flag |= IN_LOCKED;
8656746Smckusick 	if (ip->i_nlink <= 0 && (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
8756746Smckusick #ifdef QUOTA
8856746Smckusick 		if (!getinoquota(ip))
8956746Smckusick 			(void)chkiq(ip, -1, NOCRED, 0);
9056746Smckusick #endif
9156746Smckusick 		error = VOP_TRUNCATE(vp, (off_t)0, 0, NOCRED, NULL);
9264598Sbostic 		ip->i_rdev = 0;
9356746Smckusick 		mode = ip->i_mode;
9456746Smckusick 		ip->i_mode = 0;
9564598Sbostic 		ip->i_flag |= IN_CHANGE | IN_UPDATE;
9656746Smckusick 		VOP_VFREE(vp, ip->i_number, mode);
9756746Smckusick 	}
9864598Sbostic 	if (ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) {
9956746Smckusick 		tv = time;
10056746Smckusick 		VOP_UPDATE(vp, &tv, &tv, 0);
10156746Smckusick 	}
10256746Smckusick 	VOP_UNLOCK(vp);
10356746Smckusick 	/*
10456746Smckusick 	 * If we are done with the inode, reclaim it
10556746Smckusick 	 * so that it can be reused immediately.
10656746Smckusick 	 */
10756746Smckusick 	if (vp->v_usecount == 0 && ip->i_mode == 0)
10856746Smckusick 		vgone(vp);
10956746Smckusick 	return (error);
11056746Smckusick }
11156746Smckusick 
11256746Smckusick /*
11339392Smckusick  * Reclaim an inode so that it can be used for other purposes.
11424Sbill  */
11551509Sbostic int
ufs_reclaim(vp)116*67406Smckusick ufs_reclaim(vp)
117*67406Smckusick 	register struct vnode *vp;
11839392Smckusick {
11951509Sbostic 	register struct inode *ip;
120*67406Smckusick 	int i;
121*67406Smckusick 	extern int prtactive;
12239392Smckusick 
12353864Sheideman 	if (prtactive && vp->v_usecount != 0)
12453864Sheideman 		vprint("ufs_reclaim: pushing active", vp);
12539392Smckusick 	/*
12639392Smckusick 	 * Remove the inode from its hash chain.
12739392Smckusick 	 */
12853864Sheideman 	ip = VTOI(vp);
12955413Smckusick 	ufs_ihashrem(ip);
13039392Smckusick 	/*
13139392Smckusick 	 * Purge old data structures associated with the inode.
13239392Smckusick 	 */
13353864Sheideman 	cache_purge(vp);
13439392Smckusick 	if (ip->i_devvp) {
13539392Smckusick 		vrele(ip->i_devvp);
13639392Smckusick 		ip->i_devvp = 0;
13739392Smckusick 	}
13839392Smckusick #ifdef QUOTA
13941313Smckusick 	for (i = 0; i < MAXQUOTAS; i++) {
14041313Smckusick 		if (ip->i_dquot[i] != NODQUOT) {
14153864Sheideman 			dqrele(vp, ip->i_dquot[i]);
14241313Smckusick 			ip->i_dquot[i] = NODQUOT;
14341313Smckusick 		}
14441313Smckusick 	}
14539392Smckusick #endif
14639392Smckusick 	return (0);
14739392Smckusick }
148