xref: /original-bsd/sys/ufs/ufs/ufs_inode.c (revision 47436896)
1 /*
2  * Copyright (c) 1991 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  *	@(#)ufs_inode.c	7.49 (Berkeley) 07/20/92
8  */
9 
10 #include <sys/param.h>
11 #include <sys/systm.h>
12 #include <sys/proc.h>
13 #include <sys/vnode.h>
14 #include <sys/mount.h>
15 #include <sys/kernel.h>
16 #include <sys/malloc.h>
17 
18 #include <ufs/ufs/quota.h>
19 #include <ufs/ufs/inode.h>
20 #include <ufs/ufs/ufsmount.h>
21 #include <ufs/ufs/ufs_extern.h>
22 
23 u_long	nextgennumber;		/* Next generation number to assign. */
24 int	prtactive = 0;		/* 1 => print out reclaim of active vnodes */
25 
26 int
27 ufs_init()
28 {
29 	static int first = 1;
30 
31 	if (!first)
32 		return (0);
33 	first = 0;
34 
35 #ifdef DIAGNOSTIC
36 	if ((sizeof(struct inode) - 1) & sizeof(struct inode))
37 		printf("ufs_init: bad size %d\n", sizeof(struct inode));
38 #endif
39 	ufs_ihashinit();
40 	dqinit();
41 	return (0);
42 }
43 
44 /*
45  * Unlock and decrement the reference count of an inode structure.
46  */
47 void
48 ufs_iput(ip)
49 	register struct inode *ip;
50 {
51 
52 	if ((ip->i_flag & ILOCKED) == 0)
53 		panic("iput");
54 	IUNLOCK(ip);
55 	vrele(ITOV(ip));
56 }
57 
58 /*
59  * Reclaim an inode so that it can be used for other purposes.
60  */
61 int
62 ufs_reclaim(ap)
63 	struct vop_reclaim_args /* {
64 		struct vnode *a_vp;
65 	} */ *ap;
66 {
67 	register struct vnode *vp = ap->a_vp;
68 	register struct inode *ip;
69 	int i, type;
70 
71 	if (prtactive && vp->v_usecount != 0)
72 		vprint("ufs_reclaim: pushing active", vp);
73 	/*
74 	 * Remove the inode from its hash chain.
75 	 */
76 	ip = VTOI(vp);
77 	ufs_ihashrem(ip);
78 	/*
79 	 * Purge old data structures associated with the inode.
80 	 */
81 	cache_purge(vp);
82 	if (ip->i_devvp) {
83 		vrele(ip->i_devvp);
84 		ip->i_devvp = 0;
85 	}
86 #ifdef QUOTA
87 	for (i = 0; i < MAXQUOTAS; i++) {
88 		if (ip->i_dquot[i] != NODQUOT) {
89 			dqrele(vp, ip->i_dquot[i]);
90 			ip->i_dquot[i] = NODQUOT;
91 		}
92 	}
93 #endif
94 	switch (vp->v_mount->mnt_stat.f_type) {
95 	case MOUNT_UFS:
96 		type = M_FFSNODE;
97 		break;
98 	case MOUNT_MFS:
99 		type = M_MFSNODE;
100 		break;
101 	case MOUNT_LFS:
102 		type = M_LFSNODE;
103 		break;
104 	default:
105 		panic("ufs_reclaim: not ufs file");
106 	}
107 	FREE(vp->v_data, type);
108 	vp->v_data = NULL;
109 	return (0);
110 }
111 
112 /*
113  * Lock an inode. If its already locked, set the WANT bit and sleep.
114  */
115 void
116 ufs_ilock(ip)
117 	register struct inode *ip;
118 {
119 	struct proc *p = curproc;	/* XXX */
120 
121 	while (ip->i_flag & ILOCKED) {
122 		ip->i_flag |= IWANT;
123 #ifdef DIAGNOSTIC
124 		if (p) {
125 			if (p->p_pid == ip->i_lockholder)
126 				panic("locking against myself");
127 			ip->i_lockwaiter = p->p_pid;
128 		}
129 #endif
130 		(void) sleep((caddr_t)ip, PINOD);
131 	}
132 #ifdef DIAGNOSTIC
133 	ip->i_lockwaiter = 0;
134 	if (p)
135 		ip->i_lockholder = p->p_pid;
136 #endif
137 	ip->i_flag |= ILOCKED;
138 }
139 
140 /*
141  * Unlock an inode.  If WANT bit is on, wakeup.
142  */
143 void
144 ufs_iunlock(ip)
145 	register struct inode *ip;
146 {
147 
148 	if ((ip->i_flag & ILOCKED) == 0)
149 		vprint("ufs_iunlock: unlocked inode", ITOV(ip));
150 #ifdef DIAGNOSTIC
151 	ip->i_lockholder = 0;
152 #endif
153 	ip->i_flag &= ~ILOCKED;
154 	if (ip->i_flag&IWANT) {
155 		ip->i_flag &= ~IWANT;
156 		wakeup((caddr_t)ip);
157 	}
158 }
159