xref: /original-bsd/sys/ufs/ufs/ufs_inode.c (revision 13ec26c3)
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.47 (Berkeley) 06/04/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 *ap;
64 {
65 	register struct vnode *vp = ap->a_vp;
66 	register struct inode *ip;
67 	int i, type;
68 
69 	if (prtactive && vp->v_usecount != 0)
70 		vprint("ufs_reclaim: pushing active", vp);
71 	/*
72 	 * Remove the inode from its hash chain.
73 	 */
74 	ip = VTOI(vp);
75 	remque(ip);
76 	/*
77 	 * Purge old data structures associated with the inode.
78 	 */
79 	cache_purge(vp);
80 	if (ip->i_devvp) {
81 		vrele(ip->i_devvp);
82 		ip->i_devvp = 0;
83 	}
84 #ifdef QUOTA
85 	for (i = 0; i < MAXQUOTAS; i++) {
86 		if (ip->i_dquot[i] != NODQUOT) {
87 			dqrele(vp, ip->i_dquot[i]);
88 			ip->i_dquot[i] = NODQUOT;
89 		}
90 	}
91 #endif
92 	switch (vp->v_mount->mnt_stat.f_type) {
93 	case MOUNT_UFS:
94 		type = M_FFSNODE;
95 		break;
96 	case MOUNT_MFS:
97 		type = M_MFSNODE;
98 		break;
99 	case MOUNT_LFS:
100 		type = M_LFSNODE;
101 		break;
102 	default:
103 		panic("ufs_reclaim: not ufs file");
104 	}
105 	FREE(vp->v_data, type);
106 	vp->v_data = NULL;
107 	return (0);
108 }
109 
110 /*
111  * Lock an inode. If its already locked, set the WANT bit and sleep.
112  */
113 void
114 ufs_ilock(ip)
115 	register struct inode *ip;
116 {
117 	struct proc *p = curproc;	/* XXX */
118 
119 	while (ip->i_flag & ILOCKED) {
120 		ip->i_flag |= IWANT;
121 #ifdef DIAGNOSTIC
122 		if (p) {
123 			if (p->p_pid == ip->i_lockholder)
124 				panic("locking against myself");
125 			ip->i_lockwaiter = p->p_pid;
126 		}
127 #endif
128 		(void) sleep((caddr_t)ip, PINOD);
129 	}
130 #ifdef DIAGNOSTIC
131 	ip->i_lockwaiter = 0;
132 	if (p)
133 		ip->i_lockholder = p->p_pid;
134 #endif
135 	ip->i_flag |= ILOCKED;
136 }
137 
138 /*
139  * Unlock an inode.  If WANT bit is on, wakeup.
140  */
141 void
142 ufs_iunlock(ip)
143 	register struct inode *ip;
144 {
145 
146 	if ((ip->i_flag & ILOCKED) == 0)
147 		vprint("ufs_iunlock: unlocked inode", ITOV(ip));
148 #ifdef DIAGNOSTIC
149 	ip->i_lockholder = 0;
150 #endif
151 	ip->i_flag &= ~ILOCKED;
152 	if (ip->i_flag&IWANT) {
153 		ip->i_flag &= ~IWANT;
154 		wakeup((caddr_t)ip);
155 	}
156 }
157