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