|
|
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.