xref: /csrg-svn/sys/ufs/ffs/ufs_inode.c (revision 51547)
123399Smckusick /*
251509Sbostic  * Copyright (c) 1991 Regents of the University of California.
337736Smckusick  * All rights reserved.
423399Smckusick  *
544537Sbostic  * %sccs.include.redist.c%
637736Smckusick  *
7*51547Smckusick  *	@(#)ufs_inode.c	7.42 (Berkeley) 11/05/91
823399Smckusick  */
924Sbill 
1051509Sbostic #include <sys/param.h>
1151509Sbostic #include <sys/systm.h>
1251509Sbostic #include <sys/proc.h>
1351509Sbostic #include <sys/vnode.h>
1451509Sbostic #include <sys/mount.h>
1551509Sbostic #include <sys/kernel.h>
1624Sbill 
1751509Sbostic #include <ufs/ufs/quota.h>
1851509Sbostic #include <ufs/ufs/inode.h>
1951509Sbostic #include <ufs/ufs/ufsmount.h>
2051509Sbostic #include <ufs/ufs/ufs_extern.h>
2147571Skarels 
2251509Sbostic u_long	nextgennumber;		/* Next generation number to assign. */
23*51547Smckusick int	prtactive = 0;		/* 1 => print out reclaim of active vnodes */
2424Sbill 
2551509Sbostic int
2639440Smckusick ufs_init()
2724Sbill {
2851509Sbostic 	static int first = 1;
2924Sbill 
3051509Sbostic 	if (!first)
3151509Sbostic 		return (0);
3251509Sbostic 	first = 0;
3351509Sbostic 
3451509Sbostic #ifdef DIAGNOSTIC
3539392Smckusick 	if (VN_MAXPRIVATE < sizeof(struct inode))
3651509Sbostic 		panic("ufs_init: inode too small");
3751509Sbostic #endif
3851509Sbostic 	ufs_ihashinit();
3941313Smckusick 	dqinit();
4037736Smckusick 	return (0);
4137736Smckusick }
427334Skre 
4337736Smckusick /*
4439392Smckusick  * Unlock and decrement the reference count of an inode structure.
4524Sbill  */
4651509Sbostic void
4751509Sbostic ufs_iput(ip)
484818Swnj 	register struct inode *ip;
4924Sbill {
507118Smckusick 
518452Sroot 	if ((ip->i_flag & ILOCKED) == 0)
527118Smckusick 		panic("iput");
5316665Smckusick 	IUNLOCK(ip);
5437736Smckusick 	vrele(ITOV(ip));
557118Smckusick }
567118Smckusick 
5739392Smckusick /*
5839392Smckusick  * Reclaim an inode so that it can be used for other purposes.
5924Sbill  */
6051509Sbostic int
6139392Smckusick ufs_reclaim(vp)
6239392Smckusick 	register struct vnode *vp;
6339392Smckusick {
6451509Sbostic 	register struct inode *ip;
6541313Smckusick 	int i;
6639392Smckusick 
6739816Smckusick 	if (prtactive && vp->v_usecount != 0)
6839676Smckusick 		vprint("ufs_reclaim: pushing active", vp);
6939392Smckusick 	/*
7039392Smckusick 	 * Remove the inode from its hash chain.
7139392Smckusick 	 */
7251509Sbostic 	ip = VTOI(vp);
7339392Smckusick 	remque(ip);
7439392Smckusick 	ip->i_forw = ip;
7539392Smckusick 	ip->i_back = ip;
7639392Smckusick 	/*
7739392Smckusick 	 * Purge old data structures associated with the inode.
7839392Smckusick 	 */
7939392Smckusick 	cache_purge(vp);
8039392Smckusick 	if (ip->i_devvp) {
8139392Smckusick 		vrele(ip->i_devvp);
8239392Smckusick 		ip->i_devvp = 0;
8339392Smckusick 	}
8439392Smckusick #ifdef QUOTA
8541313Smckusick 	for (i = 0; i < MAXQUOTAS; i++) {
8641313Smckusick 		if (ip->i_dquot[i] != NODQUOT) {
8741313Smckusick 			dqrele(vp, ip->i_dquot[i]);
8841313Smckusick 			ip->i_dquot[i] = NODQUOT;
8941313Smckusick 		}
9041313Smckusick 	}
9139392Smckusick #endif
9239392Smckusick 	ip->i_flag = 0;
9339392Smckusick 	return (0);
9439392Smckusick }
9539392Smckusick 
9639392Smckusick /*
974818Swnj  * Lock an inode. If its already locked, set the WANT bit and sleep.
983617Sroot  */
9951509Sbostic void
10051509Sbostic ufs_ilock(ip)
1014818Swnj 	register struct inode *ip;
1023617Sroot {
1033617Sroot 
10437736Smckusick 	while (ip->i_flag & ILOCKED) {
10537736Smckusick 		ip->i_flag |= IWANT;
10647571Skarels 		if (ip->i_spare0 == curproc->p_pid)
10739795Smckusick 			panic("locking against myself");
10847571Skarels 		ip->i_spare1 = curproc->p_pid;
10937736Smckusick 		(void) sleep((caddr_t)ip, PINOD);
11037736Smckusick 	}
11139795Smckusick 	ip->i_spare1 = 0;
11247571Skarels 	ip->i_spare0 = curproc->p_pid;
11337736Smckusick 	ip->i_flag |= ILOCKED;
1143617Sroot }
1153617Sroot 
1163617Sroot /*
1174818Swnj  * Unlock an inode.  If WANT bit is on, wakeup.
1183617Sroot  */
11951509Sbostic void
12051509Sbostic ufs_iunlock(ip)
1214818Swnj 	register struct inode *ip;
1223617Sroot {
1233617Sroot 
12437736Smckusick 	if ((ip->i_flag & ILOCKED) == 0)
12551509Sbostic 		vprint("ufs_iunlock: unlocked inode", ITOV(ip));
12639795Smckusick 	ip->i_spare0 = 0;
12737736Smckusick 	ip->i_flag &= ~ILOCKED;
12837736Smckusick 	if (ip->i_flag&IWANT) {
12937736Smckusick 		ip->i_flag &= ~IWANT;
13037736Smckusick 		wakeup((caddr_t)ip);
13137736Smckusick 	}
1323617Sroot }
133