123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950 |
- /* $OpenBSD: cd9660_vnops.c,v 1.72 2015/04/17 04:43:20 guenther Exp $ */
- /* $NetBSD: cd9660_vnops.c,v 1.42 1997/10/16 23:56:57 christos Exp $ */
- /*-
- * Copyright (c) 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley
- * by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
- * Support code is derived from software contributed to Berkeley
- * by Atsushi Murai (amurai@spec.co.jp).
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)cd9660_vnops.c 8.15 (Berkeley) 12/5/94
- */
- #include <sys/param.h>
- #include <sys/systm.h>
- #include <sys/namei.h>
- #include <sys/resourcevar.h>
- #include <sys/kernel.h>
- #include <sys/file.h>
- #include <sys/stat.h>
- #include <sys/buf.h>
- #include <sys/conf.h>
- #include <sys/mount.h>
- #include <sys/vnode.h>
- #include <sys/lock.h>
- #include <sys/malloc.h>
- #include <sys/pool.h>
- #include <sys/dirent.h>
- #include <sys/ioctl.h>
- #include <sys/ioccom.h>
- #include <sys/poll.h>
- #include <sys/specdev.h>
- #include <sys/unistd.h>
- #include <miscfs/fifofs/fifo.h>
- #include <isofs/cd9660/iso.h>
- #include <isofs/cd9660/cd9660_extern.h>
- #include <isofs/cd9660/cd9660_node.h>
- #include <isofs/cd9660/iso_rrip.h>
- /*
- * Structure for reading directories
- */
- struct isoreaddir {
- struct dirent saveent;
- struct dirent assocent;
- struct dirent current;
- off_t saveoff;
- off_t assocoff;
- off_t curroff;
- struct uio *uio;
- off_t uio_off;
- int eofflag;
- };
- int iso_uiodir(struct isoreaddir *, struct dirent *, off_t);
- int iso_shipdir(struct isoreaddir *);
- /*
- * Setattr call. Only allowed for block and character special devices.
- */
- int
- cd9660_setattr(void *v)
- {
- struct vop_setattr_args *ap = v;
- struct vnode *vp = ap->a_vp;
- struct vattr *vap = ap->a_vap;
- if (vap->va_flags != VNOVAL || vap->va_uid != (uid_t)VNOVAL ||
- vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_nsec != VNOVAL ||
- vap->va_mtime.tv_nsec != VNOVAL || vap->va_mode != (mode_t)VNOVAL ||
- (vap->va_vaflags & VA_UTIMES_CHANGE))
- return (EROFS);
- if (vap->va_size != VNOVAL) {
- switch (vp->v_type) {
- case VDIR:
- return (EISDIR);
- case VLNK:
- case VREG:
- return (EROFS);
- case VCHR:
- case VBLK:
- case VSOCK:
- case VFIFO:
- return (0);
- default:
- return (EINVAL);
- }
- }
- return (EINVAL);
- }
- /*
- * Open called.
- *
- * Nothing to do.
- */
- /* ARGSUSED */
- int
- cd9660_open(void *v)
- {
- return (0);
- }
- /*
- * Close called
- *
- * Update the times on the inode on writeable file systems.
- */
- /* ARGSUSED */
- int
- cd9660_close(void *v)
- {
- return (0);
- }
- /*
- * Check mode permission on inode pointer. Mode is READ, WRITE or EXEC.
- * The mode is shifted to select the owner/group/other fields. The
- * super user is granted all permissions.
- */
- int
- cd9660_access(void *v)
- {
- struct vop_access_args *ap = v;
- struct iso_node *ip = VTOI(ap->a_vp);
- return (vaccess(ap->a_vp->v_type, ip->inode.iso_mode & ALLPERMS,
- ip->inode.iso_uid, ip->inode.iso_gid, ap->a_mode, ap->a_cred));
- }
- int
- cd9660_getattr(void *v)
- {
- struct vop_getattr_args *ap = v;
- struct vnode *vp = ap->a_vp;
- register struct vattr *vap = ap->a_vap;
- register struct iso_node *ip = VTOI(vp);
- vap->va_fsid = ip->i_dev;
- vap->va_fileid = ip->i_number;
- vap->va_mode = ip->inode.iso_mode & ALLPERMS;
- vap->va_nlink = ip->inode.iso_links;
- vap->va_uid = ip->inode.iso_uid;
- vap->va_gid = ip->inode.iso_gid;
- vap->va_atime = ip->inode.iso_atime;
- vap->va_mtime = ip->inode.iso_mtime;
- vap->va_ctime = ip->inode.iso_ctime;
- vap->va_rdev = ip->inode.iso_rdev;
- vap->va_size = (u_quad_t) ip->i_size;
- if (ip->i_size == 0 && vp->v_type == VLNK) {
- struct vop_readlink_args rdlnk;
- struct iovec aiov;
- struct uio auio;
- char *cp;
- cp = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
- aiov.iov_base = cp;
- aiov.iov_len = MAXPATHLEN;
- auio.uio_iov = &aiov;
- auio.uio_iovcnt = 1;
- auio.uio_offset = 0;
- auio.uio_rw = UIO_READ;
- auio.uio_segflg = UIO_SYSSPACE;
- auio.uio_procp = ap->a_p;
- auio.uio_resid = MAXPATHLEN;
- rdlnk.a_uio = &auio;
- rdlnk.a_vp = ap->a_vp;
- rdlnk.a_cred = ap->a_cred;
- if (cd9660_readlink(&rdlnk) == 0)
- vap->va_size = MAXPATHLEN - auio.uio_resid;
- free(cp, M_TEMP, 0);
- }
- vap->va_flags = 0;
- vap->va_gen = 1;
- vap->va_blocksize = ip->i_mnt->logical_block_size;
- vap->va_bytes = (u_quad_t) ip->i_size;
- vap->va_type = vp->v_type;
- return (0);
- }
- /*
- * Vnode op for reading.
- */
- int
- cd9660_read(void *v)
- {
- struct vop_read_args *ap = v;
- struct vnode *vp = ap->a_vp;
- register struct uio *uio = ap->a_uio;
- register struct iso_node *ip = VTOI(vp);
- register struct iso_mnt *imp;
- struct buf *bp;
- daddr_t lbn, rablock;
- off_t diff;
- int error = 0;
- long size, n, on;
- if (uio->uio_resid == 0)
- return (0);
- if (uio->uio_offset < 0)
- return (EINVAL);
- ip->i_flag |= IN_ACCESS;
- imp = ip->i_mnt;
- do {
- struct cluster_info *ci = &ip->i_ci;
- lbn = lblkno(imp, uio->uio_offset);
- on = blkoff(imp, uio->uio_offset);
- n = min((u_int)(imp->logical_block_size - on),
- uio->uio_resid);
- diff = (off_t)ip->i_size - uio->uio_offset;
- if (diff <= 0)
- return (0);
- if (diff < n)
- n = diff;
- size = blksize(imp, ip, lbn);
- rablock = lbn + 1;
- #define MAX_RA 32
- if (ci->ci_lastr + 1 == lbn) {
- struct ra {
- daddr_t blks[MAX_RA];
- int sizes[MAX_RA];
- } *ra;
- int i;
- ra = malloc(sizeof *ra, M_TEMP, M_WAITOK);
- for (i = 0; i < MAX_RA &&
- lblktosize(imp, (rablock + i)) < ip->i_size;
- i++) {
- ra->blks[i] = rablock + i;
- ra->sizes[i] = blksize(imp, ip, rablock + i);
- }
- error = breadn(vp, lbn, size, ra->blks,
- ra->sizes, i, &bp);
- free(ra, M_TEMP, 0);
- } else
- error = bread(vp, lbn, size, &bp);
- ci->ci_lastr = lbn;
- n = min(n, size - bp->b_resid);
- if (error) {
- brelse(bp);
- return (error);
- }
- error = uiomovei(bp->b_data + on, (int)n, uio);
- brelse(bp);
- } while (error == 0 && uio->uio_resid > 0 && n != 0);
- return (error);
- }
- /* ARGSUSED */
- int
- cd9660_ioctl(void *v)
- {
- return (ENOTTY);
- }
- /* ARGSUSED */
- int
- cd9660_poll(void *v)
- {
- struct vop_poll_args *ap = v;
- /*
- * We should really check to see if I/O is possible.
- */
- return (ap->a_events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));
- }
- /*
- * Mmap a file
- *
- * NB Currently unsupported.
- */
- /* ARGSUSED */
- int
- cd9660_mmap(void *v)
- {
- return (EINVAL);
- }
- /*
- * Seek on a file
- *
- * Nothing to do, so just return.
- */
- /* ARGSUSED */
- int
- cd9660_seek(void *v)
- {
- return (0);
- }
- int
- iso_uiodir(idp,dp,off)
- struct isoreaddir *idp;
- struct dirent *dp;
- off_t off;
- {
- int error;
- dp->d_name[dp->d_namlen] = 0;
- dp->d_reclen = DIRENT_SIZE(dp);
- if (idp->uio->uio_resid < dp->d_reclen) {
- idp->eofflag = 0;
- return (-1);
- }
- dp->d_off = off;
- if ((error = uiomovei((caddr_t)dp, dp->d_reclen, idp->uio)) != 0)
- return (error);
- idp->uio_off = off;
- return (0);
- }
- int
- iso_shipdir(idp)
- struct isoreaddir *idp;
- {
- struct dirent *dp;
- int cl, sl, assoc;
- int error;
- char *cname, *sname;
- cl = idp->current.d_namlen;
- cname = idp->current.d_name;
- if ((assoc = cl > 1 && *cname == ASSOCCHAR)) {
- cl--;
- cname++;
- }
- dp = &idp->saveent;
- sname = dp->d_name;
- if (!(sl = dp->d_namlen)) {
- dp = &idp->assocent;
- sname = dp->d_name + 1;
- sl = dp->d_namlen - 1;
- }
- if (sl > 0) {
- if (sl != cl
- || bcmp(sname,cname,sl)) {
- if (idp->assocent.d_namlen) {
- error = iso_uiodir(idp, &idp->assocent,
- idp->assocoff);
- if (error)
- return (error);
- idp->assocent.d_namlen = 0;
- }
- if (idp->saveent.d_namlen) {
- error = iso_uiodir(idp, &idp->saveent,
- idp->saveoff);
- if (error)
- return (error);
- idp->saveent.d_namlen = 0;
- }
- }
- }
- idp->current.d_reclen = DIRENT_SIZE(&idp->current);
- if (assoc) {
- idp->assocoff = idp->curroff;
- bcopy(&idp->current,&idp->assocent,idp->current.d_reclen);
- } else {
- idp->saveoff = idp->curroff;
- bcopy(&idp->current,&idp->saveent,idp->current.d_reclen);
- }
- return (0);
- }
- /*
- * Vnode op for readdir
- */
- int
- cd9660_readdir(void *v)
- {
- struct vop_readdir_args *ap = v;
- register struct uio *uio = ap->a_uio;
- struct isoreaddir *idp;
- struct vnode *vdp = ap->a_vp;
- struct iso_node *dp;
- struct iso_mnt *imp;
- struct buf *bp = NULL;
- struct iso_directory_record *ep;
- int entryoffsetinblock;
- doff_t endsearch;
- u_long bmask;
- int error = 0;
- int reclen;
- u_short namelen;
- cdino_t ino;
- dp = VTOI(vdp);
- imp = dp->i_mnt;
- bmask = imp->im_bmask;
- idp = malloc(sizeof(*idp), M_TEMP, M_WAITOK);
- /*
- * These are passed to copyout(), so make sure there's no garbage
- * being leaked in padding or after short names.
- */
- memset(&idp->saveent, 0, sizeof(idp->saveent));
- memset(&idp->assocent, 0, sizeof(idp->assocent));
- memset(&idp->current, 0, sizeof(idp->current));
- /*
- * XXX
- * Is it worth trying to figure out the type?
- */
- idp->saveent.d_type = idp->assocent.d_type = idp->current.d_type =
- DT_UNKNOWN;
- idp->uio = uio;
- idp->eofflag = 1;
- idp->curroff = uio->uio_offset;
- idp->uio_off = uio->uio_offset;
- if ((entryoffsetinblock = idp->curroff & bmask) &&
- (error = cd9660_bufatoff(dp, (off_t)idp->curroff, NULL, &bp))) {
- free(idp, M_TEMP, 0);
- return (error);
- }
- endsearch = dp->i_size;
- while (idp->curroff < endsearch) {
- /*
- * If offset is on a block boundary,
- * read the next directory block.
- * Release previous if it exists.
- */
- if ((idp->curroff & bmask) == 0) {
- if (bp != NULL)
- brelse(bp);
- error = cd9660_bufatoff(dp, (off_t)idp->curroff,
- NULL, &bp);
- if (error)
- break;
- entryoffsetinblock = 0;
- }
- /*
- * Get pointer to next entry.
- */
- ep = (struct iso_directory_record *)
- ((char *)bp->b_data + entryoffsetinblock);
- reclen = isonum_711(ep->length);
- if (reclen == 0) {
- /* skip to next block, if any */
- idp->curroff =
- (idp->curroff & ~bmask) + imp->logical_block_size;
- continue;
- }
- if (reclen < ISO_DIRECTORY_RECORD_SIZE) {
- error = EINVAL;
- /* illegal entry, stop */
- break;
- }
- if (entryoffsetinblock + reclen > imp->logical_block_size) {
- error = EINVAL;
- /* illegal directory, so stop looking */
- break;
- }
- idp->current.d_namlen = isonum_711(ep->name_len);
- if (reclen < ISO_DIRECTORY_RECORD_SIZE + idp->current.d_namlen) {
- error = EINVAL;
- /* illegal entry, stop */
- break;
- }
- if (isonum_711(ep->flags)&2)
- ino = isodirino(ep, imp);
- else
- ino = dbtob(bp->b_blkno) + entryoffsetinblock;
- idp->curroff += reclen;
- switch (imp->iso_ftype) {
- case ISO_FTYPE_RRIP:
- cd9660_rrip_getname(ep,idp->current.d_name, &namelen,
- &ino, imp);
- idp->current.d_fileno = ino;
- idp->current.d_namlen = (u_char)namelen;
- if (idp->current.d_namlen)
- error = iso_uiodir(idp,&idp->current,idp->curroff);
- break;
- default: /* ISO_FTYPE_DEFAULT || ISO_FTYPE_9660 */
- idp->current.d_fileno = ino;
- strlcpy(idp->current.d_name,"..",
- sizeof idp->current.d_name);
- if (idp->current.d_namlen == 1 && ep->name[0] == 0) {
- idp->current.d_namlen = 1;
- error = iso_uiodir(idp,&idp->current,idp->curroff);
- } else if (idp->current.d_namlen == 1 &&
- ep->name[0] == 1) {
- idp->current.d_namlen = 2;
- error = iso_uiodir(idp,&idp->current,idp->curroff);
- } else {
- isofntrans(ep->name,idp->current.d_namlen,
- idp->current.d_name, &namelen,
- imp->iso_ftype == ISO_FTYPE_9660,
- isonum_711(ep->flags) & 4,
- imp->joliet_level);
- idp->current.d_namlen = (u_char)namelen;
- if (imp->iso_ftype == ISO_FTYPE_DEFAULT)
- error = iso_shipdir(idp);
- else
- error = iso_uiodir(idp,&idp->current,idp->curroff);
- }
- }
- if (error)
- break;
- entryoffsetinblock += reclen;
- }
- if (!error && imp->iso_ftype == ISO_FTYPE_DEFAULT) {
- idp->current.d_namlen = 0;
- error = iso_shipdir(idp);
- }
- if (error < 0)
- error = 0;
- if (bp)
- brelse (bp);
- uio->uio_offset = idp->uio_off;
- *ap->a_eofflag = idp->eofflag;
- free(idp, M_TEMP, 0);
- return (error);
- }
- /*
- * Return target name of a symbolic link
- * Shouldn't we get the parent vnode and read the data from there?
- * This could eventually result in deadlocks in cd9660_lookup.
- * But otherwise the block read here is in the block buffer two times.
- */
- typedef struct iso_directory_record ISODIR;
- typedef struct iso_node ISONODE;
- typedef struct iso_mnt ISOMNT;
- int
- cd9660_readlink(void *v)
- {
- struct vop_readlink_args *ap = v;
- ISONODE *ip;
- ISODIR *dirp;
- ISOMNT *imp;
- struct buf *bp;
- struct uio *uio;
- u_short symlen;
- int error;
- char *symname;
- ip = VTOI(ap->a_vp);
- imp = ip->i_mnt;
- uio = ap->a_uio;
- if (imp->iso_ftype != ISO_FTYPE_RRIP)
- return (EINVAL);
- /*
- * Get parents directory record block that this inode included.
- */
- error = bread(imp->im_devvp,
- (ip->i_number >> imp->im_bshift) <<
- (imp->im_bshift - DEV_BSHIFT),
- imp->logical_block_size, &bp);
- if (error) {
- brelse(bp);
- return (EINVAL);
- }
- /*
- * Setup the directory pointer for this inode
- */
- dirp = (ISODIR *)(bp->b_data + (ip->i_number & imp->im_bmask));
- /*
- * Just make sure, we have a right one....
- * 1: Check not cross boundary on block
- */
- if ((ip->i_number & imp->im_bmask) + isonum_711(dirp->length)
- > imp->logical_block_size) {
- brelse(bp);
- return (EINVAL);
- }
- /*
- * Now get a buffer
- * Abuse a namei buffer for now.
- */
- if (uio->uio_segflg == UIO_SYSSPACE &&
- uio->uio_iov->iov_len >= MAXPATHLEN)
- symname = uio->uio_iov->iov_base;
- else
- symname = pool_get(&namei_pool, PR_WAITOK);
-
- /*
- * Ok, we just gathering a symbolic name in SL record.
- */
- if (cd9660_rrip_getsymname(dirp, symname, &symlen, imp) == 0) {
- if (uio->uio_segflg != UIO_SYSSPACE ||
- uio->uio_iov->iov_len < MAXPATHLEN)
- pool_put(&namei_pool, symname);
- brelse(bp);
- return (EINVAL);
- }
- /*
- * Don't forget before you leave from home ;-)
- */
- brelse(bp);
- /*
- * return with the symbolic name to caller's.
- */
- if (uio->uio_segflg != UIO_SYSSPACE ||
- uio->uio_iov->iov_len < MAXPATHLEN) {
- error = uiomovei(symname, symlen, uio);
- pool_put(&namei_pool, symname);
- return (error);
- }
- uio->uio_resid -= symlen;
- uio->uio_iov->iov_base = (char *)uio->uio_iov->iov_base + symlen;
- uio->uio_iov->iov_len -= symlen;
- return (0);
- }
- int
- cd9660_link(void *v)
- {
- struct vop_link_args *ap = v;
- VOP_ABORTOP(ap->a_dvp, ap->a_cnp);
- vput(ap->a_dvp);
- return (EROFS);
- }
- int
- cd9660_symlink(void *v)
- {
- struct vop_symlink_args *ap = v;
- VOP_ABORTOP(ap->a_dvp, ap->a_cnp);
- vput(ap->a_dvp);
- return (EROFS);
- }
- /*
- * Lock an inode.
- */
- int
- cd9660_lock(void *v)
- {
- struct vop_lock_args *ap = v;
- struct vnode *vp = ap->a_vp;
- return (lockmgr(&VTOI(vp)->i_lock, ap->a_flags, NULL));
- }
- /*
- * Unlock an inode.
- */
- int
- cd9660_unlock(void *v)
- {
- struct vop_unlock_args *ap = v;
- struct vnode *vp = ap->a_vp;
- return (lockmgr(&VTOI(vp)->i_lock, ap->a_flags | LK_RELEASE, NULL));
- }
- /*
- * Calculate the logical to physical mapping if not done already,
- * then call the device strategy routine.
- */
- int
- cd9660_strategy(void *v)
- {
- struct vop_strategy_args *ap = v;
- struct buf *bp = ap->a_bp;
- struct vnode *vp = bp->b_vp;
- struct iso_node *ip;
- int error;
- int s;
- ip = VTOI(vp);
- if (vp->v_type == VBLK || vp->v_type == VCHR)
- panic("cd9660_strategy: spec");
- if (bp->b_blkno == bp->b_lblkno) {
- error = VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno, NULL);
- if (error) {
- bp->b_error = error;
- bp->b_flags |= B_ERROR;
- s = splbio();
- biodone(bp);
- splx(s);
- return (error);
- }
- if ((long)bp->b_blkno == -1)
- clrbuf(bp);
- }
- if ((long)bp->b_blkno == -1) {
- s = splbio();
- biodone(bp);
- splx(s);
- return (0);
- }
- vp = ip->i_devvp;
- bp->b_dev = vp->v_rdev;
- (vp->v_op->vop_strategy)(ap);
- return (0);
- }
- /*
- * Print out the contents of an inode.
- */
- /*ARGSUSED*/
- int
- cd9660_print(void *v)
- {
- printf("tag VT_ISOFS, isofs vnode\n");
- return (0);
- }
- /*
- * Check for a locked inode.
- */
- int
- cd9660_islocked(void *v)
- {
- struct vop_islocked_args *ap = v;
- return (lockstatus(&VTOI(ap->a_vp)->i_lock));
- }
- /*
- * Return POSIX pathconf information applicable to cd9660 filesystems.
- */
- int
- cd9660_pathconf(void *v)
- {
- struct vop_pathconf_args *ap = v;
- int error = 0;
- switch (ap->a_name) {
- case _PC_LINK_MAX:
- *ap->a_retval = 1;
- break;
- case _PC_NAME_MAX:
- if (VTOI(ap->a_vp)->i_mnt->iso_ftype == ISO_FTYPE_RRIP)
- *ap->a_retval = NAME_MAX;
- else
- *ap->a_retval = 37;
- break;
- case _PC_CHOWN_RESTRICTED:
- *ap->a_retval = 1;
- break;
- case _PC_NO_TRUNC:
- *ap->a_retval = 1;
- break;
- case _PC_TIMESTAMP_RESOLUTION:
- *ap->a_retval = 1000000000; /* one billion nanoseconds */
- break;
- default:
- error = EINVAL;
- break;
- }
- return (error);
- }
- /*
- * Global vfs data structures for isofs
- */
- #define cd9660_create eopnotsupp
- #define cd9660_mknod eopnotsupp
- #define cd9660_write eopnotsupp
- #define cd9660_fsync nullop
- #define cd9660_remove eopnotsupp
- #define cd9660_rename eopnotsupp
- #define cd9660_mkdir eopnotsupp
- #define cd9660_rmdir eopnotsupp
- #define cd9660_advlock eopnotsupp
- #define cd9660_valloc eopnotsupp
- #define cd9660_vfree eopnotsupp
- #define cd9660_truncate eopnotsupp
- #define cd9660_update eopnotsupp
- #define cd9660_bwrite eopnotsupp
- #define cd9660_revoke vop_generic_revoke
- /* Global vfs data structures for cd9660. */
- struct vops cd9660_vops = {
- .vop_lookup = cd9660_lookup,
- .vop_create = cd9660_create,
- .vop_mknod = cd9660_mknod,
- .vop_open = cd9660_open,
- .vop_close = cd9660_close,
- .vop_access = cd9660_access,
- .vop_getattr = cd9660_getattr,
- .vop_setattr = cd9660_setattr,
- .vop_read = cd9660_read,
- .vop_write = cd9660_write,
- .vop_ioctl = cd9660_ioctl,
- .vop_poll = cd9660_poll,
- .vop_revoke = cd9660_revoke,
- .vop_fsync = cd9660_fsync,
- .vop_remove = cd9660_remove,
- .vop_link = cd9660_link,
- .vop_rename = cd9660_rename,
- .vop_mkdir = cd9660_mkdir,
- .vop_rmdir = cd9660_rmdir,
- .vop_symlink = cd9660_symlink,
- .vop_readdir = cd9660_readdir,
- .vop_readlink = cd9660_readlink,
- .vop_abortop = vop_generic_abortop,
- .vop_inactive = cd9660_inactive,
- .vop_reclaim = cd9660_reclaim,
- .vop_lock = cd9660_lock,
- .vop_unlock = cd9660_unlock,
- .vop_bmap = cd9660_bmap,
- .vop_strategy = cd9660_strategy,
- .vop_print = cd9660_print,
- .vop_islocked = cd9660_islocked,
- .vop_pathconf = cd9660_pathconf,
- .vop_advlock = cd9660_advlock,
- .vop_bwrite = vop_generic_bwrite
- };
- /* Special device vnode ops */
- struct vops cd9660_specvops = {
- .vop_access = cd9660_access,
- .vop_getattr = cd9660_getattr,
- .vop_setattr = cd9660_setattr,
- .vop_inactive = cd9660_inactive,
- .vop_reclaim = cd9660_reclaim,
- .vop_lock = cd9660_lock,
- .vop_unlock = cd9660_unlock,
- .vop_print = cd9660_print,
- .vop_islocked = cd9660_islocked,
- /* XXX: Keep in sync with spec_vops. */
- .vop_lookup = vop_generic_lookup,
- .vop_create = spec_badop,
- .vop_mknod = spec_badop,
- .vop_open = spec_open,
- .vop_close = spec_close,
- .vop_read = spec_read,
- .vop_write = spec_write,
- .vop_ioctl = spec_ioctl,
- .vop_poll = spec_poll,
- .vop_kqfilter = spec_kqfilter,
- .vop_revoke = vop_generic_revoke,
- .vop_fsync = spec_fsync,
- .vop_remove = spec_badop,
- .vop_link = spec_badop,
- .vop_rename = spec_badop,
- .vop_mkdir = spec_badop,
- .vop_rmdir = spec_badop,
- .vop_symlink = spec_badop,
- .vop_readdir = spec_badop,
- .vop_readlink = spec_badop,
- .vop_abortop = spec_badop,
- .vop_bmap = vop_generic_bmap,
- .vop_strategy = spec_strategy,
- .vop_pathconf = spec_pathconf,
- .vop_advlock = spec_advlock,
- .vop_bwrite = vop_generic_bwrite,
- };
- #ifdef FIFO
- struct vops cd9660_fifovops = {
- .vop_access = cd9660_access,
- .vop_getattr = cd9660_getattr,
- .vop_setattr = cd9660_setattr,
- .vop_inactive = cd9660_inactive,
- .vop_reclaim = cd9660_reclaim,
- .vop_lock = cd9660_lock,
- .vop_unlock = cd9660_unlock,
- .vop_print = cd9660_print,
- .vop_islocked = cd9660_islocked,
- .vop_bwrite = vop_generic_bwrite,
- /* XXX: Keep in sync with fifo_vops. */
- .vop_lookup = vop_generic_lookup,
- .vop_create = fifo_badop,
- .vop_mknod = fifo_badop,
- .vop_open = fifo_open,
- .vop_close = fifo_close,
- .vop_read = fifo_read,
- .vop_write = fifo_write,
- .vop_ioctl = fifo_ioctl,
- .vop_poll = fifo_poll,
- .vop_kqfilter = fifo_kqfilter,
- .vop_revoke = vop_generic_revoke,
- .vop_fsync = nullop,
- .vop_remove = fifo_badop,
- .vop_link = fifo_badop,
- .vop_rename = fifo_badop,
- .vop_mkdir = fifo_badop,
- .vop_rmdir = fifo_badop,
- .vop_symlink = fifo_badop,
- .vop_readdir = fifo_badop,
- .vop_readlink = fifo_badop,
- .vop_abortop = fifo_badop,
- .vop_bmap = vop_generic_bmap,
- .vop_strategy = fifo_badop,
- .vop_pathconf = fifo_pathconf,
- .vop_advlock = fifo_advlock,
- };
- #endif /* FIFO */
|