Annotation of XNU/bsd/isofs/cd9660/cd9660_vnops.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * The contents of this file constitute Original Code as defined in and
        !             7:  * are subject to the Apple Public Source License Version 1.1 (the
        !             8:  * "License").  You may not use this file except in compliance with the
        !             9:  * License.  Please obtain a copy of the License at
        !            10:  * http://www.apple.com/publicsource and read it before using this file.
        !            11:  * 
        !            12:  * This Original Code and all software distributed under the License are
        !            13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            17:  * License for the specific language governing rights and limitations
        !            18:  * under the License.
        !            19:  * 
        !            20:  * @APPLE_LICENSE_HEADER_END@
        !            21:  */
        !            22: /*     $NetBSD: cd9660_vnops.c,v 1.22 1994/12/27 19:05:12 mycroft Exp $        */
        !            23: 
        !            24: /*-
        !            25:  * Copyright (c) 1994
        !            26:  *     The Regents of the University of California.  All rights reserved.
        !            27:  *
        !            28:  * This code is derived from software contributed to Berkeley
        !            29:  * by Pace Willisson ([email protected]).  The Rock Ridge Extension
        !            30:  * Support code is derived from software contributed to Berkeley
        !            31:  * by Atsushi Murai ([email protected]).
        !            32:  *
        !            33:  * Redistribution and use in source and binary forms, with or without
        !            34:  * modification, are permitted provided that the following conditions
        !            35:  * are met:
        !            36:  * 1. Redistributions of source code must retain the above copyright
        !            37:  *    notice, this list of conditions and the following disclaimer.
        !            38:  * 2. Redistributions in binary form must reproduce the above copyright
        !            39:  *    notice, this list of conditions and the following disclaimer in the
        !            40:  *    documentation and/or other materials provided with the distribution.
        !            41:  * 3. All advertising materials mentioning features or use of this software
        !            42:  *    must display the following acknowledgement:
        !            43:  *     This product includes software developed by the University of
        !            44:  *     California, Berkeley and its contributors.
        !            45:  * 4. Neither the name of the University nor the names of its contributors
        !            46:  *    may be used to endorse or promote products derived from this software
        !            47:  *    without specific prior written permission.
        !            48:  *
        !            49:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            50:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            51:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            52:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            53:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            54:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            55:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            56:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            57:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            58:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            59:  * SUCH DAMAGE.
        !            60:  *
        !            61:  *     @(#)cd9660_vnops.c      8.15 (Berkeley) 12/5/94
        !            62:  *
        !            63:  * HISTORY
        !            64:  * 02-Feb-00   chw             Add cd9660_copyfile to return error
        !            65:  * 29-Sep-98   djb             Add cd9660_getattrlist VOP for VDI support.
        !            66:  * 15-sep-98   added cd9660_rmdir to do proper unlocking - chw
        !            67:  * 12-aug-98   added cd9660_remove which will do proper unlocking - chw
        !            68:  * 17-Feb-98   radar 1669467 - changed lock protocols to use the lock manager - chw
        !            69:  * 22-Jan-98   radar 1669467 - ISO 9660 CD support - jwc
        !            70:  */
        !            71: 
        !            72: #include <sys/param.h>
        !            73: #include <sys/systm.h>
        !            74: #include <sys/namei.h>
        !            75: #include <sys/resourcevar.h>
        !            76: #include <sys/kernel.h>
        !            77: #include <sys/file.h>
        !            78: #include <sys/stat.h>
        !            79: #include <sys/buf.h>
        !            80: #include <sys/proc.h>
        !            81: #include <sys/conf.h>
        !            82: #include <sys/mount.h>
        !            83: #include <sys/vnode.h>
        !            84: #include <miscfs/specfs/specdev.h>
        !            85: #include <miscfs/fifofs/fifo.h>
        !            86: #include <sys/malloc.h>
        !            87: #include <sys/dir.h>
        !            88: #include <sys/attr.h>
        !            89: #include <vfs/vfs_support.h>
        !            90: 
        !            91: // radar 1669467  Using the lock manager now so include lock.h
        !            92: #include <sys/lock.h>
        !            93: 
        !            94: #include <isofs/cd9660/iso.h>
        !            95: #include <isofs/cd9660/cd9660_node.h>
        !            96: #include <isofs/cd9660/iso_rrip.h>
        !            97: 
        !            98: 
        !            99: #if 0
        !           100: /*
        !           101:  * Mknod vnode call
        !           102:  *  Actually remap the device number
        !           103:  */
        !           104: cd9660_mknod(ndp, vap, cred, p)
        !           105:        struct nameidata *ndp;
        !           106:        struct ucred *cred;
        !           107:        struct vattr *vap;
        !           108:        struct proc *p;
        !           109: {
        !           110: #ifndef        ISODEVMAP
        !           111:        FREE_ZONE(ndp->ni_pnbuf, ndp->ni_pnlen, M_NAMEI);
        !           112:        vput(ndp->ni_dvp);
        !           113:        vput(ndp->ni_vp);
        !           114:        return (EINVAL);
        !           115: #else
        !           116:        register struct vnode *vp;
        !           117:        struct iso_node *ip;
        !           118:        struct iso_dnode *dp;
        !           119:        int error;
        !           120: 
        !           121:        vp = ndp->ni_vp;
        !           122:        ip = VTOI(vp);
        !           123: 
        !           124:        if (ip->i_mnt->iso_ftype != ISO_FTYPE_RRIP
        !           125:            || vap->va_type != vp->v_type
        !           126:            || (vap->va_type != VCHR && vap->va_type != VBLK)) {
        !           127:                FREE_ZONE(ndp->ni_pnbuf, ndp->ni_pnlen, M_NAMEI);
        !           128:                vput(ndp->ni_dvp);
        !           129:                vput(ndp->ni_vp);
        !           130:                return (EINVAL);
        !           131:        }
        !           132: 
        !           133:        dp = iso_dmap(ip->i_dev,ip->i_number,1);
        !           134:        if (ip->inode.iso_rdev == vap->va_rdev || vap->va_rdev == VNOVAL) {
        !           135:                /* same as the unmapped one, delete the mapping */
        !           136:                remque(dp);
        !           137:                FREE(dp,M_CACHE);
        !           138:        } else
        !           139:                /* enter new mapping */
        !           140:                dp->d_dev = vap->va_rdev;
        !           141: 
        !           142:        /*
        !           143:         * Remove inode so that it will be reloaded by iget and
        !           144:         * checked to see if it is an alias of an existing entry
        !           145:         * in the inode cache.
        !           146:         */
        !           147:        vput(vp);
        !           148:        vp->v_type = VNON;
        !           149:        vgone(vp);
        !           150:        return (0);
        !           151: #endif
        !           152: }
        !           153: #endif
        !           154: 
        !           155: /*
        !           156:  * Open called.
        !           157:  *
        !           158:  * Nothing to do.
        !           159:  */
        !           160: /* ARGSUSED */
        !           161: int
        !           162: cd9660_open(ap)
        !           163:        struct vop_open_args /* {
        !           164:                struct vnode *a_vp;
        !           165:                int  a_mode;
        !           166:                struct ucred *a_cred;
        !           167:                struct proc *a_p;
        !           168:        } */ *ap;
        !           169: {
        !           170:        return (0);
        !           171: }
        !           172: 
        !           173: /*
        !           174:  * Close called
        !           175:  *
        !           176:  * Update the times on the inode on writeable file systems.
        !           177:  */
        !           178: /* ARGSUSED */
        !           179: int
        !           180: cd9660_close(ap)
        !           181:        struct vop_close_args /* {
        !           182:                struct vnode *a_vp;
        !           183:                int  a_fflag;
        !           184:                struct ucred *a_cred;
        !           185:                struct proc *a_p;
        !           186:        } */ *ap;
        !           187: {
        !           188:        return (0);
        !           189: }
        !           190: 
        !           191: /*
        !           192:  * Check mode permission on inode pointer. Mode is READ, WRITE or EXEC.
        !           193:  * The mode is shifted to select the owner/group/other fields. The
        !           194:  * super user is granted all permissions.
        !           195:  */
        !           196: /* ARGSUSED */
        !           197: int
        !           198: cd9660_access(ap)
        !           199:        struct vop_access_args /* {
        !           200:                struct vnode *a_vp;
        !           201:                int  a_mode;
        !           202:                struct ucred *a_cred;
        !           203:                struct proc *a_p;
        !           204:        } */ *ap;
        !           205: {
        !           206:        struct vnode *vp = ap->a_vp;
        !           207:        struct iso_node *ip = VTOI(vp);
        !           208:        struct ucred *cred = ap->a_cred;
        !           209:        mode_t mask, mode = ap->a_mode;
        !           210:        register gid_t *gp;
        !           211:        int i, error;
        !           212: 
        !           213:        /*
        !           214:         * Disallow write attempts on read-only file systems;
        !           215:         * unless the file is a socket, fifo, or a block or
        !           216:         * character device resident on the file system.
        !           217:         */
        !           218:        if (mode & VWRITE) {
        !           219:                switch (vp->v_type) {
        !           220:                case VDIR:
        !           221:                case VLNK:
        !           222:                case VREG:
        !           223:                        if (vp->v_mount->mnt_flag & MNT_RDONLY)
        !           224:                                return (EROFS);
        !           225: #if QUOTA
        !           226:                        if ( (error = getinoquota(ip)) )
        !           227:                                return (error);
        !           228: #endif
        !           229:                        break;
        !           230:                default:        // radar 1669467 - fix compiler warning
        !           231:                        break;
        !           232:                }
        !           233:        }
        !           234: 
        !           235:        /* If immutable bit set, nobody gets to write it. */
        !           236:        if ((mode & VWRITE) && (ip->i_flag & IMMUTABLE))
        !           237:                return (EPERM);
        !           238: 
        !           239:        /* Otherwise, user id 0 always gets access. */
        !           240:        if (cred->cr_uid == 0)
        !           241:                return (0);
        !           242: 
        !           243:        mask = 0;
        !           244: 
        !           245:        /* Otherwise, check the owner. */
        !           246:        if (cred->cr_uid == ip->inode.iso_uid) {
        !           247:                if (mode & VEXEC)
        !           248:                        mask |= S_IXUSR;
        !           249:                if (mode & VREAD)
        !           250:                        mask |= S_IRUSR;
        !           251:                if (mode & VWRITE)
        !           252:                        mask |= S_IWUSR;
        !           253:                return ((ip->inode.iso_mode & mask) == mask ? 0 : EACCES);
        !           254:        }
        !           255: 
        !           256:        /* Otherwise, check the groups. */
        !           257:        for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++)
        !           258:                if (ip->inode.iso_gid == *gp) {
        !           259:                        if (mode & VEXEC)
        !           260:                                mask |= S_IXGRP;
        !           261:                        if (mode & VREAD)
        !           262:                                mask |= S_IRGRP;
        !           263:                        if (mode & VWRITE)
        !           264:                                mask |= S_IWGRP;
        !           265:                        return ((ip->inode.iso_mode & mask) == mask ? 0 : EACCES);
        !           266:                }
        !           267: 
        !           268:        /* Otherwise, check everyone else. */
        !           269:        if (mode & VEXEC)
        !           270:                mask |= S_IXOTH;
        !           271:        if (mode & VREAD)
        !           272:                mask |= S_IROTH;
        !           273:        if (mode & VWRITE)
        !           274:                mask |= S_IWOTH;
        !           275:        return ((ip->inode.iso_mode & mask) == mask ? 0 : EACCES);
        !           276: }
        !           277: 
        !           278: int
        !           279: cd9660_getattr(ap)
        !           280:        struct vop_getattr_args /* {
        !           281:                struct vnode *a_vp;
        !           282:                struct vattr *a_vap;
        !           283:                struct ucred *a_cred;
        !           284:                struct proc *a_p;
        !           285:        } */ *ap;
        !           286: 
        !           287: {
        !           288:        struct vnode *vp = ap->a_vp;
        !           289:        register struct vattr *vap = ap->a_vap;
        !           290:        register struct iso_node *ip = VTOI(vp);
        !           291: 
        !           292:        vap->va_fsid    = ip->i_dev;
        !           293:        vap->va_fileid  = ip->i_number;
        !           294: 
        !           295:        vap->va_mode    = ip->inode.iso_mode;
        !           296:        vap->va_nlink   = ip->inode.iso_links;
        !           297:        vap->va_uid     = ip->inode.iso_uid;
        !           298:        vap->va_gid     = ip->inode.iso_gid;
        !           299:        vap->va_atime   = ip->inode.iso_atime;
        !           300:        vap->va_mtime   = ip->inode.iso_mtime;
        !           301:        vap->va_ctime   = ip->inode.iso_ctime;
        !           302:        vap->va_rdev    = ip->inode.iso_rdev;
        !           303: 
        !           304:        vap->va_size    = (u_quad_t) ip->i_size;
        !           305:        if (ip->i_size == 0 && (vap->va_mode & S_IFMT) == S_IFLNK) {
        !           306:                struct vop_readlink_args rdlnk;
        !           307:                struct iovec aiov;
        !           308:                struct uio auio;
        !           309:                char *cp;
        !           310: 
        !           311:                MALLOC(cp, char *, MAXPATHLEN, M_TEMP, M_WAITOK);
        !           312:                aiov.iov_base = cp;
        !           313:                aiov.iov_len = MAXPATHLEN;
        !           314:                auio.uio_iov = &aiov;
        !           315:                auio.uio_iovcnt = 1;
        !           316:                auio.uio_offset = 0;
        !           317:                auio.uio_rw = UIO_READ;
        !           318:                auio.uio_segflg = UIO_SYSSPACE;
        !           319:                auio.uio_procp = ap->a_p;
        !           320:                auio.uio_resid = MAXPATHLEN;
        !           321:                rdlnk.a_uio = &auio;
        !           322:                rdlnk.a_vp = ap->a_vp;
        !           323:                rdlnk.a_cred = ap->a_cred;
        !           324:                if (cd9660_readlink(&rdlnk) == 0)
        !           325:                        vap->va_size = MAXPATHLEN - auio.uio_resid;
        !           326:                FREE(cp, M_TEMP);
        !           327:        }
        !           328:        vap->va_flags   = 0;
        !           329:        vap->va_gen = 1;
        !           330:        vap->va_blocksize = ip->i_mnt->logical_block_size;
        !           331:        vap->va_bytes   = (u_quad_t) ip->i_size;
        !           332:        vap->va_type    = vp->v_type;
        !           333: 
        !           334:        return (0);
        !           335: }
        !           336: 
        !           337: #if ISO_DEFAULT_BLOCK_SIZE >= NBPG
        !           338: #ifdef DEBUG
        !           339: extern int doclusterread;
        !           340: #else
        !           341: #define doclusterread 1
        !           342: #endif
        !           343: #else
        !           344: /* XXX until cluster routines can handle block sizes less than one page */
        !           345: #define doclusterread 0
        !           346: #endif
        !           347: 
        !           348: /*
        !           349:  * Vnode op for reading.
        !           350:  */
        !           351: int
        !           352: cd9660_read(ap)
        !           353:        struct vop_read_args /* {
        !           354:                struct vnode *a_vp;
        !           355:                struct uio *a_uio;
        !           356:                int a_ioflag;
        !           357:                struct ucred *a_cred;
        !           358:        } */ *ap;
        !           359: {
        !           360:        struct vnode *vp = ap->a_vp;
        !           361:        register struct uio *uio = ap->a_uio;
        !           362:        register struct iso_node *ip = VTOI(vp);
        !           363:        register struct iso_mnt *imp;
        !           364:        struct buf *bp;
        !           365:        daddr_t lbn, rablock;
        !           366:        off_t diff;
        !           367:        int rasize, error = 0;
        !           368:        long size, n, on;
        !           369: #ifdef NeXT
        !           370:        int firstpass;
        !           371:        int seq;
        !           372:        int devBlockSize;
        !           373: #endif /* NeXT */
        !           374: 
        !           375:        if (uio->uio_resid == 0)
        !           376:                return (0);
        !           377:        if (uio->uio_offset < 0)
        !           378:                return (EINVAL);
        !           379:        ip->i_flag |= IN_ACCESS;
        !           380:        imp = ip->i_mnt;
        !           381: #ifdef NeXT 
        !           382:        firstpass=TRUE;
        !           383:        VOP_DEVBLOCKSIZE(ip->i_devvp, &devBlockSize);
        !           384: #endif /* NeXT */
        !           385:        do {
        !           386:                lbn = lblkno(imp, uio->uio_offset);
        !           387:                on = blkoff(imp, uio->uio_offset);
        !           388:                n = min((u_int)(imp->logical_block_size - on),
        !           389:                        uio->uio_resid);
        !           390:                diff = (off_t)ip->i_size - uio->uio_offset;
        !           391:                if (diff <= 0)
        !           392:                        return (0);
        !           393:                if (diff < n)
        !           394:                        n = diff;
        !           395:                size = blksize(imp, ip, lbn);
        !           396:                rablock = lbn + 1;
        !           397:                if (doclusterread) {
        !           398:                        if (lblktosize(imp, rablock) <= ip->i_size)
        !           399: #ifdef NeXT
        !           400:                                error = cluster_read(vp, (off_t)ip->i_size,
        !           401:                                   lbn, size, NOCRED, &bp, devBlockSize,
        !           402:                                     firstpass, (uio->uio_resid + on), &seq);
        !           403: #else
        !           404:                                error = cluster_read(vp, (off_t)ip->i_size,
        !           405:                                                     lbn, size, NOCRED, &bp);
        !           406: #endif /* NeXT */
        !           407:                        else
        !           408:                                error = bread(vp, lbn, size, NOCRED, &bp);
        !           409:                } else {
        !           410:                        if (vp->v_lastr + 1 == lbn &&
        !           411:                            lblktosize(imp, rablock) < ip->i_size) {
        !           412:                                rasize = blksize(imp, ip, rablock);
        !           413:                                error = breadn(vp, lbn, size, &rablock,
        !           414:                                               &rasize, 1, NOCRED, &bp);
        !           415:                        } else
        !           416:                                error = bread(vp, lbn, size, NOCRED, &bp);
        !           417:                }
        !           418:                vp->v_lastr = lbn;
        !           419:                n = min(n, size - bp->b_resid);
        !           420:                if (error) {
        !           421:                        brelse(bp);
        !           422:                        return (error);
        !           423:                }
        !           424: 
        !           425:                error = uiomove(bp->b_data + on, (int)n, uio);
        !           426:                if (n + on == imp->logical_block_size ||
        !           427:                    uio->uio_offset == (off_t)ip->i_size)
        !           428:                        bp->b_flags |= B_AGE;
        !           429:                brelse(bp);
        !           430:        firstpass = FALSE;
        !           431:        } while (error == 0 && uio->uio_resid > 0 && n != 0);
        !           432:        return (error);
        !           433: }
        !           434: 
        !           435: /* ARGSUSED */
        !           436: int
        !           437: cd9660_ioctl(ap)
        !           438:        struct vop_ioctl_args /* {
        !           439:                struct vnode *a_vp;
        !           440:                u_long a_command;
        !           441:                caddr_t  a_data;
        !           442:                int  a_fflag;
        !           443:                struct ucred *a_cred;
        !           444:                struct proc *a_p;
        !           445:        } */ *ap;
        !           446: {
        !           447:        printf("You did ioctl for isofs !!\n");
        !           448:        return (ENOTTY);
        !           449: }
        !           450: 
        !           451: /* ARGSUSED */
        !           452: int
        !           453: cd9660_select(ap)
        !           454:        struct vop_select_args /* {
        !           455:                struct vnode *a_vp;
        !           456:                int  a_which;
        !           457:                int  a_fflags;
        !           458:                struct ucred *a_cred;
        !           459:                struct proc *a_p;
        !           460:        } */ *ap;
        !           461: {
        !           462:        /*
        !           463:         * We should really check to see if I/O is possible.
        !           464:         */
        !           465:        return (1);
        !           466: }
        !           467: 
        !           468: /*
        !           469:  * Mmap a file
        !           470:  *
        !           471:  * NB Currently unsupported.
        !           472:  */
        !           473: /* ARGSUSED */
        !           474: int
        !           475: cd9660_mmap(ap)
        !           476:        struct vop_mmap_args /* {
        !           477:                struct vnode *a_vp;
        !           478:                int  a_fflags;
        !           479:                struct ucred *a_cred;
        !           480:                struct proc *a_p;
        !           481:        } */ *ap;
        !           482: {
        !           483: 
        !           484:        return (EINVAL);
        !           485: }
        !           486: 
        !           487: /*
        !           488:  * Seek on a file
        !           489:  *
        !           490:  * Nothing to do, so just return.
        !           491:  */
        !           492: /* ARGSUSED */
        !           493: int
        !           494: cd9660_seek(ap)
        !           495:        struct vop_seek_args /* {
        !           496:                struct vnode *a_vp;
        !           497:                off_t  a_oldoff;
        !           498:                off_t  a_newoff;
        !           499:                struct ucred *a_cred;
        !           500:        } */ *ap;
        !           501: {
        !           502: 
        !           503:        return (0);
        !           504: }
        !           505: 
        !           506: /*
        !           507:  * Structure for reading directories
        !           508:  */
        !           509: struct isoreaddir {
        !           510:        struct dirent saveent;
        !           511:        struct dirent assocent;
        !           512:        struct dirent current;
        !           513:        off_t saveoff;
        !           514:        off_t assocoff;
        !           515:        off_t curroff;
        !           516:        struct uio *uio;
        !           517:        off_t uio_off;
        !           518:        int eofflag;
        !           519: //     u_long **cookies;
        !           520: //     int *ncookies;
        !           521: };
        !           522: 
        !           523: int
        !           524: iso_uiodir(idp,dp,off)
        !           525:        struct isoreaddir *idp;
        !           526:        struct dirent *dp;
        !           527:        off_t off;
        !           528: {
        !           529:        int error;
        !           530: 
        !           531:        dp->d_name[dp->d_namlen] = 0;
        !           532:        dp->d_reclen = DIRSIZ(dp);
        !           533: 
        !           534:        if (idp->uio->uio_resid < dp->d_reclen) {
        !           535:                idp->eofflag = 0;
        !           536:                return (-1);
        !           537:        }
        !           538: 
        !           539: #if 0
        !           540:        if (idp->cookies) {
        !           541:                if (*idp->ncookies <= 0) {
        !           542:                        idp->eofflag = 0;
        !           543:                        return (-1);
        !           544:                }
        !           545: 
        !           546:                **idp->cookies++ = off;
        !           547:                --*idp->ncookies;
        !           548:        }
        !           549: #endif
        !           550: 
        !           551:        if ( (error = uiomove( (caddr_t)dp, dp->d_reclen, idp->uio )) )
        !           552:                return (error);
        !           553:        idp->uio_off = off;
        !           554:        return (0);
        !           555: }
        !           556: 
        !           557: int
        !           558: iso_shipdir(idp)
        !           559:        struct isoreaddir *idp;
        !           560: {
        !           561:        struct dirent *dp;
        !           562:        int cl, sl, assoc;
        !           563:        int error;
        !           564:        char *cname, *sname;
        !           565: 
        !           566:        cl = idp->current.d_namlen;
        !           567:        cname = idp->current.d_name;
        !           568:        assoc = (cl > 1) && (*cname == ASSOCCHAR );
        !           569:        if (assoc)  {
        !           570:                cl--;
        !           571:                cname++;
        !           572:        }
        !           573: 
        !           574:        dp = &idp->saveent;
        !           575:        sname = dp->d_name;
        !           576:        if (!(sl = dp->d_namlen)) {
        !           577:                dp = &idp->assocent;
        !           578:                sname = dp->d_name + 1;
        !           579:                sl = dp->d_namlen - 1;
        !           580:        }
        !           581:        if (sl > 0) {
        !           582:                if (sl != cl
        !           583:                    || bcmp(sname,cname,sl)) {
        !           584:                        if (idp->assocent.d_namlen) {
        !           585:                                if ( (error = iso_uiodir(idp,&idp->assocent,idp->assocoff)) )
        !           586:                                        return (error);
        !           587:                                idp->assocent.d_namlen = 0;
        !           588:                        }
        !           589:                        if (idp->saveent.d_namlen) {
        !           590:                                if ( (error = iso_uiodir(idp,&idp->saveent,idp->saveoff)) )
        !           591:                                        return (error);
        !           592:                                idp->saveent.d_namlen = 0;
        !           593:                        }
        !           594:                }
        !           595:        }
        !           596:        idp->current.d_reclen = DIRSIZ(&idp->current);
        !           597:        if (assoc) {
        !           598:                idp->assocoff = idp->curroff;
        !           599:                bcopy(&idp->current,&idp->assocent,idp->current.d_reclen);
        !           600:        } else {
        !           601:                idp->saveoff = idp->curroff;
        !           602:                bcopy(&idp->current,&idp->saveent,idp->current.d_reclen);
        !           603:        }
        !           604:        return (0);
        !           605: }
        !           606: 
        !           607: /*
        !           608:  * Vnode op for readdir
        !           609:  */
        !           610: int
        !           611: cd9660_readdir(ap)
        !           612:        struct vop_readdir_args /* {
        !           613:                struct vnodeop_desc *a_desc;
        !           614:                struct vnode *a_vp;
        !           615:                struct uio *a_uio;
        !           616:                struct ucred *a_cred;
        !           617:                int *a_eofflag;
        !           618:                int *a_ncookies;
        !           619:                u_long **a_cookies;
        !           620:        } */ *ap;
        !           621: {
        !           622:        register struct uio *uio = ap->a_uio;
        !           623:        off_t startingOffset = uio->uio_offset;
        !           624:        size_t lost = 0;
        !           625:        struct isoreaddir *idp;
        !           626:        struct vnode *vdp = ap->a_vp;
        !           627:        struct iso_node *dp;
        !           628:        struct iso_mnt *imp;
        !           629:        struct buf *bp = NULL;
        !           630:        struct iso_directory_record *ep;
        !           631:        int entryoffsetinblock;
        !           632:        doff_t endsearch;
        !           633:        u_long bmask;
        !           634:        int error = 0;
        !           635:        int reclen;
        !           636:        u_short namelen;
        !           637: 
        !           638:        dp = VTOI(vdp);
        !           639:        imp = dp->i_mnt;
        !           640:        bmask = imp->im_bmask;
        !           641: 
        !           642:        MALLOC(idp, struct isoreaddir *, sizeof(*idp), M_TEMP, M_WAITOK);
        !           643:        idp->saveent.d_namlen = idp->assocent.d_namlen = 0;
        !           644:        /*
        !           645:         * XXX
        !           646:         * Is it worth trying to figure out the type?
        !           647:         */
        !           648:        idp->saveent.d_type = idp->assocent.d_type = idp->current.d_type =
        !           649:            DT_UNKNOWN;
        !           650:        idp->uio = uio;
        !           651:        idp->eofflag = 1;
        !           652:        idp->curroff = uio->uio_offset;
        !           653: 
        !           654:        if ((entryoffsetinblock = idp->curroff & bmask) &&
        !           655:            (error = VOP_BLKATOFF(vdp, (off_t)idp->curroff, NULL, &bp))) {
        !           656:                FREE(idp, M_TEMP);
        !           657:                return (error);
        !           658:        }
        !           659:        endsearch = dp->i_size;
        !           660: 
        !           661:        while (idp->curroff < endsearch) {
        !           662:                /*
        !           663:                 * If offset is on a block boundary,
        !           664:                 * read the next directory block.
        !           665:                 * Release previous if it exists.
        !           666:                 */
        !           667:                if ((idp->curroff & bmask) == 0) {
        !           668:                        if (bp != NULL)
        !           669:                                brelse(bp);
        !           670:                        if ( (error = VOP_BLKATOFF(vdp, (off_t)idp->curroff, NULL, &bp)) )
        !           671:                                break;
        !           672:                        entryoffsetinblock = 0;
        !           673:                }
        !           674:                /*
        !           675:                 * Get pointer to next entry.
        !           676:                 */
        !           677:                ep = (struct iso_directory_record *)
        !           678:                        ((char *)bp->b_data + entryoffsetinblock);
        !           679: 
        !           680:                reclen = isonum_711(ep->length);
        !           681:                if (reclen == 0) {
        !           682:                        /* skip to next block, if any */
        !           683:                        idp->curroff =
        !           684:                            (idp->curroff & ~bmask) + imp->logical_block_size;
        !           685:                        continue;
        !           686:                }
        !           687: 
        !           688:                if (reclen < ISO_DIRECTORY_RECORD_SIZE) {
        !           689:                        error = EINVAL;
        !           690:                        /* illegal entry, stop */
        !           691:                        break;
        !           692:                }
        !           693: 
        !           694:                if (entryoffsetinblock + reclen > imp->logical_block_size) {
        !           695:                        error = EINVAL;
        !           696:                        /* illegal directory, so stop looking */
        !           697:                        break;
        !           698:                }
        !           699: 
        !           700:                idp->current.d_namlen = isonum_711(ep->name_len);
        !           701: 
        !           702:                if (reclen < ISO_DIRECTORY_RECORD_SIZE + idp->current.d_namlen) {
        !           703:                        error = EINVAL;
        !           704:                        /* illegal entry, stop */
        !           705:                        break;
        !           706:                }
        !           707: 
        !           708: #if 1 // radar 1669467 - make it pretty
        !           709:                if ( isonum_711(ep->flags) & directoryBit )
        !           710: #else
        !           711:                if (isonum_711(ep->flags)&2)            
        !           712: #endif // radar 1669467
        !           713:                        idp->current.d_fileno = isodirino(ep, imp);
        !           714:                else
        !           715:                {
        !           716: 
        !           717: #if 1 // radar 1669467
        !           718:                        idp->current.d_fileno = (bp->b_blkno << imp->im_bshift) + entryoffsetinblock;
        !           719: #else
        !           720:                        idp->current.d_fileno = dbtob(bp->b_blkno) + entryoffsetinblock;
        !           721: #endif // radar 1669467
        !           722: 
        !           723:                }
        !           724: 
        !           725:                idp->curroff += reclen;
        !           726: 
        !           727:                switch (imp->iso_ftype) {
        !           728:                case ISO_FTYPE_RRIP:
        !           729:                        cd9660_rrip_getname(ep,idp->current.d_name, &namelen,
        !           730:                                           &idp->current.d_fileno,imp);
        !           731:                        idp->current.d_namlen = (u_char)namelen;
        !           732:                        if (idp->current.d_namlen)
        !           733:                                error = iso_uiodir(idp,&idp->current,idp->curroff);
        !           734:                        break;
        !           735:                default:        /* ISO_FTYPE_DEFAULT || ISO_FTYPE_9660 */
        !           736:                        strcpy(idp->current.d_name,"..");
        !           737:                        switch (ep->name[0]) {
        !           738:                        case 0:
        !           739:                                idp->current.d_namlen = 1;
        !           740:                                error = iso_uiodir(idp,&idp->current,idp->curroff);
        !           741:                                break;
        !           742:                        case 1:
        !           743:                                idp->current.d_namlen = 2;
        !           744:                                error = iso_uiodir(idp,&idp->current,idp->curroff);
        !           745:                                break;
        !           746:                        default:
        !           747:                                isofntrans(ep->name,idp->current.d_namlen,
        !           748:                                           idp->current.d_name, &namelen,
        !           749:                                           imp->iso_ftype == ISO_FTYPE_9660,
        !           750:                                           isonum_711(ep->flags) & associatedBit);
        !           751:                                idp->current.d_namlen = (u_char)namelen;
        !           752:                                if (imp->iso_ftype == ISO_FTYPE_DEFAULT)
        !           753:                                        error = iso_shipdir(idp);
        !           754:                                else
        !           755:                                        error = iso_uiodir(idp,&idp->current,idp->curroff);
        !           756:                                break;
        !           757:                        }
        !           758:                }
        !           759:                if (error)
        !           760:                        break;
        !           761: 
        !           762:                entryoffsetinblock += reclen;
        !           763:        }
        !           764: 
        !           765:        if (!error && imp->iso_ftype == ISO_FTYPE_DEFAULT) {
        !           766:                idp->current.d_namlen = 0;
        !           767:                error = iso_shipdir(idp);
        !           768:        }
        !           769: 
        !           770:        if (!error && ap->a_ncookies) {
        !           771:                struct dirent *dp, *dpstart;
        !           772:                off_t bufferOffset;
        !           773:                u_long *cookies;
        !           774:                int ncookies;
        !           775: 
        !           776:                /*
        !           777:                 * Only the NFS server uses cookies, and it loads the
        !           778:                 * directory block into system space, so we can just look at
        !           779:                 * it directly.
        !           780:                 *
        !           781:                 * We assume the entire transfer is done to a single contiguous buffer.
        !           782:                 */
        !           783:                if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1)
        !           784:                        panic("ufs_readdir: lost in space");
        !           785:                
        !           786:                /*
        !           787:                 * Make a first pass over the buffer just generated,
        !           788:                 * counting the number of entries:
        !           789:                 */
        !           790:                dpstart = (struct dirent *) (uio->uio_iov->iov_base - (uio->uio_offset - startingOffset));
        !           791:                for (dp = dpstart, bufferOffset = startingOffset, ncookies = 0;
        !           792:                     bufferOffset < uio->uio_offset; ) {
        !           793:                        if (dp->d_reclen == 0)
        !           794:                                break;
        !           795:                        bufferOffset += dp->d_reclen;
        !           796:                        ncookies++;
        !           797:                        dp = (struct dirent *)((caddr_t)dp + dp->d_reclen);
        !           798:                }
        !           799:                lost += uio->uio_offset - bufferOffset;
        !           800:                uio->uio_offset = bufferOffset;
        !           801:                
        !           802:                /*
        !           803:                 * Allocate a buffer to hold the cookies requested:
        !           804:                 */
        !           805:                MALLOC(cookies, u_long *, ncookies * sizeof(u_long), M_TEMP, M_WAITOK);
        !           806:                *ap->a_ncookies = ncookies;
        !           807:                *ap->a_cookies = cookies;
        !           808: 
        !           809:                /*
        !           810:                 * Fill in the offsets for each entry in the buffer just allocated:
        !           811:                 */
        !           812:                for (bufferOffset = startingOffset, dp = dpstart; bufferOffset < uio->uio_offset; ) {
        !           813:                        *(cookies++) = bufferOffset;
        !           814:                        bufferOffset += dp->d_reclen;
        !           815:                        dp = (struct dirent *)((caddr_t)dp + dp->d_reclen);
        !           816:                }
        !           817:        }
        !           818: 
        !           819:        if (error < 0)
        !           820:                error = 0;
        !           821: 
        !           822:        if (bp)
        !           823:                brelse (bp);
        !           824: 
        !           825:        uio->uio_offset = idp->uio_off;
        !           826:        *ap->a_eofflag = idp->eofflag;
        !           827: 
        !           828:        FREE(idp, M_TEMP);
        !           829: 
        !           830:        return (error);
        !           831: }
        !           832: 
        !           833: /*
        !           834:  * Return target name of a symbolic link
        !           835:  * Shouldn't we get the parent vnode and read the data from there?
        !           836:  * This could eventually result in deadlocks in cd9660_lookup.
        !           837:  * But otherwise the block read here is in the block buffer two times.
        !           838:  */
        !           839: typedef struct iso_directory_record ISODIR;
        !           840: typedef struct iso_node             ISONODE;
        !           841: typedef struct iso_mnt              ISOMNT;
        !           842: int
        !           843: cd9660_readlink(ap)
        !           844:        struct vop_readlink_args /* {
        !           845:                struct vnode *a_vp;
        !           846:                struct uio *a_uio;
        !           847:                struct ucred *a_cred;
        !           848:        } */ *ap;
        !           849: {
        !           850:        ISONODE *ip;
        !           851:        ISODIR  *dirp;
        !           852:        ISOMNT  *imp;
        !           853:        struct  buf *bp;
        !           854:        struct  uio *uio;
        !           855:        u_short symlen;
        !           856:        int     error;
        !           857:        char    *symname;
        !           858: 
        !           859:        ip  = VTOI(ap->a_vp);
        !           860:        imp = ip->i_mnt;
        !           861:        uio = ap->a_uio;
        !           862: 
        !           863:        if (imp->iso_ftype != ISO_FTYPE_RRIP)
        !           864:                return (EINVAL);
        !           865: 
        !           866:        /*
        !           867:         * Get parents directory record block that this inode included.
        !           868:         */
        !           869:        error = bread(imp->im_devvp,
        !           870: #if 1 // radar 1669467 
        !           871:                          (ip->i_number >> imp->im_bshift),
        !           872: #else
        !           873:                      (ip->i_number >> imp->im_bshift) << (imp->im_bshift - DEV_BSHIFT),
        !           874: #endif // radar 1669467
        !           875:                      imp->logical_block_size, NOCRED, &bp);
        !           876:        if (error) {
        !           877:                brelse(bp);
        !           878:                return (EINVAL);
        !           879:        }
        !           880: 
        !           881:        /*
        !           882:         * Setup the directory pointer for this inode
        !           883:         */
        !           884:        dirp = (ISODIR *)(bp->b_data + (ip->i_number & imp->im_bmask));
        !           885: 
        !           886:        /*
        !           887:         * Just make sure, we have a right one....
        !           888:         *   1: Check not cross boundary on block
        !           889:         */
        !           890:        if ((ip->i_number & imp->im_bmask) + isonum_711(dirp->length)
        !           891:            > imp->logical_block_size) {
        !           892:                brelse(bp);
        !           893:                return (EINVAL);
        !           894:        }
        !           895: 
        !           896:        /*
        !           897:         * Now get a buffer
        !           898:         * Abuse a namei buffer for now.
        !           899:         */
        !           900:        if (uio->uio_segflg == UIO_SYSSPACE)
        !           901:                symname = uio->uio_iov->iov_base;
        !           902:        else
        !           903:                MALLOC_ZONE(symname, char *, MAXPATHLEN, M_NAMEI, M_WAITOK);
        !           904:        
        !           905:        /*
        !           906:         * Ok, we just gathering a symbolic name in SL record.
        !           907:         */
        !           908:        if (cd9660_rrip_getsymname(dirp, symname, &symlen, imp) == 0) {
        !           909:                if (uio->uio_segflg != UIO_SYSSPACE)
        !           910:                        FREE_ZONE(symname, MAXPATHLEN, M_NAMEI);
        !           911:                brelse(bp);
        !           912:                return (EINVAL);
        !           913:        }
        !           914:        /*
        !           915:         * Don't forget before you leave from home ;-)
        !           916:         */
        !           917:        brelse(bp);
        !           918: 
        !           919:        /*
        !           920:         * return with the symbolic name to caller's.
        !           921:         */
        !           922:        if (uio->uio_segflg != UIO_SYSSPACE) {
        !           923:                error = uiomove(symname, symlen, uio);
        !           924:                FREE_ZONE(symname, MAXPATHLEN, M_NAMEI);
        !           925:                return (error);
        !           926:        }
        !           927:        uio->uio_resid -= symlen;
        !           928:        uio->uio_iov->iov_base += symlen;
        !           929:        uio->uio_iov->iov_len -= symlen;
        !           930:        return (0);
        !           931: }
        !           932: 
        !           933: /*
        !           934:  * Ufs abort op, called after namei() when a CREATE/DELETE isn't actually
        !           935:  * done. If a buffer has been saved in anticipation of a CREATE, delete it.
        !           936:  */
        !           937: int
        !           938: cd9660_abortop(ap)
        !           939:        struct vop_abortop_args /* {
        !           940:                struct vnode *a_dvp;
        !           941:                struct componentname *a_cnp;
        !           942:        } */ *ap;
        !           943: {
        !           944:        if ((ap->a_cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF)
        !           945:                FREE_ZONE(ap->a_cnp->cn_pnbuf, ap->a_cnp->cn_pnlen, M_NAMEI);
        !           946:        return (0);
        !           947: }
        !           948: 
        !           949: /*
        !           950:  * Lock an inode.
        !           951:  */
        !           952:  
        !           953:  // radar 1669467 - changed ap struct too!!!
        !           954:  // radar 1669467 - chw changed implementation to use the lock manager. This is a delta from
        !           955:  //                what we first did with the radar.  This is now basically identical to ufs_lock.
        !           956: int
        !           957: cd9660_lock(ap)
        !           958:        struct vop_lock_args /* {
        !           959:                struct vnode *a_vp;
        !           960:                int a_flags;
        !           961:                struct proc *a_p;
        !           962:        } */ *ap;
        !           963: {
        !           964:        struct vnode *vp = ap->a_vp;
        !           965: 
        !           966:        if (VTOI(vp) == (struct inode *) NULL)
        !           967:                panic ("cd9660 inode in vnode is null\n");
        !           968:        return (lockmgr(&VTOI(vp)->i_lock, ap->a_flags, &vp->v_interlock,ap->a_p));
        !           969: }
        !           970: 
        !           971: /*
        !           972:  * Unlock an inode.
        !           973:  */
        !           974: 
        !           975: // radar 1669467 - chw changed implementation to use the lock manager.  As with lock,  this is a
        !           976: //                 delta from what we first did with the radar.
        !           977: 
        !           978: int
        !           979: cd9660_unlock(ap)
        !           980:        struct vop_unlock_args /* {
        !           981:                struct vnode *a_vp;
        !           982:                int a_flags;
        !           983:                struct proc *a_p;
        !           984:        } */ *ap;
        !           985: {
        !           986:        struct vnode *vp = ap->a_vp;
        !           987: 
        !           988:        return (lockmgr(&VTOI(vp)->i_lock, ap->a_flags | LK_RELEASE, &vp->v_interlock,ap->a_p));
        !           989: 
        !           990: }
        !           991: 
        !           992: /*
        !           993:  * Calculate the logical to physical mapping if not done already,
        !           994:  * then call the device strategy routine.
        !           995:  */
        !           996: int
        !           997: cd9660_strategy(ap)
        !           998:        struct vop_strategy_args /* {
        !           999:                struct buf *a_bp;
        !          1000:        } */ *ap;
        !          1001: {
        !          1002:        register struct buf *bp = ap->a_bp;
        !          1003:        register struct vnode *vp = bp->b_vp;
        !          1004:        register struct iso_node *ip;
        !          1005:        int error;
        !          1006: 
        !          1007:        ip = VTOI(vp);
        !          1008:        if (vp->v_type == VBLK || vp->v_type == VCHR)
        !          1009:                panic("cd9660_strategy: spec");
        !          1010:        if (bp->b_blkno == bp->b_lblkno) {
        !          1011:                if ( (error = VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno, NULL)) ) {
        !          1012:                        bp->b_error = error;
        !          1013:                        bp->b_flags |= B_ERROR;
        !          1014:                        biodone(bp);
        !          1015:                        return (error);
        !          1016:                }
        !          1017:                if ((long)bp->b_blkno == -1)
        !          1018:                        clrbuf(bp);
        !          1019:        }
        !          1020:        if ((long)bp->b_blkno == -1) {
        !          1021:                biodone(bp);
        !          1022:                return (0);
        !          1023:        }
        !          1024:        vp = ip->i_devvp;
        !          1025:        bp->b_dev = vp->v_rdev;
        !          1026:        VOCALL (vp->v_op, VOFFSET(vop_strategy), ap);
        !          1027:        return (0);
        !          1028: }
        !          1029: 
        !          1030: /*
        !          1031:  * Print out the contents of an inode.
        !          1032:  */
        !          1033: int
        !          1034: cd9660_print(ap)
        !          1035:        struct vop_print_args /* {
        !          1036:                struct vnode *a_vp;
        !          1037:        } */ *ap;
        !          1038: {
        !          1039: 
        !          1040:        printf("tag VT_ISOFS, isofs vnode\n");
        !          1041:        return (0);
        !          1042: }
        !          1043: 
        !          1044: /*
        !          1045:  * Check for a locked inode.
        !          1046:  */
        !          1047: // radar 1669467 changed this to use the lock manager  - chw
        !          1048: 
        !          1049: int
        !          1050: cd9660_islocked(ap)
        !          1051:        struct vop_islocked_args /* {
        !          1052:                struct vnode *a_vp;
        !          1053:        } */ *ap;
        !          1054: {
        !          1055: 
        !          1056:        return (lockstatus(&VTOI(ap->a_vp)->i_lock));
        !          1057: }
        !          1058: 
        !          1059: /*
        !          1060:  * Return POSIX pathconf information applicable to cd9660 filesystems.
        !          1061:  */
        !          1062: int
        !          1063: cd9660_pathconf(ap)
        !          1064:        struct vop_pathconf_args /* {
        !          1065:                struct vnode *a_vp;
        !          1066:                int a_name;
        !          1067:                register_t *a_retval;
        !          1068:        } */ *ap;
        !          1069: {
        !          1070: 
        !          1071:        switch (ap->a_name) {
        !          1072:        case _PC_LINK_MAX:
        !          1073:                *ap->a_retval = 1;
        !          1074:                return (0);
        !          1075:        case _PC_NAME_MAX:
        !          1076:                if (VTOI(ap->a_vp)->i_mnt->iso_ftype == ISO_FTYPE_RRIP)
        !          1077:                        *ap->a_retval = NAME_MAX;
        !          1078:                else
        !          1079:                        *ap->a_retval = 37;
        !          1080:                return (0);
        !          1081:        case _PC_PATH_MAX:
        !          1082:                *ap->a_retval = PATH_MAX;
        !          1083:                return (0);
        !          1084:        case _PC_PIPE_BUF:
        !          1085:                *ap->a_retval = PIPE_BUF;
        !          1086:                return (0);
        !          1087:        case _PC_CHOWN_RESTRICTED:
        !          1088:                *ap->a_retval = 1;
        !          1089:                return (0);
        !          1090:        case _PC_NO_TRUNC:
        !          1091:                *ap->a_retval = 1;
        !          1092:                return (0);
        !          1093:        default:
        !          1094:                return (EINVAL);
        !          1095:        }
        !          1096:        /* NOTREACHED */
        !          1097: }
        !          1098: 
        !          1099: /*
        !          1100:  * Unsupported operation
        !          1101:  */
        !          1102: int
        !          1103: cd9660_enotsupp()
        !          1104: {
        !          1105: 
        !          1106:        return (EOPNOTSUPP);
        !          1107: }
        !          1108: /* Pagein  */
        !          1109: int
        !          1110: cd9660_pagein(ap)
        !          1111:        struct vop_pagein_args /* {
        !          1112:                struct vnode *a_vp;
        !          1113:                struct uio *a_uio;
        !          1114:                int a_ioflag;
        !          1115:                struct ucred *a_cred;
        !          1116:        } */ *ap;
        !          1117: {
        !          1118:        /* pass thru to read */ 
        !          1119:        return (VOP_READ(ap->a_vp, ap->a_uio, ap->a_ioflag, ap->a_cred));
        !          1120: }
        !          1121: 
        !          1122: /* Pageout  */
        !          1123: int
        !          1124: cd9660_pageout(ap)
        !          1125:        struct vop_pageout_args /* {
        !          1126:                struct vnode *a_vp;
        !          1127:                struct uio *a_uio;
        !          1128:                int a_ioflag;
        !          1129:                struct ucred *a_cred;
        !          1130:        } */ *ap;
        !          1131: {
        !          1132:        /* pass thru to write */ 
        !          1133:        return (VOP_WRITE(ap->a_vp, ap->a_uio, ap->a_ioflag, ap->a_cred));
        !          1134: }
        !          1135: 
        !          1136: /*  
        !          1137:  * cd9660_remove - not possible to remove a file from iso cds
        !          1138:  *  
        !          1139:  * Locking policy: a_dvp and vp locked on entry, unlocked on exit
        !          1140:  */ 
        !          1141: int 
        !          1142: cd9660_remove(ap)
        !          1143:     struct vop_remove_args      /* { struct vnode *a_dvp; struct vnode *a_vp;
        !          1144:         struct componentname *a_cnp; } */ *ap;  
        !          1145: {   
        !          1146:     if (ap->a_dvp == ap->a_vp)
        !          1147:                 vrele(ap->a_vp);
        !          1148:         else
        !          1149:                 vput(ap->a_vp);
        !          1150:        vput(ap->a_dvp);
        !          1151: 
        !          1152:     return (EROFS);
        !          1153: }   
        !          1154: 
        !          1155: 
        !          1156: /*  
        !          1157:  * cd9660_rmdir - not possible to remove a directory from iso cds
        !          1158:  *  
        !          1159:  * Locking policy: a_dvp and vp locked on entry, unlocked on exit
        !          1160:  */ 
        !          1161: int 
        !          1162: cd9660_rmdir(ap)
        !          1163:     struct vop_rmdir_args      /* { struct vnode *a_dvp; struct vnode *a_vp;
        !          1164:         struct componentname *a_cnp; } */ *ap;  
        !          1165: {   
        !          1166:     (void) nop_rmdir(ap);
        !          1167:     return (EROFS);
        !          1168: }   
        !          1169: 
        !          1170: /*
        !          1171: 
        !          1172: #
        !          1173: #% getattrlist vp      = = =
        !          1174: #
        !          1175:  vop_getattrlist {
        !          1176:      IN struct vnode *vp;
        !          1177:      IN struct attrlist *alist;
        !          1178:      INOUT struct uio *uio;
        !          1179:      IN struct ucred *cred;
        !          1180:      IN struct proc *p;
        !          1181:  };
        !          1182: 
        !          1183:  */
        !          1184: int
        !          1185: cd9660_getattrlist(ap)
        !          1186:        struct vop_getattrlist_args /* {
        !          1187:        struct vnode *a_vp;
        !          1188:        struct attrlist *a_alist
        !          1189:        struct uio *a_uio;
        !          1190:        struct ucred *a_cred;
        !          1191:        struct proc *a_p;
        !          1192:        } */ *ap;
        !          1193: {
        !          1194:     struct attrlist *alist = ap->a_alist;
        !          1195:     int fixedblocksize;
        !          1196:     int attrblocksize;
        !          1197:     int attrbufsize;
        !          1198:     void *attrbufptr;
        !          1199:     void *attrptr;
        !          1200:     void *varptr;
        !          1201:     int error = 0;
        !          1202: 
        !          1203:        if ((alist->bitmapcount != ATTR_BIT_MAP_COUNT) ||
        !          1204:         ((alist->commonattr & ~ATTR_CMN_VALIDMASK) != 0) ||
        !          1205:         ((alist->volattr & ~ATTR_VOL_VALIDMASK) != 0) ||
        !          1206:         ((alist->dirattr & ~ATTR_DIR_VALIDMASK) != 0) ||
        !          1207:         ((alist->fileattr & ~ATTR_FILE_VALIDMASK) != 0) ||
        !          1208:         ((alist->forkattr & ~ATTR_FORK_VALIDMASK) != 0)) {
        !          1209:                return EINVAL;
        !          1210:        };
        !          1211: 
        !          1212:        /* 
        !          1213:         * Requesting volume information requires setting the ATTR_VOL_INFO bit and
        !          1214:         * volume info requests are mutually exclusive with all other info requests:
        !          1215:         */
        !          1216:        if ((alist->volattr != 0) &&
        !          1217:                (((alist->volattr & ATTR_VOL_INFO) == 0) ||
        !          1218:                (alist->dirattr != 0) || 
        !          1219:                (alist->fileattr != 0) || 
        !          1220:                (alist->forkattr != 0) )) {
        !          1221:         return EINVAL;
        !          1222:        };
        !          1223: 
        !          1224:        /*
        !          1225:         * Reject requests for unsupported options for now:
        !          1226:         */
        !          1227:        if (alist->volattr & ATTR_VOL_MOUNTPOINT) return EINVAL;
        !          1228:        if (alist->commonattr & (ATTR_CMN_NAMEDATTRCOUNT | ATTR_CMN_NAMEDATTRLIST)) return EINVAL;
        !          1229:        if (alist->fileattr &
        !          1230:                (ATTR_FILE_FILETYPE |
        !          1231:                 ATTR_FILE_FORKCOUNT |
        !          1232:                 ATTR_FILE_FORKLIST |
        !          1233:                 ATTR_FILE_DATAEXTENTS |
        !          1234:                 ATTR_FILE_RSRCEXTENTS)) {
        !          1235:                return EINVAL;
        !          1236:        };
        !          1237: 
        !          1238: 
        !          1239:     fixedblocksize = attrcalcsize(alist);
        !          1240:     attrblocksize = fixedblocksize + (sizeof(u_long));                                                 /* u_long for length longword */
        !          1241:     if (alist->commonattr & ATTR_CMN_NAME) attrblocksize += NAME_MAX;
        !          1242:     if (alist->commonattr & ATTR_CMN_NAMEDATTRLIST) attrblocksize += 0;                        /* XXX PPD */
        !          1243:     if (alist->volattr & ATTR_VOL_MOUNTPOINT) attrblocksize += PATH_MAX;
        !          1244:     if (alist->volattr & ATTR_VOL_NAME) attrblocksize += NAME_MAX;
        !          1245:     if (alist->fileattr & ATTR_FILE_FORKLIST) attrblocksize += 0;                              /* XXX PPD */
        !          1246: 
        !          1247:     attrbufsize = MIN(ap->a_uio->uio_resid, attrblocksize);
        !          1248:     MALLOC(attrbufptr, void *, attrblocksize, M_TEMP, M_WAITOK);
        !          1249:     attrptr = attrbufptr;
        !          1250:     *((u_long *)attrptr) = 0;                                                                  /* Set buffer length in case of errors */
        !          1251:     ++((u_long *)attrptr);                                                                             /* Reserve space for length field */
        !          1252:     varptr = ((char *)attrptr) + fixedblocksize;                               /* Point to variable-length storage */
        !          1253: 
        !          1254:        packattrblk(alist, ap->a_vp, &attrptr, &varptr);
        !          1255: 
        !          1256:     *((u_long *)attrbufptr) = (varptr - attrbufptr);           /* Store length of fixed + var block */
        !          1257:     attrbufsize = MIN(attrbufsize, varptr - attrbufptr);       /* Don't copy out more data than was generated */
        !          1258: 
        !          1259:     error = uiomove((caddr_t)attrbufptr, attrbufsize, ap->a_uio);
        !          1260: 
        !          1261:     FREE(attrbufptr, M_TEMP);
        !          1262: 
        !          1263:     return error;
        !          1264: }
        !          1265: 
        !          1266: /*
        !          1267:  * Global vfs data structures for isofs
        !          1268:  */
        !          1269: #define cd9660_create \
        !          1270:        ((int (*) __P((struct  vop_create_args *)))err_create)
        !          1271: #define cd9660_mknod ((int (*) __P((struct  vop_mknod_args *)))err_mknod)
        !          1272: #define cd9660_setattr \
        !          1273:        ((int (*) __P((struct  vop_setattr_args *)))cd9660_enotsupp)
        !          1274: #define cd9660_write ((int (*) __P((struct  vop_write_args *)))cd9660_enotsupp)
        !          1275: #if NFSSERVER
        !          1276: int    lease_check __P((struct vop_lease_args *));
        !          1277: #define        cd9660_lease_check lease_check
        !          1278: #else
        !          1279: #define        cd9660_lease_check ((int (*) __P((struct vop_lease_args *)))nullop)
        !          1280: #endif
        !          1281: #define cd9660_fsync ((int (*) __P((struct  vop_fsync_args *)))nullop)
        !          1282: #define cd9660_rename \
        !          1283:        ((int (*) __P((struct  vop_rename_args *)))err_rename)
        !          1284: #define cd9660_copyfile \
        !          1285:        ((int (*) __P((struct  vop_copyfile *)))err_copyfile)
        !          1286: #define cd9660_link ((int (*) __P((struct  vop_link_args *)))err_link)
        !          1287: #define cd9660_mkdir ((int (*) __P((struct  vop_mkdir_args *)))err_mkdir)
        !          1288: #define cd9660_symlink \
        !          1289:        ((int (*) __P((struct vop_symlink_args *)))err_symlink)
        !          1290: #define cd9660_advlock \
        !          1291:        ((int (*) __P((struct vop_advlock_args *)))cd9660_enotsupp)
        !          1292: #define cd9660_valloc ((int(*) __P(( \
        !          1293:                struct vnode *pvp, \
        !          1294:                int mode, \
        !          1295:                struct ucred *cred, \
        !          1296:                struct vnode **vpp))) cd9660_enotsupp)
        !          1297: #define cd9660_vfree ((int (*) __P((struct  vop_vfree_args *)))cd9660_enotsupp)
        !          1298: #define cd9660_truncate \
        !          1299:        ((int (*) __P((struct  vop_truncate_args *)))cd9660_enotsupp)
        !          1300: #define cd9660_update \
        !          1301:        ((int (*) __P((struct  vop_update_args *)))cd9660_enotsupp)
        !          1302: #define cd9660_bwrite \
        !          1303:        ((int (*) __P((struct  vop_bwrite_args *)))cd9660_enotsupp)
        !          1304: 
        !          1305: /*
        !          1306:  * Global vfs data structures for cd9660
        !          1307:  */
        !          1308: int (**cd9660_vnodeop_p)();
        !          1309: struct vnodeopv_entry_desc cd9660_vnodeop_entries[] = {
        !          1310:        { &vop_default_desc, vn_default_error },
        !          1311:        { &vop_lookup_desc, cd9660_lookup },    /* lookup */
        !          1312:        { &vop_create_desc, cd9660_create },    /* create */
        !          1313:        { &vop_mknod_desc, cd9660_mknod },      /* mknod */
        !          1314:        { &vop_open_desc, cd9660_open },        /* open */
        !          1315:        { &vop_close_desc, cd9660_close },      /* close */
        !          1316:        { &vop_access_desc, cd9660_access },    /* access */
        !          1317:        { &vop_getattr_desc, cd9660_getattr },  /* getattr */
        !          1318:        { &vop_setattr_desc, cd9660_setattr },  /* setattr */
        !          1319:        { &vop_read_desc, cd9660_read },        /* read */
        !          1320:        { &vop_write_desc, cd9660_write },      /* write */
        !          1321:        { &vop_lease_desc, cd9660_lease_check },/* lease */
        !          1322:        { &vop_ioctl_desc, cd9660_ioctl },      /* ioctl */
        !          1323:        { &vop_select_desc, cd9660_select },    /* select */
        !          1324:        { &vop_mmap_desc, cd9660_mmap },        /* mmap */
        !          1325:        { &vop_fsync_desc, cd9660_fsync },      /* fsync */
        !          1326:        { &vop_seek_desc, cd9660_seek },        /* seek */
        !          1327:        { &vop_remove_desc, cd9660_remove },    /* remove */
        !          1328:        { &vop_link_desc, cd9660_link },        /* link */
        !          1329:        { &vop_rename_desc, cd9660_rename },    /* rename */
        !          1330:        { &vop_copyfile_desc, cd9660_copyfile },/* copyfile */
        !          1331:        { &vop_mkdir_desc, cd9660_mkdir },      /* mkdir */
        !          1332:        { &vop_rmdir_desc, cd9660_rmdir },      /* rmdir */
        !          1333:        { &vop_symlink_desc, cd9660_symlink },  /* symlink */
        !          1334:        { &vop_readdir_desc, cd9660_readdir },  /* readdir */
        !          1335:        { &vop_readlink_desc, cd9660_readlink },/* readlink */
        !          1336:        { &vop_abortop_desc, cd9660_abortop },  /* abortop */
        !          1337:        { &vop_inactive_desc, cd9660_inactive },/* inactive */
        !          1338:        { &vop_reclaim_desc, cd9660_reclaim },  /* reclaim */
        !          1339:        { &vop_lock_desc, cd9660_lock },        /* lock */
        !          1340:        { &vop_unlock_desc, cd9660_unlock },    /* unlock */
        !          1341:        { &vop_bmap_desc, cd9660_bmap },        /* bmap */
        !          1342:        { &vop_strategy_desc, cd9660_strategy },/* strategy */
        !          1343:        { &vop_print_desc, cd9660_print },      /* print */
        !          1344:        { &vop_islocked_desc, cd9660_islocked },/* islocked */
        !          1345:        { &vop_pathconf_desc, cd9660_pathconf },/* pathconf */
        !          1346:        { &vop_advlock_desc, cd9660_advlock },  /* advlock */
        !          1347:        { &vop_blkatoff_desc, cd9660_blkatoff },/* blkatoff */
        !          1348:        { &vop_valloc_desc, cd9660_valloc },    /* valloc */
        !          1349:        { &vop_vfree_desc, cd9660_vfree },      /* vfree */
        !          1350:        { &vop_truncate_desc, cd9660_truncate },/* truncate */
        !          1351:        { &vop_update_desc, cd9660_update },    /* update */
        !          1352:        { &vop_bwrite_desc, vn_bwrite },
        !          1353:        { &vop_pagein_desc, cd9660_pagein },            /* Pagein */
        !          1354:        { &vop_pageout_desc, cd9660_pageout },          /* Pageout */
        !          1355:        { &vop_getattrlist_desc, cd9660_getattrlist },  /* getattrlist */
        !          1356:        { (struct vnodeop_desc*)NULL, (int(*)())NULL }
        !          1357: };
        !          1358: struct vnodeopv_desc cd9660_vnodeop_opv_desc =
        !          1359:        { &cd9660_vnodeop_p, cd9660_vnodeop_entries };
        !          1360: 
        !          1361: /*
        !          1362:  * Special device vnode ops
        !          1363:  */
        !          1364: int (**cd9660_specop_p)();
        !          1365: struct vnodeopv_entry_desc cd9660_specop_entries[] = {
        !          1366:        { &vop_default_desc, vn_default_error },
        !          1367:        { &vop_lookup_desc, spec_lookup },      /* lookup */
        !          1368:        { &vop_create_desc, spec_create },      /* create */
        !          1369:        { &vop_mknod_desc, spec_mknod },        /* mknod */
        !          1370:        { &vop_open_desc, spec_open },          /* open */
        !          1371:        { &vop_close_desc, spec_close },        /* close */
        !          1372:        { &vop_access_desc, cd9660_access },    /* access */
        !          1373:        { &vop_getattr_desc, cd9660_getattr },  /* getattr */
        !          1374:        { &vop_setattr_desc, cd9660_setattr },  /* setattr */
        !          1375:        { &vop_read_desc, spec_read },          /* read */
        !          1376:        { &vop_write_desc, spec_write },        /* write */
        !          1377:        { &vop_lease_desc, spec_lease_check },  /* lease */
        !          1378:        { &vop_ioctl_desc, spec_ioctl },        /* ioctl */
        !          1379:        { &vop_select_desc, spec_select },      /* select */
        !          1380:        { &vop_mmap_desc, spec_mmap },          /* mmap */
        !          1381:        { &vop_fsync_desc, spec_fsync },        /* fsync */
        !          1382:        { &vop_seek_desc, spec_seek },          /* seek */
        !          1383:        { &vop_remove_desc, spec_remove },      /* remove */
        !          1384:        { &vop_link_desc, spec_link },          /* link */
        !          1385:        { &vop_rename_desc, spec_rename },      /* rename */
        !          1386:        { &vop_mkdir_desc, spec_mkdir },        /* mkdir */
        !          1387:        { &vop_rmdir_desc, spec_rmdir },        /* rmdir */
        !          1388:        { &vop_symlink_desc, spec_symlink },    /* symlink */
        !          1389:        { &vop_readdir_desc, spec_readdir },    /* readdir */
        !          1390:        { &vop_readlink_desc, spec_readlink },  /* readlink */
        !          1391:        { &vop_abortop_desc, spec_abortop },    /* abortop */
        !          1392:        { &vop_inactive_desc, cd9660_inactive },/* inactive */
        !          1393:        { &vop_reclaim_desc, cd9660_reclaim },  /* reclaim */
        !          1394:        { &vop_lock_desc, cd9660_lock },        /* lock */
        !          1395:        { &vop_unlock_desc, cd9660_unlock },    /* unlock */
        !          1396:        { &vop_bmap_desc, spec_bmap },          /* bmap */
        !          1397:        { &vop_strategy_desc, spec_strategy },  /* strategy */
        !          1398:        { &vop_print_desc, cd9660_print },      /* print */
        !          1399:        { &vop_islocked_desc, cd9660_islocked },/* islocked */
        !          1400:        { &vop_pathconf_desc, spec_pathconf },  /* pathconf */
        !          1401:        { &vop_advlock_desc, spec_advlock },    /* advlock */
        !          1402:        { &vop_blkatoff_desc, spec_blkatoff },  /* blkatoff */
        !          1403:        { &vop_valloc_desc, spec_valloc },      /* valloc */
        !          1404:        { &vop_vfree_desc, spec_vfree },        /* vfree */
        !          1405:        { &vop_truncate_desc, spec_truncate },  /* truncate */
        !          1406:        { &vop_update_desc, cd9660_update },    /* update */
        !          1407:        { &vop_bwrite_desc, vn_bwrite },
        !          1408: #ifdef NeXT
        !          1409:        { &vop_devblocksize_desc, spec_devblocksize },  /* devblocksize */
        !          1410: #endif /* NeXT */
        !          1411:        { &vop_pagein_desc, cd9660_pagein },            /* Pagein */
        !          1412:        { &vop_pageout_desc, cd9660_pageout },          /* Pageout */
        !          1413:        { (struct vnodeop_desc*)NULL, (int(*)())NULL }
        !          1414: };
        !          1415: struct vnodeopv_desc cd9660_specop_opv_desc =
        !          1416:        { &cd9660_specop_p, cd9660_specop_entries };
        !          1417: 
        !          1418: #if FIFO
        !          1419: int (**cd9660_fifoop_p)();
        !          1420: struct vnodeopv_entry_desc cd9660_fifoop_entries[] = {
        !          1421:        { &vop_default_desc, vn_default_error },
        !          1422:        { &vop_lookup_desc, fifo_lookup },      /* lookup */
        !          1423:        { &vop_create_desc, fifo_create },      /* create */
        !          1424:        { &vop_mknod_desc, fifo_mknod },        /* mknod */
        !          1425:        { &vop_open_desc, fifo_open },          /* open */
        !          1426:        { &vop_close_desc, fifo_close },        /* close */
        !          1427:        { &vop_access_desc, cd9660_access },    /* access */
        !          1428:        { &vop_getattr_desc, cd9660_getattr },  /* getattr */
        !          1429:        { &vop_setattr_desc, cd9660_setattr },  /* setattr */
        !          1430:        { &vop_read_desc, fifo_read },          /* read */
        !          1431:        { &vop_write_desc, fifo_write },        /* write */
        !          1432:        { &vop_lease_desc, fifo_lease_check },  /* lease */
        !          1433:        { &vop_ioctl_desc, fifo_ioctl },        /* ioctl */
        !          1434:        { &vop_select_desc, fifo_select },      /* select */
        !          1435:        { &vop_mmap_desc, fifo_mmap },          /* mmap */
        !          1436:        { &vop_fsync_desc, fifo_fsync },        /* fsync */
        !          1437:        { &vop_seek_desc, fifo_seek },          /* seek */
        !          1438:        { &vop_remove_desc, fifo_remove },      /* remove */
        !          1439:        { &vop_link_desc, fifo_link }   ,       /* link */
        !          1440:        { &vop_rename_desc, fifo_rename },      /* rename */
        !          1441:        { &vop_mkdir_desc, fifo_mkdir },        /* mkdir */
        !          1442:        { &vop_rmdir_desc, fifo_rmdir },        /* rmdir */
        !          1443:        { &vop_symlink_desc, fifo_symlink },    /* symlink */
        !          1444:        { &vop_readdir_desc, fifo_readdir },    /* readdir */
        !          1445:        { &vop_readlink_desc, fifo_readlink },  /* readlink */
        !          1446:        { &vop_abortop_desc, fifo_abortop },    /* abortop */
        !          1447:        { &vop_inactive_desc, cd9660_inactive },/* inactive */
        !          1448:        { &vop_reclaim_desc, cd9660_reclaim },  /* reclaim */
        !          1449:        { &vop_lock_desc, cd9660_lock },        /* lock */
        !          1450:        { &vop_unlock_desc, cd9660_unlock },    /* unlock */
        !          1451:        { &vop_bmap_desc, fifo_bmap },          /* bmap */
        !          1452:        { &vop_strategy_desc, fifo_strategy },  /* strategy */
        !          1453:        { &vop_print_desc, cd9660_print },      /* print */
        !          1454:        { &vop_islocked_desc, cd9660_islocked },/* islocked */
        !          1455:        { &vop_pathconf_desc, fifo_pathconf },  /* pathconf */
        !          1456:        { &vop_advlock_desc, fifo_advlock },    /* advlock */
        !          1457:        { &vop_blkatoff_desc, fifo_blkatoff },  /* blkatoff */
        !          1458:        { &vop_valloc_desc, fifo_valloc },      /* valloc */
        !          1459:        { &vop_vfree_desc, fifo_vfree },        /* vfree */
        !          1460:        { &vop_truncate_desc, fifo_truncate },  /* truncate */
        !          1461:        { &vop_update_desc, cd9660_update },    /* update */
        !          1462:        { &vop_bwrite_desc, vn_bwrite },
        !          1463:        { &vop_pagein_desc, cd9660_pagein },            /* Pagein */
        !          1464:        { &vop_pageout_desc, cd9660_pageout },          /* Pageout */
        !          1465:        { (struct vnodeop_desc*)NULL, (int(*)())NULL }
        !          1466: };
        !          1467: struct vnodeopv_desc cd9660_fifoop_opv_desc =
        !          1468:        { &cd9660_fifoop_p, cd9660_fifoop_entries };
        !          1469: #endif /* FIFO */

unix.superglobalmegacorp.com

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