ROOTINO is in common code
[unix-history] / usr / src / sys / ufs / ffs / ufs_inode.c
CommitLineData
da7c5cc6 1/*
cc050d2c 2 * Copyright (c) 1991 Regents of the University of California.
7188ac27 3 * All rights reserved.
da7c5cc6 4 *
b702c21d 5 * %sccs.include.redist.c%
7188ac27 6 *
cc050d2c 7 * @(#)ufs_inode.c 7.41 (Berkeley) %G%
da7c5cc6 8 */
5d5124a1 9
cc050d2c
KB
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>
5d5124a1 16
cc050d2c
KB
17#include <ufs/ufs/quota.h>
18#include <ufs/ufs/inode.h>
19#include <ufs/ufs/ufsmount.h>
20#include <ufs/ufs/ufs_extern.h>
c6f5111d 21
cc050d2c
KB
22u_long nextgennumber; /* Next generation number to assign. */
23int prtactive; /* 1 => print out reclaim of active vnodes */
3ebac878 24
cc050d2c 25int
1259a9f9 26ufs_init()
5d5124a1 27{
cc050d2c 28 static int first = 1;
5d5124a1 29
cc050d2c
KB
30 if (!first)
31 return (0);
32 first = 0;
2e64ab65 33
cc050d2c
KB
34#ifdef DIAGNOSTIC
35 if (VN_MAXPRIVATE < sizeof(struct inode))
36 panic("ufs_init: inode too small");
1259a9f9 37#endif
cc050d2c
KB
38 ufs_ihashinit();
39 dqinit();
7188ac27
KM
40 return (0);
41}
3ebac878 42
5d5124a1 43/*
a1e9dd57 44 * Unlock and decrement the reference count of an inode structure.
5d5124a1 45 */
cc050d2c
KB
46void
47ufs_iput(ip)
7494ef16 48 register struct inode *ip;
5d5124a1 49{
ff56f48a 50
5c2ba954 51 if ((ip->i_flag & ILOCKED) == 0)
ff56f48a 52 panic("iput");
a388503d 53 IUNLOCK(ip);
7188ac27 54 vrele(ITOV(ip));
ff56f48a
KM
55}
56
a1e9dd57
KM
57/*
58 * Last reference to an inode, write the inode out and if necessary,
59 * truncate and deallocate the file.
60 */
cc050d2c 61int
28708b72 62ufs_inactive(vp, p)
7188ac27 63 struct vnode *vp;
28708b72 64 struct proc *p;
ff56f48a 65{
cc050d2c
KB
66 register struct inode *ip;
67 struct ufsmount *ump;
68 int mode, error;
7188ac27 69
0811b508 70 if (prtactive && vp->v_usecount != 0)
e038406d 71 vprint("ufs_inactive: pushing active", vp);
cc050d2c
KB
72
73 /* Get rid of inodes related to stale file handles. */
74 ip = VTOI(vp);
1259a9f9 75 if (ip->i_mode == 0) {
e038406d
KM
76 if ((vp->v_flag & VXLOCK) == 0)
77 vgone(vp);
1259a9f9
KM
78 return (0);
79 }
cc050d2c
KB
80
81 error = 0;
82 ump = VFSTOUFS(vp->v_mount);
aed86454 83 ILOCK(ip);
82161bc8 84 if (ip->i_nlink <= 0 && (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
4b61628b
KM
85#ifdef QUOTA
86 if (!getinoquota(ip))
cc050d2c 87 (void)chkiq(ip, -1, NOCRED, 0);
4b61628b 88#endif
cc050d2c 89 error = (ump->um_itrunc)(ip, (u_long)0, 0);
7188ac27
KM
90 mode = ip->i_mode;
91 ip->i_mode = 0;
e9cacd5b 92 ip->i_rdev = 0;
7188ac27 93 ip->i_flag |= IUPD|ICHG;
cc050d2c 94 (ump->um_ifree)(ip, ip->i_number, mode);
7188ac27 95 }
cc050d2c
KB
96 if (ip->i_flag&(IUPD|IACC|ICHG|IMOD))
97 (ump->um_iupdat)(ip, &time, &time, 0);
d11dbec7
KM
98 IUNLOCK(ip);
99 ip->i_flag = 0;
7188ac27 100 /*
a1e9dd57
KM
101 * If we are done with the inode, reclaim it
102 * so that it can be reused immediately.
7188ac27 103 */
4b61628b 104 if (vp->v_usecount == 0 && ip->i_mode == 0)
d11dbec7 105 vgone(vp);
7188ac27 106 return (error);
5d5124a1
BJ
107}
108
109/*
a1e9dd57
KM
110 * Reclaim an inode so that it can be used for other purposes.
111 */
cc050d2c 112int
a1e9dd57
KM
113ufs_reclaim(vp)
114 register struct vnode *vp;
115{
cc050d2c 116 register struct inode *ip;
4b61628b 117 int i;
a1e9dd57 118
0811b508 119 if (prtactive && vp->v_usecount != 0)
e038406d 120 vprint("ufs_reclaim: pushing active", vp);
a1e9dd57
KM
121 /*
122 * Remove the inode from its hash chain.
123 */
cc050d2c 124 ip = VTOI(vp);
a1e9dd57
KM
125 remque(ip);
126 ip->i_forw = ip;
127 ip->i_back = ip;
128 /*
129 * Purge old data structures associated with the inode.
130 */
131 cache_purge(vp);
132 if (ip->i_devvp) {
133 vrele(ip->i_devvp);
134 ip->i_devvp = 0;
135 }
136#ifdef QUOTA
4b61628b
KM
137 for (i = 0; i < MAXQUOTAS; i++) {
138 if (ip->i_dquot[i] != NODQUOT) {
139 dqrele(vp, ip->i_dquot[i]);
140 ip->i_dquot[i] = NODQUOT;
141 }
142 }
a1e9dd57 143#endif
a1e9dd57
KM
144 ip->i_flag = 0;
145 return (0);
146}
147
d6a210b8 148/*
7494ef16 149 * Lock an inode. If its already locked, set the WANT bit and sleep.
d6a210b8 150 */
cc050d2c
KB
151void
152ufs_ilock(ip)
7494ef16 153 register struct inode *ip;
d6a210b8
BJ
154{
155
7188ac27
KM
156 while (ip->i_flag & ILOCKED) {
157 ip->i_flag |= IWANT;
c6f5111d 158 if (ip->i_spare0 == curproc->p_pid)
71c4cb8d 159 panic("locking against myself");
c6f5111d 160 ip->i_spare1 = curproc->p_pid;
7188ac27
KM
161 (void) sleep((caddr_t)ip, PINOD);
162 }
71c4cb8d 163 ip->i_spare1 = 0;
c6f5111d 164 ip->i_spare0 = curproc->p_pid;
7188ac27 165 ip->i_flag |= ILOCKED;
7032a385 166 curproc->p_spare[2]++;
d6a210b8
BJ
167}
168
169/*
7494ef16 170 * Unlock an inode. If WANT bit is on, wakeup.
d6a210b8 171 */
cc050d2c
KB
172void
173ufs_iunlock(ip)
7494ef16 174 register struct inode *ip;
d6a210b8
BJ
175{
176
7188ac27 177 if ((ip->i_flag & ILOCKED) == 0)
cc050d2c 178 vprint("ufs_iunlock: unlocked inode", ITOV(ip));
71c4cb8d 179 ip->i_spare0 = 0;
7188ac27 180 ip->i_flag &= ~ILOCKED;
7032a385 181 curproc->p_spare[2]--;
7188ac27
KM
182 if (ip->i_flag&IWANT) {
183 ip->i_flag &= ~IWANT;
184 wakeup((caddr_t)ip);
185 }
186}