Commit | Line | Data |
---|---|---|
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 |
22 | u_long nextgennumber; /* Next generation number to assign. */ |
23 | int prtactive; /* 1 => print out reclaim of active vnodes */ | |
3ebac878 | 24 | |
cc050d2c | 25 | int |
1259a9f9 | 26 | ufs_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 |
46 | void |
47 | ufs_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 | 61 | int |
28708b72 | 62 | ufs_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 | 112 | int |
a1e9dd57 KM |
113 | ufs_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 |
151 | void |
152 | ufs_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 |
172 | void |
173 | ufs_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 | } |