Removed definition "LIB= rpc". We want libc.a to contain librpc.a, not
[unix-history] / .ref-386BSD-0.1-patchkit / usr / src / sys.386bsd / isofs / isofs_node.c
CommitLineData
7977dadd
WJ
1/*
2 * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * @(#)isofs_inode.c
23095ad6
JS
34 *
35 * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE
36 * -------------------- ----- ----------------------
37 * CURRENT PATCH LEVEL: 1 00151
38 * -------------------- ----- ----------------------
39 *
40 * 23 Apr 93 Jagane D Sundar support nfs exported isofs
7977dadd
WJ
41 */
42
43#include "param.h"
44#include "systm.h"
45#include "mount.h"
46#include "proc.h"
47#include "file.h"
48#include "buf.h"
49#include "vnode.h"
50#include "kernel.h"
51#include "malloc.h"
52
53#include "iso.h"
54#include "isofs_node.h"
55
56#define INOHSZ 512
57#if ((INOHSZ&(INOHSZ-1)) == 0)
58#define INOHASH(dev,ino) (((dev)+(ino))&(INOHSZ-1))
59#else
60#define INOHASH(dev,ino) (((unsigned)((dev)+(ino)))%INOHSZ)
61#endif
62
63union iso_ihead {
64 union iso_ihead *ih_head[2];
65 struct iso_node *ih_chain[2];
66} iso_ihead[INOHSZ];
67
68int prtactive; /* 1 => print out reclaim of active vnodes */
69
70/*
71 * Initialize hash links for inodes.
72 */
73isofs_init()
74{
75 register int i;
76 register union iso_ihead *ih = iso_ihead;
77
78#ifndef lint
79 if (VN_MAXPRIVATE < sizeof(struct iso_node))
80 panic("ihinit: too small");
81#endif /* not lint */
82 for (i = INOHSZ; --i >= 0; ih++) {
83 ih->ih_head[0] = ih;
84 ih->ih_head[1] = ih;
85 }
86}
87
88/*
89 * Look up a ISOFS dinode number to find its incore vnode.
90 * If it is not in core, read it in from the specified device.
91 * If it is in core, wait for the lock bit to clear, then
92 * return the inode locked. Detection and handling of mount
93 * points must be done by the calling routine.
94 */
95iso_iget(xp, ino, ipp, isodir)
96 struct iso_node *xp;
97 ino_t ino;
98 struct iso_node **ipp;
99 struct iso_directory_record *isodir;
100{
101 dev_t dev = xp->i_dev;
102 struct mount *mntp = ITOV(xp)->v_mount;
103 extern struct vnodeops isofs_vnodeops, spec_inodeops;
104 register struct iso_node *ip, *iq;
105 register struct vnode *vp;
106 struct vnode *nvp;
107 struct buf *bp;
108 struct dinode *dp;
109 union iso_ihead *ih;
110 int i, error;
111 struct iso_mnt *imp;
112
113 ih = &iso_ihead[INOHASH(dev, ino)];
114loop:
115 for (ip = ih->ih_chain[0];
116 ip != (struct iso_node *)ih;
117 ip = ip->i_forw) {
118 if (ino != ip->i_number || dev != ip->i_dev)
119 continue;
120 if ((ip->i_flag&ILOCKED) != 0) {
121 ip->i_flag |= IWANT;
122 sleep((caddr_t)ip, PINOD);
123 goto loop;
124 }
125 if (vget(ITOV(ip)))
126 goto loop;
127 *ipp = ip;
128 return(0);
129 }
130 /*
131 * Allocate a new inode.
132 */
133 if (error = getnewvnode(VT_ISOFS, mntp, &isofs_vnodeops, &nvp)) {
134 *ipp = 0;
135 return (error);
136 }
137 ip = VTOI(nvp);
138 ip->i_vnode = nvp;
139 ip->i_flag = 0;
140 ip->i_devvp = 0;
141 ip->i_diroff = 0;
23095ad6
JS
142 /* The following two are req for NFS FH. -Jagane D Sundar.- */
143 ip->iso_parent = xp->i_diroff; /* Parent directory's */
144 ip->iso_parent_ext = xp->iso_extent;
7977dadd
WJ
145 ip->i_lockf = 0;
146 /*
147 * Put it onto its hash chain and lock it so that other requests for
148 * this inode will block if they arrive while we are sleeping waiting
149 * for old data structures to be purged or for the contents of the
150 * disk portion of this inode to be read.
151 */
152 ip->i_dev = dev;
153 ip->i_number = ino;
154 insque(ip, ih);
155 ISO_ILOCK(ip);
156
157 ip->iso_reclen = isonum_711 (isodir->length);
158 ip->iso_extlen = isonum_711 (isodir->ext_attr_length);
159 ip->iso_extent = isonum_733 (isodir->extent);
160 ip->i_size = isonum_733 (isodir->size);
161 bcopy (isodir->date, ip->iso_time, sizeof ip->iso_time);
162 ip->iso_flags = isonum_711 (isodir->flags);
163 ip->iso_unit_size = isonum_711 (isodir->file_unit_size);
164 ip->iso_interleave_gap = isonum_711 (isodir->interleave);
165 ip->iso_volume_seq = isonum_723 (isodir->volume_sequence_number);
166 ip->iso_namelen = isonum_711 (isodir->name_len);
167
168 /*
169 * Initialize the associated vnode
170 */
171 vp = ITOV(ip);
172
173 if (ip->iso_flags & 2)
174 vp->v_type = VDIR;
175 else
176 vp->v_type = VREG;
177
178 imp = VFSTOISOFS (mntp);
179
180 if (ino == imp->root_extent)
181 vp->v_flag |= VROOT;
182 /*
183 * Finish inode initialization.
184 */
185 ip->i_mnt = imp;
186 ip->i_devvp = imp->im_devvp;
187 VREF(ip->i_devvp);
188 *ipp = ip;
189 return (0);
190}
191
192/*
193 * Unlock and decrement the reference count of an inode structure.
194 */
195iso_iput(ip)
196 register struct iso_node *ip;
197{
198
199 if ((ip->i_flag & ILOCKED) == 0)
200 panic("iso_iput");
201 ISO_IUNLOCK(ip);
202 vrele(ITOV(ip));
203}
204
205/*
206 * Last reference to an inode, write the inode out and if necessary,
207 * truncate and deallocate the file.
208 */
209isofs_inactive(vp, p)
210 struct vnode *vp;
211 struct proc *p;
212{
213 register struct iso_node *ip = VTOI(vp);
214 int mode, error = 0;
215
216 if (prtactive && vp->v_usecount != 0)
217 vprint("isofs_inactive: pushing active", vp);
218
219 ip->i_flag = 0;
220 /*
221 * If we are done with the inode, reclaim it
222 * so that it can be reused immediately.
223 */
224 if (vp->v_usecount == 0 /* && ip->i_mode == 0 */)
225 vgone(vp);
226 return (error);
227}
228
229/*
230 * Reclaim an inode so that it can be used for other purposes.
231 */
232isofs_reclaim(vp)
233 register struct vnode *vp;
234{
235 register struct iso_node *ip = VTOI(vp);
236 int i;
237
238 if (prtactive && vp->v_usecount != 0)
239 vprint("isofs_reclaim: pushing active", vp);
240 /*
241 * Remove the inode from its hash chain.
242 */
243 remque(ip);
244 ip->i_forw = ip;
245 ip->i_back = ip;
246 /*
247 * Purge old data structures associated with the inode.
248 */
249 cache_purge(vp);
250 if (ip->i_devvp) {
251 vrele(ip->i_devvp);
252 ip->i_devvp = 0;
253 }
254 ip->i_flag = 0;
255 return (0);
256}
257
258/*
259 * Lock an inode. If its already locked, set the WANT bit and sleep.
260 */
261iso_ilock(ip)
262 register struct iso_node *ip;
263{
264
265 while (ip->i_flag & ILOCKED) {
266 ip->i_flag |= IWANT;
267 if (ip->i_spare0 == curproc->p_pid)
268 panic("locking against myself");
269 ip->i_spare1 = curproc->p_pid;
270 (void) sleep((caddr_t)ip, PINOD);
271 }
272 ip->i_spare1 = 0;
273 ip->i_spare0 = curproc->p_pid;
274 ip->i_flag |= ILOCKED;
275}
276
277/*
278 * Unlock an inode. If WANT bit is on, wakeup.
279 */
280iso_iunlock(ip)
281 register struct iso_node *ip;
282{
283
284 if ((ip->i_flag & ILOCKED) == 0)
285 vprint("iso_iunlock: unlocked inode", ITOV(ip));
286 ip->i_spare0 = 0;
287 ip->i_flag &= ~ILOCKED;
288 if (ip->i_flag&IWANT) {
289 ip->i_flag &= ~IWANT;
290 wakeup((caddr_t)ip);
291 }
292}