xref: /csrg-svn/sys/ufs/ffs/ufs_inode.c (revision 55413)
123399Smckusick /*
251509Sbostic  * Copyright (c) 1991 Regents of the University of California.
337736Smckusick  * All rights reserved.
423399Smckusick  *
544537Sbostic  * %sccs.include.redist.c%
637736Smckusick  *
7*55413Smckusick  *	@(#)ufs_inode.c	7.49 (Berkeley) 07/20/92
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>
1651987Smckusick #include <sys/malloc.h>
1724Sbill 
1851509Sbostic #include <ufs/ufs/quota.h>
1951509Sbostic #include <ufs/ufs/inode.h>
2051509Sbostic #include <ufs/ufs/ufsmount.h>
2151509Sbostic #include <ufs/ufs/ufs_extern.h>
2247571Skarels 
2351509Sbostic u_long	nextgennumber;		/* Next generation number to assign. */
2451547Smckusick int	prtactive = 0;		/* 1 => print out reclaim of active vnodes */
2524Sbill 
2651509Sbostic int
2739440Smckusick ufs_init()
2824Sbill {
2951509Sbostic 	static int first = 1;
3024Sbill 
3151509Sbostic 	if (!first)
3251509Sbostic 		return (0);
3351509Sbostic 	first = 0;
3451509Sbostic 
3551509Sbostic #ifdef DIAGNOSTIC
3651987Smckusick 	if ((sizeof(struct inode) - 1) & sizeof(struct inode))
3751987Smckusick 		printf("ufs_init: bad size %d\n", sizeof(struct inode));
3851509Sbostic #endif
3951509Sbostic 	ufs_ihashinit();
4041313Smckusick 	dqinit();
4137736Smckusick 	return (0);
4237736Smckusick }
437334Skre 
4437736Smckusick /*
4539392Smckusick  * Unlock and decrement the reference count of an inode structure.
4624Sbill  */
4751509Sbostic void
4851509Sbostic ufs_iput(ip)
494818Swnj 	register struct inode *ip;
5024Sbill {
517118Smckusick 
528452Sroot 	if ((ip->i_flag & ILOCKED) == 0)
537118Smckusick 		panic("iput");
5416665Smckusick 	IUNLOCK(ip);
5537736Smckusick 	vrele(ITOV(ip));
567118Smckusick }
577118Smckusick 
5839392Smckusick /*
5939392Smckusick  * Reclaim an inode so that it can be used for other purposes.
6024Sbill  */
6151509Sbostic int
6254648Smckusick ufs_reclaim(ap)
6354648Smckusick 	struct vop_reclaim_args /* {
6454648Smckusick 		struct vnode *a_vp;
6554648Smckusick 	} */ *ap;
6639392Smckusick {
6753864Sheideman 	register struct vnode *vp = ap->a_vp;
6851509Sbostic 	register struct inode *ip;
6951987Smckusick 	int i, type;
7039392Smckusick 
7153864Sheideman 	if (prtactive && vp->v_usecount != 0)
7253864Sheideman 		vprint("ufs_reclaim: pushing active", vp);
7339392Smckusick 	/*
7439392Smckusick 	 * Remove the inode from its hash chain.
7539392Smckusick 	 */
7653864Sheideman 	ip = VTOI(vp);
77*55413Smckusick 	ufs_ihashrem(ip);
7839392Smckusick 	/*
7939392Smckusick 	 * Purge old data structures associated with the inode.
8039392Smckusick 	 */
8153864Sheideman 	cache_purge(vp);
8239392Smckusick 	if (ip->i_devvp) {
8339392Smckusick 		vrele(ip->i_devvp);
8439392Smckusick 		ip->i_devvp = 0;
8539392Smckusick 	}
8639392Smckusick #ifdef QUOTA
8741313Smckusick 	for (i = 0; i < MAXQUOTAS; i++) {
8841313Smckusick 		if (ip->i_dquot[i] != NODQUOT) {
8953864Sheideman 			dqrele(vp, ip->i_dquot[i]);
9041313Smckusick 			ip->i_dquot[i] = NODQUOT;
9141313Smckusick 		}
9241313Smckusick 	}
9339392Smckusick #endif
9453864Sheideman 	switch (vp->v_mount->mnt_stat.f_type) {
9551987Smckusick 	case MOUNT_UFS:
9651987Smckusick 		type = M_FFSNODE;
9751987Smckusick 		break;
9851987Smckusick 	case MOUNT_MFS:
9951987Smckusick 		type = M_MFSNODE;
10051987Smckusick 		break;
10151987Smckusick 	case MOUNT_LFS:
10251987Smckusick 		type = M_LFSNODE;
10351987Smckusick 		break;
10451987Smckusick 	default:
10551987Smckusick 		panic("ufs_reclaim: not ufs file");
10651987Smckusick 	}
10753864Sheideman 	FREE(vp->v_data, type);
10853864Sheideman 	vp->v_data = NULL;
10939392Smckusick 	return (0);
11039392Smckusick }
11139392Smckusick 
11239392Smckusick /*
1134818Swnj  * Lock an inode. If its already locked, set the WANT bit and sleep.
1143617Sroot  */
11551509Sbostic void
11651509Sbostic ufs_ilock(ip)
1174818Swnj 	register struct inode *ip;
1183617Sroot {
11952037Smckusick 	struct proc *p = curproc;	/* XXX */
1203617Sroot 
12137736Smckusick 	while (ip->i_flag & ILOCKED) {
12237736Smckusick 		ip->i_flag |= IWANT;
12352037Smckusick #ifdef DIAGNOSTIC
12452037Smckusick 		if (p) {
12552037Smckusick 			if (p->p_pid == ip->i_lockholder)
12652037Smckusick 				panic("locking against myself");
12752037Smckusick 			ip->i_lockwaiter = p->p_pid;
12852037Smckusick 		}
12952037Smckusick #endif
13037736Smckusick 		(void) sleep((caddr_t)ip, PINOD);
13137736Smckusick 	}
13252037Smckusick #ifdef DIAGNOSTIC
13351987Smckusick 	ip->i_lockwaiter = 0;
13452037Smckusick 	if (p)
13552037Smckusick 		ip->i_lockholder = p->p_pid;
13652037Smckusick #endif
13737736Smckusick 	ip->i_flag |= ILOCKED;
1383617Sroot }
1393617Sroot 
1403617Sroot /*
1414818Swnj  * Unlock an inode.  If WANT bit is on, wakeup.
1423617Sroot  */
14351509Sbostic void
14451509Sbostic ufs_iunlock(ip)
1454818Swnj 	register struct inode *ip;
1463617Sroot {
1473617Sroot 
14837736Smckusick 	if ((ip->i_flag & ILOCKED) == 0)
14951509Sbostic 		vprint("ufs_iunlock: unlocked inode", ITOV(ip));
15052037Smckusick #ifdef DIAGNOSTIC
15151987Smckusick 	ip->i_lockholder = 0;
15252037Smckusick #endif
15337736Smckusick 	ip->i_flag &= ~ILOCKED;
15437736Smckusick 	if (ip->i_flag&IWANT) {
15537736Smckusick 		ip->i_flag &= ~IWANT;
15637736Smckusick 		wakeup((caddr_t)ip);
15737736Smckusick 	}
1583617Sroot }
159