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