|
|
1.1 root 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
34: */
35:
36: #include "param.h"
37: #include "systm.h"
38: #include "mount.h"
39: #include "proc.h"
40: #include "file.h"
41: #include "buf.h"
42: #include "vnode.h"
43: #include "kernel.h"
44: #include "malloc.h"
45:
46: #include "iso.h"
47: #include "isofs_node.h"
48:
49: #define INOHSZ 512
50: #if ((INOHSZ&(INOHSZ-1)) == 0)
51: #define INOHASH(dev,ino) (((dev)+(ino))&(INOHSZ-1))
52: #else
53: #define INOHASH(dev,ino) (((unsigned)((dev)+(ino)))%INOHSZ)
54: #endif
55:
56: union iso_ihead {
57: union iso_ihead *ih_head[2];
58: struct iso_node *ih_chain[2];
59: } iso_ihead[INOHSZ];
60:
61: int prtactive; /* 1 => print out reclaim of active vnodes */
62:
63: /*
64: * Initialize hash links for inodes.
65: */
66: isofs_init()
67: {
68: register int i;
69: register union iso_ihead *ih = iso_ihead;
70:
71: #ifndef lint
72: if (VN_MAXPRIVATE < sizeof(struct iso_node))
73: panic("ihinit: too small");
74: #endif /* not lint */
75: for (i = INOHSZ; --i >= 0; ih++) {
76: ih->ih_head[0] = ih;
77: ih->ih_head[1] = ih;
78: }
79: }
80:
81: /*
82: * Look up a ISOFS dinode number to find its incore vnode.
83: * If it is not in core, read it in from the specified device.
84: * If it is in core, wait for the lock bit to clear, then
85: * return the inode locked. Detection and handling of mount
86: * points must be done by the calling routine.
87: */
88: iso_iget(xp, ino, ipp, isodir)
89: struct iso_node *xp;
90: ino_t ino;
91: struct iso_node **ipp;
92: struct iso_directory_record *isodir;
93: {
94: dev_t dev = xp->i_dev;
95: struct mount *mntp = ITOV(xp)->v_mount;
96: extern struct vnodeops isofs_vnodeops, spec_inodeops;
97: register struct iso_node *ip, *iq;
98: register struct vnode *vp;
99: struct vnode *nvp;
100: struct buf *bp;
101: struct dinode *dp;
102: union iso_ihead *ih;
103: int i, error;
104: struct iso_mnt *imp;
105:
106: ih = &iso_ihead[INOHASH(dev, ino)];
107: loop:
108: for (ip = ih->ih_chain[0];
109: ip != (struct iso_node *)ih;
110: ip = ip->i_forw) {
111: if (ino != ip->i_number || dev != ip->i_dev)
112: continue;
113: if ((ip->i_flag&ILOCKED) != 0) {
114: ip->i_flag |= IWANT;
115: sleep((caddr_t)ip, PINOD);
116: goto loop;
117: }
118: if (vget(ITOV(ip)))
119: goto loop;
120: *ipp = ip;
121: return(0);
122: }
123: /*
124: * Allocate a new inode.
125: */
126: if (error = getnewvnode(VT_ISOFS, mntp, &isofs_vnodeops, &nvp)) {
127: *ipp = 0;
128: return (error);
129: }
130: ip = VTOI(nvp);
131: ip->i_vnode = nvp;
132: ip->i_flag = 0;
133: ip->i_devvp = 0;
134: ip->i_diroff = 0;
135: ip->i_lockf = 0;
136: /*
137: * Put it onto its hash chain and lock it so that other requests for
138: * this inode will block if they arrive while we are sleeping waiting
139: * for old data structures to be purged or for the contents of the
140: * disk portion of this inode to be read.
141: */
142: ip->i_dev = dev;
143: ip->i_number = ino;
144: insque(ip, ih);
145: ISO_ILOCK(ip);
146:
147: ip->iso_reclen = isonum_711 (isodir->length);
148: ip->iso_extlen = isonum_711 (isodir->ext_attr_length);
149: ip->iso_extent = isonum_733 (isodir->extent);
150: ip->i_size = isonum_733 (isodir->size);
151: bcopy (isodir->date, ip->iso_time, sizeof ip->iso_time);
152: ip->iso_flags = isonum_711 (isodir->flags);
153: ip->iso_unit_size = isonum_711 (isodir->file_unit_size);
154: ip->iso_interleave_gap = isonum_711 (isodir->interleave);
155: ip->iso_volume_seq = isonum_723 (isodir->volume_sequence_number);
156: ip->iso_namelen = isonum_711 (isodir->name_len);
157:
158: /*
159: * Initialize the associated vnode
160: */
161: vp = ITOV(ip);
162:
163: if (ip->iso_flags & 2)
164: vp->v_type = VDIR;
165: else
166: vp->v_type = VREG;
167:
168: imp = VFSTOISOFS (mntp);
169:
170: if (ino == imp->root_extent)
171: vp->v_flag |= VROOT;
172: /*
173: * Finish inode initialization.
174: */
175: ip->i_mnt = imp;
176: ip->i_devvp = imp->im_devvp;
177: VREF(ip->i_devvp);
178: *ipp = ip;
179: return (0);
180: }
181:
182: /*
183: * Unlock and decrement the reference count of an inode structure.
184: */
185: iso_iput(ip)
186: register struct iso_node *ip;
187: {
188:
189: if ((ip->i_flag & ILOCKED) == 0)
190: panic("iso_iput");
191: ISO_IUNLOCK(ip);
192: vrele(ITOV(ip));
193: }
194:
195: /*
196: * Last reference to an inode, write the inode out and if necessary,
197: * truncate and deallocate the file.
198: */
199: isofs_inactive(vp, p)
200: struct vnode *vp;
201: struct proc *p;
202: {
203: register struct iso_node *ip = VTOI(vp);
204: int mode, error = 0;
205:
206: if (prtactive && vp->v_usecount != 0)
207: vprint("isofs_inactive: pushing active", vp);
208:
209: ip->i_flag = 0;
210: /*
211: * If we are done with the inode, reclaim it
212: * so that it can be reused immediately.
213: */
214: if (vp->v_usecount == 0 /* && ip->i_mode == 0 */)
215: vgone(vp);
216: return (error);
217: }
218:
219: /*
220: * Reclaim an inode so that it can be used for other purposes.
221: */
222: isofs_reclaim(vp)
223: register struct vnode *vp;
224: {
225: register struct iso_node *ip = VTOI(vp);
226: int i;
227:
228: if (prtactive && vp->v_usecount != 0)
229: vprint("isofs_reclaim: pushing active", vp);
230: /*
231: * Remove the inode from its hash chain.
232: */
233: remque(ip);
234: ip->i_forw = ip;
235: ip->i_back = ip;
236: /*
237: * Purge old data structures associated with the inode.
238: */
239: cache_purge(vp);
240: if (ip->i_devvp) {
241: vrele(ip->i_devvp);
242: ip->i_devvp = 0;
243: }
244: ip->i_flag = 0;
245: return (0);
246: }
247:
248: /*
249: * Lock an inode. If its already locked, set the WANT bit and sleep.
250: */
251: iso_ilock(ip)
252: register struct iso_node *ip;
253: {
254:
255: while (ip->i_flag & ILOCKED) {
256: ip->i_flag |= IWANT;
257: if (ip->i_spare0 == curproc->p_pid)
258: panic("locking against myself");
259: ip->i_spare1 = curproc->p_pid;
260: (void) sleep((caddr_t)ip, PINOD);
261: }
262: ip->i_spare1 = 0;
263: ip->i_spare0 = curproc->p_pid;
264: ip->i_flag |= ILOCKED;
265: }
266:
267: /*
268: * Unlock an inode. If WANT bit is on, wakeup.
269: */
270: iso_iunlock(ip)
271: register struct iso_node *ip;
272: {
273:
274: if ((ip->i_flag & ILOCKED) == 0)
275: vprint("iso_iunlock: unlocked inode", ITOV(ip));
276: ip->i_spare0 = 0;
277: ip->i_flag &= ~ILOCKED;
278: if (ip->i_flag&IWANT) {
279: ip->i_flag &= ~IWANT;
280: wakeup((caddr_t)ip);
281: }
282: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.