Annotation of Net2/isofs/isofs_node.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.