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