1*65789Smckusick /*- 2*65789Smckusick * Copyright (c) 1994 3*65789Smckusick * The Regents of the University of California. All rights reserved. 4*65789Smckusick * 5*65789Smckusick * This code is derived from software contributed to Berkeley 6*65789Smckusick * by Pace Willisson (pace@blitz.com). The Rock Ridge Extension 7*65789Smckusick * Support code is derived from software contributed to Berkeley 8*65789Smckusick * by Atsushi Murai (amurai@spec.co.jp). 9*65789Smckusick * 10*65789Smckusick * %sccs.include.redist.c% 11*65789Smckusick * 12*65789Smckusick * @(#)cd9660_vnops.c 8.1 (Berkeley) 01/21/94 13*65789Smckusick */ 14*65789Smckusick 15*65789Smckusick #include <sys/param.h> 16*65789Smckusick #include <sys/systm.h> 17*65789Smckusick #include <sys/namei.h> 18*65789Smckusick #include <sys/resourcevar.h> 19*65789Smckusick #include <sys/kernel.h> 20*65789Smckusick #include <sys/file.h> 21*65789Smckusick #include <sys/stat.h> 22*65789Smckusick #include <sys/buf.h> 23*65789Smckusick #include <sys/proc.h> 24*65789Smckusick #include <sys/conf.h> 25*65789Smckusick #include <sys/mount.h> 26*65789Smckusick #include <sys/vnode.h> 27*65789Smckusick #include <miscfs/specfs/specdev.h> 28*65789Smckusick #include <miscfs/fifofs/fifo.h> 29*65789Smckusick #include <sys/malloc.h> 30*65789Smckusick #include <sys/dir.h> 31*65789Smckusick 32*65789Smckusick #include <isofs/cd9660/iso.h> 33*65789Smckusick #include <isofs/cd9660/isofs_node.h> 34*65789Smckusick #include <isofs/cd9660/iso_rrip.h> 35*65789Smckusick 36*65789Smckusick #if 0 37*65789Smckusick /* 38*65789Smckusick * Mknod vnode call 39*65789Smckusick * Actually remap the device number 40*65789Smckusick */ 41*65789Smckusick isofs_mknod(ndp, vap, cred, p) 42*65789Smckusick struct nameidata *ndp; 43*65789Smckusick struct ucred *cred; 44*65789Smckusick struct vattr *vap; 45*65789Smckusick struct proc *p; 46*65789Smckusick { 47*65789Smckusick #ifndef ISODEVMAP 48*65789Smckusick free(ndp->ni_pnbuf, M_NAMEI); 49*65789Smckusick vput(ndp->ni_dvp); 50*65789Smckusick vput(ndp->ni_vp); 51*65789Smckusick return EINVAL; 52*65789Smckusick #else 53*65789Smckusick register struct vnode *vp; 54*65789Smckusick struct iso_node *ip; 55*65789Smckusick struct iso_dnode *dp; 56*65789Smckusick int error; 57*65789Smckusick 58*65789Smckusick vp = ndp->ni_vp; 59*65789Smckusick ip = VTOI(vp); 60*65789Smckusick 61*65789Smckusick if (ip->i_mnt->iso_ftype != ISO_FTYPE_RRIP 62*65789Smckusick || vap->va_type != vp->v_type 63*65789Smckusick || (vap->va_type != VCHR && vap->va_type != VBLK)) { 64*65789Smckusick free(ndp->ni_pnbuf, M_NAMEI); 65*65789Smckusick vput(ndp->ni_dvp); 66*65789Smckusick vput(ndp->ni_vp); 67*65789Smckusick return EINVAL; 68*65789Smckusick } 69*65789Smckusick 70*65789Smckusick dp = iso_dmap(ip->i_dev,ip->i_number,1); 71*65789Smckusick if (ip->inode.iso_rdev == vap->va_rdev || vap->va_rdev == VNOVAL) { 72*65789Smckusick /* same as the unmapped one, delete the mapping */ 73*65789Smckusick remque(dp); 74*65789Smckusick FREE(dp,M_CACHE); 75*65789Smckusick } else 76*65789Smckusick /* enter new mapping */ 77*65789Smckusick dp->d_dev = vap->va_rdev; 78*65789Smckusick 79*65789Smckusick /* 80*65789Smckusick * Remove inode so that it will be reloaded by iget and 81*65789Smckusick * checked to see if it is an alias of an existing entry 82*65789Smckusick * in the inode cache. 83*65789Smckusick */ 84*65789Smckusick vput(vp); 85*65789Smckusick vp->v_type = VNON; 86*65789Smckusick vgone(vp); 87*65789Smckusick return (0); 88*65789Smckusick #endif 89*65789Smckusick } 90*65789Smckusick #endif 91*65789Smckusick 92*65789Smckusick /* 93*65789Smckusick * Open called. 94*65789Smckusick * 95*65789Smckusick * Nothing to do. 96*65789Smckusick */ 97*65789Smckusick /* ARGSUSED */ 98*65789Smckusick int 99*65789Smckusick isofs_open(ap) 100*65789Smckusick struct vop_open_args /* { 101*65789Smckusick struct vnode *a_vp; 102*65789Smckusick int a_mode; 103*65789Smckusick struct ucred *a_cred; 104*65789Smckusick struct proc *a_p; 105*65789Smckusick } */ *ap; 106*65789Smckusick { 107*65789Smckusick return (0); 108*65789Smckusick } 109*65789Smckusick 110*65789Smckusick /* 111*65789Smckusick * Close called 112*65789Smckusick * 113*65789Smckusick * Update the times on the inode on writeable file systems. 114*65789Smckusick */ 115*65789Smckusick /* ARGSUSED */ 116*65789Smckusick int 117*65789Smckusick isofs_close(ap) 118*65789Smckusick struct vop_close_args /* { 119*65789Smckusick struct vnode *a_vp; 120*65789Smckusick int a_fflag; 121*65789Smckusick struct ucred *a_cred; 122*65789Smckusick struct proc *a_p; 123*65789Smckusick } */ *ap; 124*65789Smckusick { 125*65789Smckusick return (0); 126*65789Smckusick } 127*65789Smckusick 128*65789Smckusick /* 129*65789Smckusick * Check mode permission on inode pointer. Mode is READ, WRITE or EXEC. 130*65789Smckusick * The mode is shifted to select the owner/group/other fields. The 131*65789Smckusick * super user is granted all permissions. 132*65789Smckusick */ 133*65789Smckusick /* ARGSUSED */ 134*65789Smckusick isofs_access(ap) 135*65789Smckusick struct vop_access_args /* { 136*65789Smckusick struct vnode *a_vp; 137*65789Smckusick int a_mode; 138*65789Smckusick struct ucred *a_cred; 139*65789Smckusick struct proc *a_p; 140*65789Smckusick } */ *ap; 141*65789Smckusick { 142*65789Smckusick return (0); 143*65789Smckusick } 144*65789Smckusick 145*65789Smckusick isofs_getattr(ap) 146*65789Smckusick struct vop_getattr_args /* { 147*65789Smckusick struct vnode *a_vp; 148*65789Smckusick struct vattr *a_vap; 149*65789Smckusick struct ucred *a_cred; 150*65789Smckusick struct proc *a_p; 151*65789Smckusick } */ *ap; 152*65789Smckusick 153*65789Smckusick { 154*65789Smckusick struct vnode *vp = ap->a_vp; 155*65789Smckusick register struct vattr *vap = ap->a_vap; 156*65789Smckusick register struct iso_node *ip = VTOI(vp); 157*65789Smckusick int i; 158*65789Smckusick 159*65789Smckusick vap->va_fsid = ip->i_dev; 160*65789Smckusick vap->va_fileid = ip->i_number; 161*65789Smckusick 162*65789Smckusick vap->va_mode = ip->inode.iso_mode; 163*65789Smckusick vap->va_nlink = ip->inode.iso_links; 164*65789Smckusick vap->va_uid = ip->inode.iso_uid; 165*65789Smckusick vap->va_gid = ip->inode.iso_gid; 166*65789Smckusick vap->va_atime = ip->inode.iso_atime; 167*65789Smckusick vap->va_mtime = ip->inode.iso_mtime; 168*65789Smckusick vap->va_ctime = ip->inode.iso_ctime; 169*65789Smckusick vap->va_rdev = ip->inode.iso_rdev; 170*65789Smckusick 171*65789Smckusick vap->va_size = (u_quad_t) ip->i_size; 172*65789Smckusick vap->va_flags = 0; 173*65789Smckusick vap->va_gen = 1; 174*65789Smckusick vap->va_blocksize = ip->i_mnt->logical_block_size; 175*65789Smckusick vap->va_bytes = (u_quad_t) ip->i_size; 176*65789Smckusick vap->va_type = vp->v_type; 177*65789Smckusick return (0); 178*65789Smckusick } 179*65789Smckusick 180*65789Smckusick #if ISO_DEFAULT_BLOCK_SIZE >= NBPG 181*65789Smckusick #ifdef DEBUG 182*65789Smckusick extern int doclusterread; 183*65789Smckusick #else 184*65789Smckusick #define doclusterread 1 185*65789Smckusick #endif 186*65789Smckusick #else 187*65789Smckusick /* XXX until cluster routines can handle block sizes less than one page */ 188*65789Smckusick #define doclusterread 0 189*65789Smckusick #endif 190*65789Smckusick 191*65789Smckusick /* 192*65789Smckusick * Vnode op for reading. 193*65789Smckusick */ 194*65789Smckusick isofs_read(ap) 195*65789Smckusick struct vop_read_args /* { 196*65789Smckusick struct vnode *a_vp; 197*65789Smckusick struct uio *a_uio; 198*65789Smckusick int a_ioflag; 199*65789Smckusick struct ucred *a_cred; 200*65789Smckusick } */ *ap; 201*65789Smckusick { 202*65789Smckusick struct vnode *vp = ap->a_vp; 203*65789Smckusick register struct uio *uio = ap->a_uio; 204*65789Smckusick register struct iso_node *ip = VTOI(vp); 205*65789Smckusick register struct iso_mnt *imp; 206*65789Smckusick struct buf *bp; 207*65789Smckusick daddr_t lbn, bn, rablock; 208*65789Smckusick off_t diff; 209*65789Smckusick int rasize, error = 0; 210*65789Smckusick long size, n, on; 211*65789Smckusick 212*65789Smckusick if (uio->uio_resid == 0) 213*65789Smckusick return (0); 214*65789Smckusick if (uio->uio_offset < 0) 215*65789Smckusick return (EINVAL); 216*65789Smckusick ip->i_flag |= IACC; 217*65789Smckusick imp = ip->i_mnt; 218*65789Smckusick do { 219*65789Smckusick lbn = iso_lblkno(imp, uio->uio_offset); 220*65789Smckusick on = iso_blkoff(imp, uio->uio_offset); 221*65789Smckusick n = min((unsigned)(imp->logical_block_size - on), 222*65789Smckusick uio->uio_resid); 223*65789Smckusick diff = (off_t)ip->i_size - uio->uio_offset; 224*65789Smckusick if (diff <= 0) 225*65789Smckusick return (0); 226*65789Smckusick if (diff < n) 227*65789Smckusick n = diff; 228*65789Smckusick size = iso_blksize(imp, ip, lbn); 229*65789Smckusick rablock = lbn + 1; 230*65789Smckusick #if 1 231*65789Smckusick if (doclusterread) { 232*65789Smckusick if (iso_lblktosize(imp, rablock) <= ip->i_size) 233*65789Smckusick error = cluster_read(vp, (off_t)ip->i_size, 234*65789Smckusick lbn, size, NOCRED, &bp); 235*65789Smckusick else 236*65789Smckusick error = bread(vp, lbn, size, NOCRED, &bp); 237*65789Smckusick } else { 238*65789Smckusick if (vp->v_lastr + 1 == lbn && 239*65789Smckusick iso_lblktosize(imp, rablock) < ip->i_size) { 240*65789Smckusick rasize = iso_blksize(imp, ip, rablock); 241*65789Smckusick error = breadn(vp, lbn, size, &rablock, 242*65789Smckusick &rasize, 1, NOCRED, &bp); 243*65789Smckusick } else 244*65789Smckusick error = bread(vp, lbn, size, NOCRED, &bp); 245*65789Smckusick } 246*65789Smckusick #endif 247*65789Smckusick vp->v_lastr = lbn; 248*65789Smckusick n = min(n, size - bp->b_resid); 249*65789Smckusick if (error) { 250*65789Smckusick brelse(bp); 251*65789Smckusick return (error); 252*65789Smckusick } 253*65789Smckusick 254*65789Smckusick error = uiomove(bp->b_un.b_addr + on, (int)n, uio); 255*65789Smckusick if (n + on == imp->logical_block_size || 256*65789Smckusick uio->uio_offset == (off_t)ip->i_size) 257*65789Smckusick bp->b_flags |= B_AGE; 258*65789Smckusick brelse(bp); 259*65789Smckusick } while (error == 0 && uio->uio_resid > 0 && n != 0); 260*65789Smckusick return (error); 261*65789Smckusick } 262*65789Smckusick 263*65789Smckusick /* ARGSUSED */ 264*65789Smckusick int 265*65789Smckusick isofs_ioctl(ap) 266*65789Smckusick struct vop_ioctl_args /* { 267*65789Smckusick struct vnode *a_vp; 268*65789Smckusick int a_command; 269*65789Smckusick caddr_t a_data; 270*65789Smckusick int a_fflag; 271*65789Smckusick struct ucred *a_cred; 272*65789Smckusick struct proc *a_p; 273*65789Smckusick } */ *ap; 274*65789Smckusick { 275*65789Smckusick printf("You did ioctl for isofs !!\n"); 276*65789Smckusick return (ENOTTY); 277*65789Smckusick } 278*65789Smckusick 279*65789Smckusick /* ARGSUSED */ 280*65789Smckusick int 281*65789Smckusick isofs_select(ap) 282*65789Smckusick struct vop_select_args /* { 283*65789Smckusick struct vnode *a_vp; 284*65789Smckusick int a_which; 285*65789Smckusick int a_fflags; 286*65789Smckusick struct ucred *a_cred; 287*65789Smckusick struct proc *a_p; 288*65789Smckusick } */ *ap; 289*65789Smckusick { 290*65789Smckusick 291*65789Smckusick /* 292*65789Smckusick * We should really check to see if I/O is possible. 293*65789Smckusick */ 294*65789Smckusick return (1); 295*65789Smckusick } 296*65789Smckusick 297*65789Smckusick /* 298*65789Smckusick * Mmap a file 299*65789Smckusick * 300*65789Smckusick * NB Currently unsupported. 301*65789Smckusick */ 302*65789Smckusick /* ARGSUSED */ 303*65789Smckusick int 304*65789Smckusick isofs_mmap(ap) 305*65789Smckusick struct vop_mmap_args /* { 306*65789Smckusick struct vnode *a_vp; 307*65789Smckusick int a_fflags; 308*65789Smckusick struct ucred *a_cred; 309*65789Smckusick struct proc *a_p; 310*65789Smckusick } */ *ap; 311*65789Smckusick { 312*65789Smckusick 313*65789Smckusick return (EINVAL); 314*65789Smckusick } 315*65789Smckusick 316*65789Smckusick /* 317*65789Smckusick * Seek on a file 318*65789Smckusick * 319*65789Smckusick * Nothing to do, so just return. 320*65789Smckusick */ 321*65789Smckusick /* ARGSUSED */ 322*65789Smckusick int 323*65789Smckusick isofs_seek(ap) 324*65789Smckusick struct vop_seek_args /* { 325*65789Smckusick struct vnode *a_vp; 326*65789Smckusick off_t a_oldoff; 327*65789Smckusick off_t a_newoff; 328*65789Smckusick struct ucred *a_cred; 329*65789Smckusick } */ *ap; 330*65789Smckusick { 331*65789Smckusick 332*65789Smckusick return (0); 333*65789Smckusick } 334*65789Smckusick 335*65789Smckusick /* 336*65789Smckusick * Structure for reading directories 337*65789Smckusick */ 338*65789Smckusick struct isoreaddir { 339*65789Smckusick struct dirent saveent; 340*65789Smckusick struct dirent assocent; 341*65789Smckusick struct dirent current; 342*65789Smckusick off_t saveoff; 343*65789Smckusick off_t assocoff; 344*65789Smckusick off_t curroff; 345*65789Smckusick struct uio *uio; 346*65789Smckusick off_t uio_off; 347*65789Smckusick u_int *cookiep; 348*65789Smckusick int ncookies; 349*65789Smckusick int eof; 350*65789Smckusick }; 351*65789Smckusick 352*65789Smckusick static int 353*65789Smckusick iso_uiodir(idp,dp,off) 354*65789Smckusick struct isoreaddir *idp; 355*65789Smckusick struct dirent *dp; 356*65789Smckusick off_t off; 357*65789Smckusick { 358*65789Smckusick int error; 359*65789Smckusick 360*65789Smckusick dp->d_name[dp->d_namlen] = 0; 361*65789Smckusick dp->d_reclen = DIRSIZ(dp); 362*65789Smckusick 363*65789Smckusick if (idp->uio->uio_resid < dp->d_reclen) { 364*65789Smckusick idp->eof = 0; 365*65789Smckusick return -1; 366*65789Smckusick } 367*65789Smckusick 368*65789Smckusick if (idp->cookiep) { 369*65789Smckusick if (idp->ncookies <= 0) { 370*65789Smckusick idp->eof = 0; 371*65789Smckusick return -1; 372*65789Smckusick } 373*65789Smckusick 374*65789Smckusick *idp->cookiep++ = off; 375*65789Smckusick --idp->ncookies; 376*65789Smckusick } 377*65789Smckusick 378*65789Smckusick if (error = uiomove(dp,dp->d_reclen,idp->uio)) 379*65789Smckusick return error; 380*65789Smckusick idp->uio_off = off; 381*65789Smckusick return 0; 382*65789Smckusick } 383*65789Smckusick 384*65789Smckusick static int 385*65789Smckusick iso_shipdir(idp) 386*65789Smckusick struct isoreaddir *idp; 387*65789Smckusick { 388*65789Smckusick struct dirent *dp; 389*65789Smckusick int cl, sl, assoc; 390*65789Smckusick int error; 391*65789Smckusick char *cname, *sname; 392*65789Smckusick 393*65789Smckusick cl = idp->current.d_namlen; 394*65789Smckusick cname = idp->current.d_name; 395*65789Smckusick if (assoc = cl > 1 && *cname == ASSOCCHAR) { 396*65789Smckusick cl--; 397*65789Smckusick cname++; 398*65789Smckusick } 399*65789Smckusick 400*65789Smckusick dp = &idp->saveent; 401*65789Smckusick sname = dp->d_name; 402*65789Smckusick if (!(sl = dp->d_namlen)) { 403*65789Smckusick dp = &idp->assocent; 404*65789Smckusick sname = dp->d_name + 1; 405*65789Smckusick sl = dp->d_namlen - 1; 406*65789Smckusick } 407*65789Smckusick if (sl > 0) { 408*65789Smckusick if (sl != cl 409*65789Smckusick || bcmp(sname,cname,sl)) { 410*65789Smckusick if (idp->assocent.d_namlen) { 411*65789Smckusick if (error = iso_uiodir(idp,&idp->assocent,idp->assocoff)) 412*65789Smckusick return error; 413*65789Smckusick idp->assocent.d_namlen = 0; 414*65789Smckusick } 415*65789Smckusick if (idp->saveent.d_namlen) { 416*65789Smckusick if (error = iso_uiodir(idp,&idp->saveent,idp->saveoff)) 417*65789Smckusick return error; 418*65789Smckusick idp->saveent.d_namlen = 0; 419*65789Smckusick } 420*65789Smckusick } 421*65789Smckusick } 422*65789Smckusick idp->current.d_reclen = DIRSIZ(&idp->current); 423*65789Smckusick if (assoc) { 424*65789Smckusick idp->assocoff = idp->curroff; 425*65789Smckusick bcopy(&idp->current,&idp->assocent,idp->current.d_reclen); 426*65789Smckusick } else { 427*65789Smckusick idp->saveoff = idp->curroff; 428*65789Smckusick bcopy(&idp->current,&idp->saveent,idp->current.d_reclen); 429*65789Smckusick } 430*65789Smckusick return 0; 431*65789Smckusick } 432*65789Smckusick 433*65789Smckusick /* 434*65789Smckusick * Vnode op for readdir 435*65789Smckusick * XXX make sure everything still works now that eofflagp and cookiep 436*65789Smckusick * are no longer args. 437*65789Smckusick */ 438*65789Smckusick int 439*65789Smckusick isofs_readdir(ap) 440*65789Smckusick struct vop_readdir_args /* { 441*65789Smckusick struct vnode *a_vp; 442*65789Smckusick struct uio *a_uio; 443*65789Smckusick struct ucred *a_cred; 444*65789Smckusick } */ *ap; 445*65789Smckusick { 446*65789Smckusick register struct uio *uio = ap->a_uio; 447*65789Smckusick struct isoreaddir *idp; 448*65789Smckusick int entryoffsetinblock; 449*65789Smckusick int error = 0; 450*65789Smckusick int endsearch; 451*65789Smckusick struct iso_directory_record *ep; 452*65789Smckusick u_short elen; 453*65789Smckusick int reclen; 454*65789Smckusick struct iso_mnt *imp; 455*65789Smckusick struct iso_node *ip; 456*65789Smckusick struct buf *bp = NULL; 457*65789Smckusick 458*65789Smckusick ip = VTOI(ap->a_vp); 459*65789Smckusick imp = ip->i_mnt; 460*65789Smckusick 461*65789Smckusick MALLOC(idp,struct isoreaddir *,sizeof(*idp),M_TEMP,M_WAITOK); 462*65789Smckusick idp->saveent.d_namlen = 0; 463*65789Smckusick idp->assocent.d_namlen = 0; 464*65789Smckusick idp->uio = uio; 465*65789Smckusick #if 0 466*65789Smckusick idp->cookiep = cookies; 467*65789Smckusick idp->ncookies = ncookies; 468*65789Smckusick idp->eof = 1; 469*65789Smckusick #else 470*65789Smckusick idp->cookiep = 0; 471*65789Smckusick #endif 472*65789Smckusick idp->curroff = uio->uio_offset; 473*65789Smckusick 474*65789Smckusick entryoffsetinblock = iso_blkoff(imp, idp->curroff); 475*65789Smckusick if (entryoffsetinblock != 0) { 476*65789Smckusick if (error = iso_blkatoff(ip, idp->curroff, &bp)) { 477*65789Smckusick FREE(idp,M_TEMP); 478*65789Smckusick return (error); 479*65789Smckusick } 480*65789Smckusick } 481*65789Smckusick 482*65789Smckusick endsearch = ip->i_size; 483*65789Smckusick 484*65789Smckusick while (idp->curroff < endsearch) { 485*65789Smckusick /* 486*65789Smckusick * If offset is on a block boundary, 487*65789Smckusick * read the next directory block. 488*65789Smckusick * Release previous if it exists. 489*65789Smckusick */ 490*65789Smckusick 491*65789Smckusick if (iso_blkoff(imp, idp->curroff) == 0) { 492*65789Smckusick if (bp != NULL) 493*65789Smckusick brelse(bp); 494*65789Smckusick if (error = iso_blkatoff(ip, idp->curroff, &bp)) 495*65789Smckusick break; 496*65789Smckusick entryoffsetinblock = 0; 497*65789Smckusick } 498*65789Smckusick /* 499*65789Smckusick * Get pointer to next entry. 500*65789Smckusick */ 501*65789Smckusick 502*65789Smckusick ep = (struct iso_directory_record *) 503*65789Smckusick (bp->b_un.b_addr + entryoffsetinblock); 504*65789Smckusick 505*65789Smckusick reclen = isonum_711 (ep->length); 506*65789Smckusick if (reclen == 0) { 507*65789Smckusick /* skip to next block, if any */ 508*65789Smckusick idp->curroff = roundup (idp->curroff, 509*65789Smckusick imp->logical_block_size); 510*65789Smckusick continue; 511*65789Smckusick } 512*65789Smckusick 513*65789Smckusick if (reclen < ISO_DIRECTORY_RECORD_SIZE) { 514*65789Smckusick error = EINVAL; 515*65789Smckusick /* illegal entry, stop */ 516*65789Smckusick break; 517*65789Smckusick } 518*65789Smckusick 519*65789Smckusick if (entryoffsetinblock + reclen > imp->logical_block_size) { 520*65789Smckusick error = EINVAL; 521*65789Smckusick /* illegal directory, so stop looking */ 522*65789Smckusick break; 523*65789Smckusick } 524*65789Smckusick 525*65789Smckusick idp->current.d_namlen = isonum_711 (ep->name_len); 526*65789Smckusick if (isonum_711(ep->flags)&2) 527*65789Smckusick isodirino(&idp->current.d_fileno,ep,imp); 528*65789Smckusick else 529*65789Smckusick idp->current.d_fileno = dbtob(bp->b_blkno) + 530*65789Smckusick idp->curroff; 531*65789Smckusick 532*65789Smckusick if (reclen < ISO_DIRECTORY_RECORD_SIZE + idp->current.d_namlen) { 533*65789Smckusick error = EINVAL; 534*65789Smckusick /* illegal entry, stop */ 535*65789Smckusick break; 536*65789Smckusick } 537*65789Smckusick 538*65789Smckusick idp->curroff += reclen; 539*65789Smckusick /* 540*65789Smckusick * 541*65789Smckusick */ 542*65789Smckusick switch (imp->iso_ftype) { 543*65789Smckusick case ISO_FTYPE_RRIP: 544*65789Smckusick isofs_rrip_getname(ep,idp->current.d_name, 545*65789Smckusick (u_short *)&idp->current.d_namlen, 546*65789Smckusick &idp->current.d_fileno,imp); 547*65789Smckusick if (idp->current.d_namlen) 548*65789Smckusick error = iso_uiodir(idp,&idp->current,idp->curroff); 549*65789Smckusick break; 550*65789Smckusick default: /* ISO_FTYPE_DEFAULT || ISO_FTYPE_9660 */ 551*65789Smckusick strcpy(idp->current.d_name,".."); 552*65789Smckusick switch (ep->name[0]) { 553*65789Smckusick case 0: 554*65789Smckusick idp->current.d_namlen = 1; 555*65789Smckusick error = iso_uiodir(idp,&idp->current,idp->curroff); 556*65789Smckusick break; 557*65789Smckusick case 1: 558*65789Smckusick idp->current.d_namlen = 2; 559*65789Smckusick error = iso_uiodir(idp,&idp->current,idp->curroff); 560*65789Smckusick break; 561*65789Smckusick default: 562*65789Smckusick isofntrans(ep->name,idp->current.d_namlen, 563*65789Smckusick idp->current.d_name, &elen, 564*65789Smckusick imp->iso_ftype == ISO_FTYPE_9660, 565*65789Smckusick isonum_711(ep->flags)&4); 566*65789Smckusick idp->current.d_namlen = (u_char)elen; 567*65789Smckusick if (imp->iso_ftype == ISO_FTYPE_DEFAULT) 568*65789Smckusick error = iso_shipdir(idp); 569*65789Smckusick else 570*65789Smckusick error = iso_uiodir(idp,&idp->current,idp->curroff); 571*65789Smckusick break; 572*65789Smckusick } 573*65789Smckusick } 574*65789Smckusick if (error) 575*65789Smckusick break; 576*65789Smckusick 577*65789Smckusick entryoffsetinblock += reclen; 578*65789Smckusick } 579*65789Smckusick 580*65789Smckusick if (!error && imp->iso_ftype == ISO_FTYPE_DEFAULT) { 581*65789Smckusick idp->current.d_namlen = 0; 582*65789Smckusick error = iso_shipdir(idp); 583*65789Smckusick } 584*65789Smckusick if (error < 0) 585*65789Smckusick error = 0; 586*65789Smckusick 587*65789Smckusick if (bp) 588*65789Smckusick brelse (bp); 589*65789Smckusick 590*65789Smckusick uio->uio_offset = idp->uio_off; 591*65789Smckusick #if 0 592*65789Smckusick *eofflagp = idp->eof; 593*65789Smckusick #endif 594*65789Smckusick 595*65789Smckusick FREE(idp,M_TEMP); 596*65789Smckusick 597*65789Smckusick return (error); 598*65789Smckusick } 599*65789Smckusick 600*65789Smckusick /* 601*65789Smckusick * Return target name of a symbolic link 602*65789Smckusick * Shouldn't we get the parent vnode and read the data from there? 603*65789Smckusick * This could eventually result in deadlocks in isofs_lookup. 604*65789Smckusick * But otherwise the block read here is in the block buffer two times. 605*65789Smckusick */ 606*65789Smckusick typedef struct iso_directory_record ISODIR; 607*65789Smckusick typedef struct iso_node ISONODE; 608*65789Smckusick typedef struct iso_mnt ISOMNT; 609*65789Smckusick int 610*65789Smckusick isofs_readlink(ap) 611*65789Smckusick struct vop_readlink_args /* { 612*65789Smckusick struct vnode *a_vp; 613*65789Smckusick struct uio *a_uio; 614*65789Smckusick struct ucred *a_cred; 615*65789Smckusick } */ *ap; 616*65789Smckusick { 617*65789Smckusick ISONODE *ip; 618*65789Smckusick ISODIR *dirp; 619*65789Smckusick ISOMNT *imp; 620*65789Smckusick struct buf *bp; 621*65789Smckusick u_short symlen; 622*65789Smckusick int error; 623*65789Smckusick char *symname; 624*65789Smckusick ino_t ino; 625*65789Smckusick 626*65789Smckusick ip = VTOI(ap->a_vp); 627*65789Smckusick imp = ip->i_mnt; 628*65789Smckusick 629*65789Smckusick if (imp->iso_ftype != ISO_FTYPE_RRIP) 630*65789Smckusick return EINVAL; 631*65789Smckusick 632*65789Smckusick /* 633*65789Smckusick * Get parents directory record block that this inode included. 634*65789Smckusick */ 635*65789Smckusick error = bread(imp->im_devvp, 636*65789Smckusick (daddr_t)(ip->i_number / DEV_BSIZE), 637*65789Smckusick imp->logical_block_size, 638*65789Smckusick NOCRED, 639*65789Smckusick &bp); 640*65789Smckusick if (error) { 641*65789Smckusick brelse(bp); 642*65789Smckusick return EINVAL; 643*65789Smckusick } 644*65789Smckusick 645*65789Smckusick /* 646*65789Smckusick * Setup the directory pointer for this inode 647*65789Smckusick */ 648*65789Smckusick dirp = (ISODIR *)(bp->b_un.b_addr + (ip->i_number & imp->im_bmask)); 649*65789Smckusick #ifdef DEBUG 650*65789Smckusick printf("lbn=%d,off=%d,bsize=%d,DEV_BSIZE=%d, dirp= %08x, b_addr=%08x, offset=%08x(%08x)\n", 651*65789Smckusick (daddr_t)(ip->i_number >> imp->im_bshift), 652*65789Smckusick ip->i_number & imp->im_bmask, 653*65789Smckusick imp->logical_block_size, 654*65789Smckusick DEV_BSIZE, 655*65789Smckusick dirp, 656*65789Smckusick bp->b_un.b_addr, 657*65789Smckusick ip->i_number, 658*65789Smckusick ip->i_number & imp->im_bmask ); 659*65789Smckusick #endif 660*65789Smckusick 661*65789Smckusick /* 662*65789Smckusick * Just make sure, we have a right one.... 663*65789Smckusick * 1: Check not cross boundary on block 664*65789Smckusick */ 665*65789Smckusick if ((ip->i_number & imp->im_bmask) + isonum_711(dirp->length) 666*65789Smckusick > imp->logical_block_size) { 667*65789Smckusick brelse(bp); 668*65789Smckusick return EINVAL; 669*65789Smckusick } 670*65789Smckusick 671*65789Smckusick /* 672*65789Smckusick * Now get a buffer 673*65789Smckusick * Abuse a namei buffer for now. 674*65789Smckusick */ 675*65789Smckusick MALLOC(symname,char *,MAXPATHLEN,M_NAMEI,M_WAITOK); 676*65789Smckusick 677*65789Smckusick /* 678*65789Smckusick * Ok, we just gathering a symbolic name in SL record. 679*65789Smckusick */ 680*65789Smckusick if (isofs_rrip_getsymname(dirp,symname,&symlen,imp) == 0) { 681*65789Smckusick FREE(symname,M_NAMEI); 682*65789Smckusick brelse(bp); 683*65789Smckusick return EINVAL; 684*65789Smckusick } 685*65789Smckusick /* 686*65789Smckusick * Don't forget before you leave from home ;-) 687*65789Smckusick */ 688*65789Smckusick brelse(bp); 689*65789Smckusick 690*65789Smckusick /* 691*65789Smckusick * return with the symbolic name to caller's. 692*65789Smckusick */ 693*65789Smckusick error = uiomove(symname,symlen,ap->a_uio); 694*65789Smckusick 695*65789Smckusick FREE(symname,M_NAMEI); 696*65789Smckusick 697*65789Smckusick return error; 698*65789Smckusick } 699*65789Smckusick 700*65789Smckusick /* 701*65789Smckusick * Ufs abort op, called after namei() when a CREATE/DELETE isn't actually 702*65789Smckusick * done. If a buffer has been saved in anticipation of a CREATE, delete it. 703*65789Smckusick */ 704*65789Smckusick int 705*65789Smckusick isofs_abortop(ap) 706*65789Smckusick struct vop_abortop_args /* { 707*65789Smckusick struct vnode *a_dvp; 708*65789Smckusick struct componentname *a_cnp; 709*65789Smckusick } */ *ap; 710*65789Smckusick { 711*65789Smckusick if ((ap->a_cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF) 712*65789Smckusick FREE(ap->a_cnp->cn_pnbuf, M_NAMEI); 713*65789Smckusick return 0; 714*65789Smckusick } 715*65789Smckusick 716*65789Smckusick /* 717*65789Smckusick * Lock an inode. 718*65789Smckusick */ 719*65789Smckusick int 720*65789Smckusick isofs_lock(ap) 721*65789Smckusick struct vop_lock_args /* { 722*65789Smckusick struct vnode *a_vp; 723*65789Smckusick } */ *ap; 724*65789Smckusick { 725*65789Smckusick register struct iso_node *ip = VTOI(ap->a_vp); 726*65789Smckusick 727*65789Smckusick ISO_ILOCK(ip); 728*65789Smckusick return 0; 729*65789Smckusick } 730*65789Smckusick 731*65789Smckusick /* 732*65789Smckusick * Unlock an inode. 733*65789Smckusick */ 734*65789Smckusick int 735*65789Smckusick isofs_unlock(ap) 736*65789Smckusick struct vop_unlock_args /* { 737*65789Smckusick struct vnode *a_vp; 738*65789Smckusick } */ *ap; 739*65789Smckusick { 740*65789Smckusick register struct iso_node *ip = VTOI(ap->a_vp); 741*65789Smckusick 742*65789Smckusick if (!(ip->i_flag & ILOCKED)) 743*65789Smckusick panic("isofs_unlock NOT LOCKED"); 744*65789Smckusick ISO_IUNLOCK(ip); 745*65789Smckusick return 0; 746*65789Smckusick } 747*65789Smckusick 748*65789Smckusick /* 749*65789Smckusick * Check for a locked inode. 750*65789Smckusick */ 751*65789Smckusick int 752*65789Smckusick isofs_islocked(ap) 753*65789Smckusick struct vop_islocked_args /* { 754*65789Smckusick struct vnode *a_vp; 755*65789Smckusick } */ *ap; 756*65789Smckusick { 757*65789Smckusick 758*65789Smckusick if (VTOI(ap->a_vp)->i_flag & ILOCKED) 759*65789Smckusick return 1; 760*65789Smckusick return 0; 761*65789Smckusick } 762*65789Smckusick 763*65789Smckusick /* 764*65789Smckusick * Calculate the logical to physical mapping if not done already, 765*65789Smckusick * then call the device strategy routine. 766*65789Smckusick */ 767*65789Smckusick int 768*65789Smckusick isofs_strategy(ap) 769*65789Smckusick struct vop_strategy_args /* { 770*65789Smckusick struct buf *a_bp; 771*65789Smckusick } */ *ap; 772*65789Smckusick { 773*65789Smckusick register struct buf *bp = ap->a_bp; 774*65789Smckusick register struct vnode *vp = bp->b_vp; 775*65789Smckusick register struct iso_node *ip; 776*65789Smckusick int error; 777*65789Smckusick 778*65789Smckusick ip = VTOI(vp); 779*65789Smckusick if (vp->v_type == VBLK || vp->v_type == VCHR) 780*65789Smckusick panic("isofs_strategy: spec"); 781*65789Smckusick if (bp->b_blkno == bp->b_lblkno) { 782*65789Smckusick if (error = 783*65789Smckusick VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno, NULL)) { 784*65789Smckusick bp->b_error = error; 785*65789Smckusick bp->b_flags |= B_ERROR; 786*65789Smckusick biodone(bp); 787*65789Smckusick return (error); 788*65789Smckusick } 789*65789Smckusick if ((long)bp->b_blkno == -1) 790*65789Smckusick clrbuf(bp); 791*65789Smckusick } 792*65789Smckusick if ((long)bp->b_blkno == -1) { 793*65789Smckusick biodone(bp); 794*65789Smckusick return (0); 795*65789Smckusick } 796*65789Smckusick vp = ip->i_devvp; 797*65789Smckusick bp->b_dev = vp->v_rdev; 798*65789Smckusick VOCALL (vp->v_op, VOFFSET(vop_strategy), ap); 799*65789Smckusick return (0); 800*65789Smckusick } 801*65789Smckusick 802*65789Smckusick /* 803*65789Smckusick * Print out the contents of an inode. 804*65789Smckusick */ 805*65789Smckusick int 806*65789Smckusick isofs_print(ap) 807*65789Smckusick struct vop_print_args /* { 808*65789Smckusick struct vnode *a_vp; 809*65789Smckusick } */ *ap; 810*65789Smckusick { 811*65789Smckusick printf("tag VT_ISOFS, isofs vnode\n"); 812*65789Smckusick return 0; 813*65789Smckusick } 814*65789Smckusick 815*65789Smckusick /* 816*65789Smckusick * Unsupported operation 817*65789Smckusick */ 818*65789Smckusick int 819*65789Smckusick isofs_enotsupp() 820*65789Smckusick { 821*65789Smckusick 822*65789Smckusick return (EOPNOTSUPP); 823*65789Smckusick } 824*65789Smckusick 825*65789Smckusick /* 826*65789Smckusick * Global vfs data structures for isofs 827*65789Smckusick */ 828*65789Smckusick #define isofs_create ((int (*) __P((struct vop_create_args *)))isofs_enotsupp) 829*65789Smckusick #define isofs_mknod ((int (*) __P((struct vop_mknod_args *)))isofs_enotsupp) 830*65789Smckusick #define isofs_setattr \ 831*65789Smckusick ((int (*) __P((struct vop_setattr_args *)))isofs_enotsupp) 832*65789Smckusick #define isofs_write ((int (*) __P((struct vop_write_args *)))isofs_enotsupp) 833*65789Smckusick #define isofs_fsync ((int (*) __P((struct vop_fsync_args *)))nullop) 834*65789Smckusick #define isofs_remove ((int (*) __P((struct vop_remove_args *)))isofs_enotsupp) 835*65789Smckusick #define isofs_link ((int (*) __P((struct vop_link_args *)))isofs_enotsupp) 836*65789Smckusick #define isofs_rename ((int (*) __P((struct vop_rename_args *)))isofs_enotsupp) 837*65789Smckusick #define isofs_mkdir ((int (*) __P((struct vop_mkdir_args *)))isofs_enotsupp) 838*65789Smckusick #define isofs_rmdir ((int (*) __P((struct vop_rmdir_args *)))isofs_enotsupp) 839*65789Smckusick #define isofs_symlink \ 840*65789Smckusick ((int (*) __P((struct vop_symlink_args *)))isofs_enotsupp) 841*65789Smckusick #define isofs_pathconf \ 842*65789Smckusick ((int (*) __P((struct vop_pathconf_args *)))isofs_enotsupp) 843*65789Smckusick #define isofs_advlock \ 844*65789Smckusick ((int (*) __P((struct vop_advlock_args *)))isofs_enotsupp) 845*65789Smckusick #define isofs_blkatoff \ 846*65789Smckusick ((int (*) __P((struct vop_blkatoff_args *)))isofs_enotsupp) 847*65789Smckusick #define isofs_valloc ((int(*) __P(( \ 848*65789Smckusick struct vnode *pvp, \ 849*65789Smckusick int mode, \ 850*65789Smckusick struct ucred *cred, \ 851*65789Smckusick struct vnode **vpp))) isofs_enotsupp) 852*65789Smckusick #define isofs_vfree ((int (*) __P((struct vop_vfree_args *)))isofs_enotsupp) 853*65789Smckusick #define isofs_truncate \ 854*65789Smckusick ((int (*) __P((struct vop_truncate_args *)))isofs_enotsupp) 855*65789Smckusick #define isofs_update ((int (*) __P((struct vop_update_args *)))isofs_enotsupp) 856*65789Smckusick #define isofs_bwrite ((int (*) __P((struct vop_bwrite_args *)))isofs_enotsupp) 857*65789Smckusick 858*65789Smckusick /* 859*65789Smckusick * Global vfs data structures for nfs 860*65789Smckusick */ 861*65789Smckusick int (**isofs_vnodeop_p)(); 862*65789Smckusick struct vnodeopv_entry_desc isofs_vnodeop_entries[] = { 863*65789Smckusick { &vop_default_desc, vn_default_error }, 864*65789Smckusick { &vop_lookup_desc, isofs_lookup }, /* lookup */ 865*65789Smckusick { &vop_create_desc, isofs_create }, /* create */ 866*65789Smckusick { &vop_mknod_desc, isofs_mknod }, /* mknod */ 867*65789Smckusick { &vop_open_desc, isofs_open }, /* open */ 868*65789Smckusick { &vop_close_desc, isofs_close }, /* close */ 869*65789Smckusick { &vop_access_desc, isofs_access }, /* access */ 870*65789Smckusick { &vop_getattr_desc, isofs_getattr }, /* getattr */ 871*65789Smckusick { &vop_setattr_desc, isofs_setattr }, /* setattr */ 872*65789Smckusick { &vop_read_desc, isofs_read }, /* read */ 873*65789Smckusick { &vop_write_desc, isofs_write }, /* write */ 874*65789Smckusick { &vop_ioctl_desc, isofs_ioctl }, /* ioctl */ 875*65789Smckusick { &vop_select_desc, isofs_select }, /* select */ 876*65789Smckusick { &vop_mmap_desc, isofs_mmap }, /* mmap */ 877*65789Smckusick { &vop_fsync_desc, isofs_fsync }, /* fsync */ 878*65789Smckusick { &vop_seek_desc, isofs_seek }, /* seek */ 879*65789Smckusick { &vop_remove_desc, isofs_remove }, /* remove */ 880*65789Smckusick { &vop_link_desc, isofs_link }, /* link */ 881*65789Smckusick { &vop_rename_desc, isofs_rename }, /* rename */ 882*65789Smckusick { &vop_mkdir_desc, isofs_mkdir }, /* mkdir */ 883*65789Smckusick { &vop_rmdir_desc, isofs_rmdir }, /* rmdir */ 884*65789Smckusick { &vop_symlink_desc, isofs_symlink }, /* symlink */ 885*65789Smckusick { &vop_readdir_desc, isofs_readdir }, /* readdir */ 886*65789Smckusick { &vop_readlink_desc, isofs_readlink }, /* readlink */ 887*65789Smckusick { &vop_abortop_desc, isofs_abortop }, /* abortop */ 888*65789Smckusick { &vop_inactive_desc, isofs_inactive }, /* inactive */ 889*65789Smckusick { &vop_reclaim_desc, isofs_reclaim }, /* reclaim */ 890*65789Smckusick { &vop_lock_desc, isofs_lock }, /* lock */ 891*65789Smckusick { &vop_unlock_desc, isofs_unlock }, /* unlock */ 892*65789Smckusick { &vop_bmap_desc, isofs_bmap }, /* bmap */ 893*65789Smckusick { &vop_strategy_desc, isofs_strategy }, /* strategy */ 894*65789Smckusick { &vop_print_desc, isofs_print }, /* print */ 895*65789Smckusick { &vop_islocked_desc, isofs_islocked }, /* islocked */ 896*65789Smckusick { &vop_pathconf_desc, isofs_pathconf }, /* pathconf */ 897*65789Smckusick { &vop_advlock_desc, isofs_advlock }, /* advlock */ 898*65789Smckusick { &vop_blkatoff_desc, isofs_blkatoff }, /* blkatoff */ 899*65789Smckusick { &vop_valloc_desc, isofs_valloc }, /* valloc */ 900*65789Smckusick { &vop_vfree_desc, isofs_vfree }, /* vfree */ 901*65789Smckusick { &vop_truncate_desc, isofs_truncate }, /* truncate */ 902*65789Smckusick { &vop_update_desc, isofs_update }, /* update */ 903*65789Smckusick { &vop_bwrite_desc, vn_bwrite }, 904*65789Smckusick { (struct vnodeop_desc*)NULL, (int(*)())NULL } 905*65789Smckusick }; 906*65789Smckusick struct vnodeopv_desc isofs_vnodeop_opv_desc = 907*65789Smckusick { &isofs_vnodeop_p, isofs_vnodeop_entries }; 908*65789Smckusick 909*65789Smckusick /* 910*65789Smckusick * Special device vnode ops 911*65789Smckusick */ 912*65789Smckusick int (**isofs_specop_p)(); 913*65789Smckusick struct vnodeopv_entry_desc isofs_specop_entries[] = { 914*65789Smckusick { &vop_default_desc, vn_default_error }, 915*65789Smckusick { &vop_lookup_desc, spec_lookup }, /* lookup */ 916*65789Smckusick { &vop_create_desc, isofs_create }, /* create */ 917*65789Smckusick { &vop_mknod_desc, isofs_mknod }, /* mknod */ 918*65789Smckusick { &vop_open_desc, spec_open }, /* open */ 919*65789Smckusick { &vop_close_desc, spec_close }, /* close */ 920*65789Smckusick { &vop_access_desc, isofs_access }, /* access */ 921*65789Smckusick { &vop_getattr_desc, isofs_getattr }, /* getattr */ 922*65789Smckusick { &vop_setattr_desc, isofs_setattr }, /* setattr */ 923*65789Smckusick { &vop_read_desc, spec_read }, /* read */ 924*65789Smckusick { &vop_write_desc, spec_write }, /* write */ 925*65789Smckusick { &vop_ioctl_desc, spec_ioctl }, /* ioctl */ 926*65789Smckusick { &vop_select_desc, spec_select }, /* select */ 927*65789Smckusick { &vop_mmap_desc, spec_mmap }, /* mmap */ 928*65789Smckusick { &vop_fsync_desc, spec_fsync }, /* fsync */ 929*65789Smckusick { &vop_seek_desc, spec_seek }, /* seek */ 930*65789Smckusick { &vop_remove_desc, isofs_remove }, /* remove */ 931*65789Smckusick { &vop_link_desc, isofs_link }, /* link */ 932*65789Smckusick { &vop_rename_desc, isofs_rename }, /* rename */ 933*65789Smckusick { &vop_mkdir_desc, isofs_mkdir }, /* mkdir */ 934*65789Smckusick { &vop_rmdir_desc, isofs_rmdir }, /* rmdir */ 935*65789Smckusick { &vop_symlink_desc, isofs_symlink }, /* symlink */ 936*65789Smckusick { &vop_readdir_desc, spec_readdir }, /* readdir */ 937*65789Smckusick { &vop_readlink_desc, spec_readlink }, /* readlink */ 938*65789Smckusick { &vop_abortop_desc, spec_abortop }, /* abortop */ 939*65789Smckusick { &vop_inactive_desc, isofs_inactive }, /* inactive */ 940*65789Smckusick { &vop_reclaim_desc, isofs_reclaim }, /* reclaim */ 941*65789Smckusick { &vop_lock_desc, isofs_lock }, /* lock */ 942*65789Smckusick { &vop_unlock_desc, isofs_unlock }, /* unlock */ 943*65789Smckusick { &vop_bmap_desc, spec_bmap }, /* bmap */ 944*65789Smckusick /* XXX strategy: panics, should be notsupp instead? */ 945*65789Smckusick { &vop_strategy_desc, isofs_strategy }, /* strategy */ 946*65789Smckusick { &vop_print_desc, isofs_print }, /* print */ 947*65789Smckusick { &vop_islocked_desc, isofs_islocked }, /* islocked */ 948*65789Smckusick { &vop_pathconf_desc, spec_pathconf }, /* pathconf */ 949*65789Smckusick { &vop_advlock_desc, spec_advlock }, /* advlock */ 950*65789Smckusick { &vop_blkatoff_desc, spec_blkatoff }, /* blkatoff */ 951*65789Smckusick { &vop_valloc_desc, spec_valloc }, /* valloc */ 952*65789Smckusick { &vop_vfree_desc, spec_vfree }, /* vfree */ 953*65789Smckusick { &vop_truncate_desc, spec_truncate }, /* truncate */ 954*65789Smckusick { &vop_update_desc, isofs_update }, /* update */ 955*65789Smckusick { &vop_bwrite_desc, vn_bwrite }, 956*65789Smckusick { (struct vnodeop_desc*)NULL, (int(*)())NULL } 957*65789Smckusick }; 958*65789Smckusick struct vnodeopv_desc isofs_specop_opv_desc = 959*65789Smckusick { &isofs_specop_p, isofs_specop_entries }; 960*65789Smckusick 961*65789Smckusick #ifdef FIFO 962*65789Smckusick int (**isofs_fifoop_p)(); 963*65789Smckusick struct vnodeopv_entry_desc isofs_fifoop_entries[] = { 964*65789Smckusick { &vop_default_desc, vn_default_error }, 965*65789Smckusick { &vop_lookup_desc, fifo_lookup }, /* lookup */ 966*65789Smckusick { &vop_create_desc, isofs_create }, /* create */ 967*65789Smckusick { &vop_mknod_desc, isofs_mknod }, /* mknod */ 968*65789Smckusick { &vop_open_desc, fifo_open }, /* open */ 969*65789Smckusick { &vop_close_desc, fifo_close }, /* close */ 970*65789Smckusick { &vop_access_desc, isofs_access }, /* access */ 971*65789Smckusick { &vop_getattr_desc, isofs_getattr }, /* getattr */ 972*65789Smckusick { &vop_setattr_desc, isofs_setattr }, /* setattr */ 973*65789Smckusick { &vop_read_desc, fifo_read }, /* read */ 974*65789Smckusick { &vop_write_desc, fifo_write }, /* write */ 975*65789Smckusick { &vop_ioctl_desc, fifo_ioctl }, /* ioctl */ 976*65789Smckusick { &vop_select_desc, fifo_select }, /* select */ 977*65789Smckusick { &vop_mmap_desc, fifo_mmap }, /* mmap */ 978*65789Smckusick { &vop_fsync_desc, fifo_fsync }, /* fsync */ 979*65789Smckusick { &vop_seek_desc, fifo_seek }, /* seek */ 980*65789Smckusick { &vop_remove_desc, isofs_remove }, /* remove */ 981*65789Smckusick { &vop_link_desc, isofs_link }, /* link */ 982*65789Smckusick { &vop_rename_desc, isofs_rename }, /* rename */ 983*65789Smckusick { &vop_mkdir_desc, isofs_mkdir }, /* mkdir */ 984*65789Smckusick { &vop_rmdir_desc, isofs_rmdir }, /* rmdir */ 985*65789Smckusick { &vop_symlink_desc, isofs_symlink }, /* symlink */ 986*65789Smckusick { &vop_readdir_desc, fifo_readdir }, /* readdir */ 987*65789Smckusick { &vop_readlink_desc, fifo_readlink }, /* readlink */ 988*65789Smckusick { &vop_abortop_desc, fifo_abortop }, /* abortop */ 989*65789Smckusick { &vop_inactive_desc, isofs_inactive }, /* inactive */ 990*65789Smckusick { &vop_reclaim_desc, isofs_reclaim }, /* reclaim */ 991*65789Smckusick { &vop_lock_desc, isofs_lock }, /* lock */ 992*65789Smckusick { &vop_unlock_desc, isofs_unlock }, /* unlock */ 993*65789Smckusick { &vop_bmap_desc, fifo_bmap }, /* bmap */ 994*65789Smckusick { &vop_strategy_desc, fifo_badop }, /* strategy */ 995*65789Smckusick { &vop_print_desc, isofs_print }, /* print */ 996*65789Smckusick { &vop_islocked_desc, isofs_islocked }, /* islocked */ 997*65789Smckusick { &vop_pathconf_desc, fifo_pathconf }, /* pathconf */ 998*65789Smckusick { &vop_advlock_desc, fifo_advlock }, /* advlock */ 999*65789Smckusick { &vop_blkatoff_desc, fifo_blkatoff }, /* blkatoff */ 1000*65789Smckusick { &vop_valloc_desc, fifo_valloc }, /* valloc */ 1001*65789Smckusick { &vop_vfree_desc, fifo_vfree }, /* vfree */ 1002*65789Smckusick { &vop_truncate_desc, fifo_truncate }, /* truncate */ 1003*65789Smckusick { &vop_update_desc, isofs_update }, /* update */ 1004*65789Smckusick { &vop_bwrite_desc, vn_bwrite }, 1005*65789Smckusick { (struct vnodeop_desc*)NULL, (int(*)())NULL } 1006*65789Smckusick }; 1007*65789Smckusick struct vnodeopv_desc isofs_fifoop_opv_desc = 1008*65789Smckusick { &isofs_fifoop_p, isofs_fifoop_entries }; 1009*65789Smckusick #endif /* FIFO */ 1010