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 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * @(#)cd9660_vnops.c 8.19 (Berkeley) 5/27/95 35 * $FreeBSD: src/sys/isofs/cd9660/cd9660_vnops.c,v 1.62 1999/12/15 23:01:51 eivind Exp $ 36 */ 37 38 #include <sys/param.h> 39 #include <sys/systm.h> 40 #include <sys/uio.h> 41 #include <sys/proc.h> 42 #include <sys/kernel.h> 43 #include <sys/stat.h> 44 #include <sys/buf.h> 45 #include <sys/mount.h> 46 #include <sys/vnode.h> 47 #include <vfs/fifofs/fifo.h> 48 #include <sys/malloc.h> 49 #include <sys/dirent.h> 50 #include <sys/unistd.h> 51 #include <sys/filio.h> 52 #include <sys/lockf.h> 53 #include <sys/objcache.h> 54 55 #include <vm/vm.h> 56 #include <vm/vnode_pager.h> 57 58 #include <sys/buf2.h> 59 60 #include "iso.h" 61 #include "cd9660_mount.h" 62 #include "cd9660_node.h" 63 #include "iso_rrip.h" 64 65 static int cd9660_access(struct vop_access_args *); 66 static int cd9660_advlock(struct vop_advlock_args *); 67 static int cd9660_getattr(struct vop_getattr_args *); 68 static int cd9660_ioctl(struct vop_ioctl_args *); 69 static int cd9660_pathconf(struct vop_pathconf_args *); 70 static int cd9660_open(struct vop_open_args *); 71 static int cd9660_read(struct vop_read_args *); 72 static int cd9660_setattr(struct vop_setattr_args *); 73 struct isoreaddir; 74 static int iso_uiodir(struct isoreaddir *idp, struct dirent *dp, off_t off); 75 static int iso_shipdir(struct isoreaddir *idp); 76 static int cd9660_readdir(struct vop_readdir_args *); 77 static int cd9660_readlink(struct vop_readlink_args *ap); 78 static int cd9660_strategy(struct vop_strategy_args *); 79 static int cd9660_print(struct vop_print_args *); 80 81 /* 82 * Setattr call. Only allowed for block and character special devices. 83 * 84 * cd9660_setattr(struct vnode *a_vp, struct vattr *a_vap, 85 * struct ucred *a_cred, struct proc *a_p) 86 */ 87 int 88 cd9660_setattr(struct vop_setattr_args *ap) 89 { 90 struct vnode *vp = ap->a_vp; 91 struct vattr *vap = ap->a_vap; 92 93 if (vap->va_flags != (u_long)VNOVAL || vap->va_uid != (uid_t)VNOVAL || 94 vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_sec != VNOVAL || 95 vap->va_mtime.tv_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL) 96 return (EROFS); 97 if (vap->va_size != (u_quad_t)VNOVAL) { 98 switch (vp->v_type) { 99 case VDIR: 100 return (EISDIR); 101 case VLNK: 102 case VREG: 103 case VDATABASE: 104 return (EROFS); 105 case VCHR: 106 case VBLK: 107 case VSOCK: 108 case VFIFO: 109 default: 110 return (0); 111 } 112 } 113 return (0); 114 } 115 116 /* 117 * Check mode permission on inode pointer. Mode is READ, WRITE or EXEC. 118 * The mode is shifted to select the owner/group/other fields. The 119 * super user is granted all permissions. 120 * 121 * cd9660_access(struct vnode *a_vp, int a_mode, struct ucred *a_cred, 122 * struct proc *a_p) 123 */ 124 /* ARGSUSED */ 125 static int 126 cd9660_access(struct vop_access_args *ap) 127 { 128 struct vnode *vp = ap->a_vp; 129 struct iso_node *ip = VTOI(vp); 130 mode_t file_mode; 131 uid_t uid; 132 gid_t gid; 133 134 KKASSERT(vp->v_mount->mnt_flag & MNT_RDONLY); 135 136 file_mode = ip->inode.iso_mode; 137 file_mode &= (vp->v_type == VDIR ? 138 ip->i_mnt->im_dmask : ip->i_mnt->im_fmask); 139 uid = (ip->i_mnt->im_flags & ISOFSMNT_UID) ? 140 ip->i_mnt->im_uid : ip->inode.iso_uid; 141 gid = (ip->i_mnt->im_flags & ISOFSMNT_GID) ? 142 ip->i_mnt->im_gid : ip->inode.iso_gid; 143 144 return (vop_helper_access(ap, uid, gid, file_mode, 0)); 145 } 146 147 /* 148 * cd9660_getattr(struct vnode *a_vp, struct vattr *a_vap) 149 */ 150 static int 151 cd9660_getattr(struct vop_getattr_args *ap) 152 { 153 struct vnode *vp = ap->a_vp; 154 struct vattr *vap = ap->a_vap; 155 struct iso_node *ip = VTOI(vp); 156 157 vap->va_fsid = devid_from_dev(ip->i_dev); 158 vap->va_fileid = ip->i_number; 159 160 vap->va_mode = ip->inode.iso_mode; 161 vap->va_mode &= (vp->v_type == VDIR ? 162 ip->i_mnt->im_dmask : ip->i_mnt->im_fmask); 163 164 vap->va_nlink = ip->inode.iso_links; 165 vap->va_uid = (ip->i_mnt->im_flags & ISOFSMNT_UID) ? 166 ip->i_mnt->im_uid : ip->inode.iso_uid; 167 vap->va_gid = (ip->i_mnt->im_flags & ISOFSMNT_GID) ? 168 ip->i_mnt->im_gid : ip->inode.iso_gid; 169 vap->va_atime = ip->inode.iso_atime; 170 vap->va_mtime = ip->inode.iso_mtime; 171 vap->va_ctime = ip->inode.iso_ctime; 172 vap->va_rmajor = umajor(ip->inode.iso_rdev); 173 vap->va_rminor = uminor(ip->inode.iso_rdev); 174 175 vap->va_size = (u_quad_t)(unsigned long)ip->i_size; 176 if (ip->i_size == 0 && (vap->va_mode & S_IFMT) == S_IFLNK) { 177 struct vop_readlink_args rdlnk; 178 struct iovec aiov; 179 struct uio auio; 180 char *cp; 181 182 cp = kmalloc(MAXPATHLEN, M_TEMP, M_WAITOK); 183 aiov.iov_base = cp; 184 aiov.iov_len = MAXPATHLEN; 185 auio.uio_iov = &aiov; 186 auio.uio_iovcnt = 1; 187 auio.uio_offset = 0; 188 auio.uio_rw = UIO_READ; 189 auio.uio_segflg = UIO_SYSSPACE; 190 auio.uio_td = curthread; 191 auio.uio_resid = MAXPATHLEN; 192 rdlnk.a_uio = &auio; 193 rdlnk.a_vp = ap->a_vp; 194 rdlnk.a_cred = proc0.p_ucred; /* use root cred */ 195 if (cd9660_readlink(&rdlnk) == 0) 196 vap->va_size = MAXPATHLEN - auio.uio_resid; 197 kfree(cp, M_TEMP); 198 } 199 vap->va_flags = 0; 200 vap->va_gen = 1; 201 vap->va_blocksize = ip->i_mnt->logical_block_size; 202 vap->va_bytes = (u_quad_t) ip->i_size; 203 vap->va_type = vp->v_type; 204 vap->va_filerev = 0; 205 return (0); 206 } 207 208 /* 209 * Vnode op for ioctl. 210 * 211 * cd9660_ioctl(struct vnode *a_vp, int a_command, caddr_t a_data, 212 * int a_fflag, struct ucred *a_cred, struct proc *a_p) 213 */ 214 static int 215 cd9660_ioctl(struct vop_ioctl_args *ap) 216 { 217 struct vnode *vp = ap->a_vp; 218 struct iso_node *ip = VTOI(vp); 219 220 switch (ap->a_command) { 221 222 case FIOGETLBA: 223 *(int *)(ap->a_data) = ip->iso_start; 224 return 0; 225 default: 226 return (ENOTTY); 227 } 228 } 229 230 /* 231 * open is called when the kernel intends to read or memory map a vnode. 232 */ 233 static int 234 cd9660_open(struct vop_open_args *ap) 235 { 236 return(vop_stdopen(ap)); 237 } 238 239 /* 240 * Vnode op for reading. 241 * 242 * cd9660_read(struct vnode *a_vp, struct uio *a_uio, int a_ioflag, 243 * struct ucred *a_cred) 244 */ 245 static int 246 cd9660_read(struct vop_read_args *ap) 247 { 248 struct vnode *vp = ap->a_vp; 249 struct uio *uio = ap->a_uio; 250 struct iso_node *ip = VTOI(vp); 251 struct iso_mnt *imp; 252 struct buf *bp; 253 daddr_t lbn, rablock; 254 off_t raoffset; 255 off_t loffset; 256 off_t diff; 257 int rasize, error = 0; 258 int seqcount; 259 long size, n, on; 260 261 seqcount = ap->a_ioflag >> IO_SEQSHIFT; 262 263 if (uio->uio_resid == 0) 264 return (0); 265 if (uio->uio_offset < 0) 266 return (EINVAL); 267 ip->i_flag |= IN_ACCESS; 268 imp = ip->i_mnt; 269 do { 270 lbn = lblkno(imp, uio->uio_offset); 271 loffset = lblktooff(imp, lbn); 272 on = blkoff(imp, uio->uio_offset); 273 n = szmin((u_int)(imp->logical_block_size - on), 274 uio->uio_resid); 275 diff = (off_t)ip->i_size - uio->uio_offset; 276 if (diff <= 0) 277 return (0); 278 if (diff < n) 279 n = diff; 280 size = blksize(imp, ip, lbn); 281 rablock = lbn + 1; 282 raoffset = lblktooff(imp, rablock); 283 if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERR) == 0) { 284 if (raoffset < ip->i_size) { 285 error = cluster_read(vp, (off_t)ip->i_size, 286 loffset, size, 287 uio->uio_resid, 288 (ap->a_ioflag >> IO_SEQSHIFT) * 289 MAXBSIZE, 290 &bp); 291 } else { 292 error = bread(vp, loffset, size, &bp); 293 } 294 } else { 295 if (seqcount > 1 && 296 lblktosize(imp, rablock) < ip->i_size) { 297 rasize = blksize(imp, ip, rablock); 298 error = breadn(vp, loffset, size, &raoffset, 299 &rasize, 1, &bp); 300 } else 301 error = bread(vp, loffset, size, &bp); 302 } 303 n = imin(n, size - bp->b_resid); 304 if (error) { 305 brelse(bp); 306 return (error); 307 } 308 309 error = uiomove(bp->b_data + on, (int)n, uio); 310 brelse(bp); 311 } while (error == 0 && uio->uio_resid > 0 && n != 0); 312 return (error); 313 } 314 315 /* struct dirent + enough space for the maximum supported size */ 316 struct iso_dirent { 317 struct dirent de; 318 char de_name[_DIRENT_RECLEN(NAME_MAX) - sizeof(struct dirent)]; 319 }; 320 321 /* 322 * Structure for reading directories 323 */ 324 struct isoreaddir { 325 struct iso_dirent saveent; 326 struct iso_dirent assocent; 327 struct iso_dirent current; 328 off_t saveoff; 329 off_t assocoff; 330 off_t curroff; 331 struct uio *uio; 332 off_t uio_off; 333 int eofflag; 334 off_t *cookies; 335 int ncookies; 336 }; 337 338 int 339 iso_uiodir(struct isoreaddir *idp, struct dirent *dp, off_t off) 340 { 341 int error; 342 343 dp->d_name[dp->d_namlen] = 0; 344 345 if (idp->uio->uio_resid < _DIRENT_DIRSIZ(dp)) { 346 idp->eofflag = 0; 347 return (-1); 348 } 349 350 if (idp->cookies) { 351 if (idp->ncookies <= 0) { 352 idp->eofflag = 0; 353 return (-1); 354 } 355 356 *idp->cookies++ = off; 357 --idp->ncookies; 358 } 359 360 if ((error = uiomove((caddr_t) dp,_DIRENT_DIRSIZ(dp),idp->uio)) != 0) 361 return (error); 362 idp->uio_off = off; 363 return (0); 364 } 365 366 int 367 iso_shipdir(struct isoreaddir *idp) 368 { 369 struct dirent *dp; 370 int cl, sl, assoc; 371 int error; 372 char *cname, *sname; 373 374 cl = idp->current.de.d_namlen; 375 cname = idp->current.de.d_name; 376 assoc = (cl > 1) && (*cname == ASSOCCHAR); 377 if (assoc) { 378 cl--; 379 cname++; 380 } 381 382 dp = &idp->saveent.de; 383 sname = dp->d_name; 384 if (!(sl = dp->d_namlen)) { 385 dp = &idp->assocent.de; 386 sname = dp->d_name + 1; 387 sl = dp->d_namlen - 1; 388 } 389 if (sl > 0) { 390 if (sl != cl 391 || bcmp(sname,cname,sl)) { 392 if (idp->assocent.de.d_namlen) { 393 if ((error = iso_uiodir(idp,&idp->assocent.de,idp->assocoff)) != 0) 394 return (error); 395 idp->assocent.de.d_namlen = 0; 396 } 397 if (idp->saveent.de.d_namlen) { 398 if ((error = iso_uiodir(idp,&idp->saveent.de,idp->saveoff)) != 0) 399 return (error); 400 idp->saveent.de.d_namlen = 0; 401 } 402 } 403 } 404 if (assoc) { 405 idp->assocoff = idp->curroff; 406 bcopy(&idp->current,&idp->assocent,_DIRENT_DIRSIZ(&idp->current.de)); 407 } else { 408 idp->saveoff = idp->curroff; 409 bcopy(&idp->current,&idp->saveent,_DIRENT_DIRSIZ(&idp->current.de)); 410 } 411 return (0); 412 } 413 414 /* 415 * Vnode op for readdir 416 * 417 * cd9660_readdir(struct vnode *a_vp, struct uio *a_uio, struct ucred *a_cred, 418 * int *a_eofflag, int *a_ncookies, off_t *a_cookies) 419 */ 420 static int 421 cd9660_readdir(struct vop_readdir_args *ap) 422 { 423 struct uio *uio = ap->a_uio; 424 struct isoreaddir *idp; 425 struct vnode *vdp = ap->a_vp; 426 struct iso_node *dp; 427 struct iso_mnt *imp; 428 struct buf *bp = NULL; 429 struct iso_directory_record *ep; 430 int entryoffsetinblock; 431 doff_t endsearch; 432 u_long bmask; 433 int error = 0; 434 int reclen; 435 u_short namelen; 436 int ncookies = 0; 437 off_t *cookies = NULL; 438 439 dp = VTOI(vdp); 440 imp = dp->i_mnt; 441 bmask = imp->im_bmask; 442 443 error = vn_lock(vdp, LK_EXCLUSIVE | LK_RETRY | LK_FAILRECLAIM); 444 if (error) 445 return (error); 446 447 idp = kmalloc(sizeof(*idp), M_TEMP, M_WAITOK); 448 idp->saveent.de.d_namlen = idp->assocent.de.d_namlen = 0; 449 /* 450 * XXX 451 * Is it worth trying to figure out the type? 452 */ 453 idp->saveent.de.d_type = DT_UNKNOWN; 454 idp->assocent.de.d_type = DT_UNKNOWN; 455 idp->current.de.d_type = DT_UNKNOWN; 456 idp->uio = uio; 457 if (ap->a_ncookies == NULL) { 458 idp->cookies = NULL; 459 } else { 460 /* 461 * Guess the number of cookies needed. Guess at least 462 * 1 to avoid a degenerate case in malloc, and cap at 463 * a reasonable limit. 464 */ 465 ncookies = uio->uio_resid / 16 + 1; 466 if (ncookies > 1024) 467 ncookies = 1024; 468 cookies = kmalloc(ncookies * sizeof(off_t), M_TEMP, M_WAITOK); 469 idp->cookies = cookies; 470 idp->ncookies = ncookies; 471 } 472 idp->eofflag = 1; 473 idp->curroff = uio->uio_offset; 474 475 if ((entryoffsetinblock = idp->curroff & bmask) && 476 (error = cd9660_devblkatoff(vdp, idp->curroff, NULL, &bp))) { 477 kfree(idp, M_TEMP); 478 goto done; 479 } 480 endsearch = dp->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 if ((idp->curroff & bmask) == 0) { 489 if (bp != NULL) 490 brelse(bp); 491 if ((error = 492 cd9660_devblkatoff(vdp, idp->curroff, NULL, &bp)) != 0) 493 break; 494 entryoffsetinblock = 0; 495 } 496 /* 497 * Get pointer to next entry. 498 */ 499 ep = (struct iso_directory_record *) 500 ((char *)bp->b_data + entryoffsetinblock); 501 502 reclen = isonum_711(ep->length); 503 if (reclen == 0) { 504 /* skip to next block, if any */ 505 idp->curroff = 506 (idp->curroff & ~bmask) + imp->logical_block_size; 507 continue; 508 } 509 510 if (reclen < ISO_DIRECTORY_RECORD_SIZE) { 511 error = EINVAL; 512 /* illegal entry, stop */ 513 break; 514 } 515 516 if (entryoffsetinblock + reclen > imp->logical_block_size) { 517 error = EINVAL; 518 /* illegal directory, so stop looking */ 519 break; 520 } 521 522 idp->current.de.d_namlen = isonum_711(ep->name_len); 523 524 if (reclen < ISO_DIRECTORY_RECORD_SIZE + idp->current.de.d_namlen) { 525 error = EINVAL; 526 /* illegal entry, stop */ 527 break; 528 } 529 530 if (isonum_711(ep->flags)&2) 531 idp->current.de.d_ino = isodirino(ep, imp); 532 else 533 idp->current.de.d_ino = bp->b_bio1.bio_offset + 534 entryoffsetinblock; 535 536 idp->curroff += reclen; 537 538 switch (imp->iso_ftype) { 539 case ISO_FTYPE_RRIP: 540 { 541 ino_t cur_fileno = idp->current.de.d_ino; 542 cd9660_rrip_getname(ep,idp->current.de.d_name, &namelen, 543 &cur_fileno,imp); 544 idp->current.de.d_ino = cur_fileno; 545 idp->current.de.d_namlen = namelen; 546 if (idp->current.de.d_namlen) 547 error = iso_uiodir(idp,&idp->current.de,idp->curroff); 548 break; 549 } 550 default: /* ISO_FTYPE_DEFAULT || ISO_FTYPE_9660 || ISO_FTYPE_HIGH_SIERRA*/ 551 strcpy(idp->current.de.d_name,".."); 552 if (idp->current.de.d_namlen == 1 && ep->name[0] == 0) { 553 idp->current.de.d_namlen = 1; 554 error = iso_uiodir(idp,&idp->current.de,idp->curroff); 555 } else if (idp->current.de.d_namlen == 1 && ep->name[0] == 1) { 556 idp->current.de.d_namlen = 2; 557 error = iso_uiodir(idp,&idp->current.de,idp->curroff); 558 } else { 559 isofntrans(ep->name,idp->current.de.d_namlen, 560 idp->current.de.d_name, &namelen, 561 imp->iso_ftype == ISO_FTYPE_9660, 562 isonum_711(ep->flags)&4, 563 imp->joliet_level, 564 imp->im_flags, 565 imp->im_d2l); 566 idp->current.de.d_namlen = namelen; 567 if (imp->iso_ftype == ISO_FTYPE_DEFAULT) 568 error = iso_shipdir(idp); 569 else 570 error = iso_uiodir(idp,&idp->current.de,idp->curroff); 571 } 572 } 573 if (error) 574 break; 575 576 entryoffsetinblock += reclen; 577 } 578 579 if (!error && imp->iso_ftype == ISO_FTYPE_DEFAULT) { 580 idp->current.de.d_namlen = 0; 581 error = iso_shipdir(idp); 582 } 583 if (error < 0) 584 error = 0; 585 586 if (ap->a_ncookies != NULL) { 587 if (error) 588 kfree(cookies, M_TEMP); 589 else { 590 /* 591 * Work out the number of cookies actually used. 592 */ 593 *ap->a_ncookies = ncookies - idp->ncookies; 594 *ap->a_cookies = cookies; 595 } 596 } 597 598 if (bp) 599 brelse (bp); 600 601 uio->uio_offset = idp->uio_off; 602 *ap->a_eofflag = idp->eofflag; 603 604 kfree(idp, M_TEMP); 605 606 done: 607 vn_unlock(vdp); 608 return (error); 609 } 610 611 /* 612 * Return target name of a symbolic link 613 * Shouldn't we get the parent vnode and read the data from there? 614 * This could eventually result in deadlocks in cd9660_lookup. 615 * But otherwise the block read here is in the block buffer two times. 616 */ 617 typedef struct iso_directory_record ISODIR; 618 typedef struct iso_node ISONODE; 619 typedef struct iso_mnt ISOMNT; 620 /* 621 * cd9660_readlink(struct vnode *a_vp, struct uio *a_uio, struct ucred *a_cred) 622 */ 623 static int 624 cd9660_readlink(struct vop_readlink_args *ap) 625 { 626 ISONODE *ip; 627 ISODIR *dirp; 628 ISOMNT *imp; 629 struct buf *bp; 630 struct uio *uio; 631 u_short symlen; 632 int error; 633 char *symname; 634 635 ip = VTOI(ap->a_vp); 636 imp = ip->i_mnt; 637 uio = ap->a_uio; 638 639 if (imp->iso_ftype != ISO_FTYPE_RRIP) 640 return (EINVAL); 641 642 /* 643 * Get parents directory record block that this inode included. 644 */ 645 error = bread(imp->im_devvp, 646 rounddown2((off_t)ip->i_number, 1 << imp->im_bshift), 647 imp->logical_block_size, &bp); 648 if (error) { 649 brelse(bp); 650 return (EINVAL); 651 } 652 653 /* 654 * Setup the directory pointer for this inode 655 */ 656 dirp = (ISODIR *)(bp->b_data + (ip->i_number & imp->im_bmask)); 657 658 /* 659 * Just make sure, we have a right one.... 660 * 1: Check not cross boundary on block 661 */ 662 if ((ip->i_number & imp->im_bmask) + isonum_711(dirp->length) 663 > (unsigned)imp->logical_block_size) { 664 brelse(bp); 665 return (EINVAL); 666 } 667 668 /* 669 * Now get a buffer 670 * Abuse a namei buffer for now. 671 */ 672 if (uio->uio_segflg == UIO_SYSSPACE) 673 symname = uio->uio_iov->iov_base; 674 else 675 symname = objcache_get(namei_oc, M_WAITOK); 676 677 /* 678 * Ok, we just gathering a symbolic name in SL record. 679 */ 680 if (cd9660_rrip_getsymname(dirp, symname, &symlen, imp) == 0) { 681 if (uio->uio_segflg != UIO_SYSSPACE) 682 objcache_put(namei_oc, symname); 683 brelse(bp); 684 return (EINVAL); 685 } 686 /* 687 * Don't forget before you leave from home ;-) 688 */ 689 brelse(bp); 690 691 /* 692 * return with the symbolic name to caller's. 693 */ 694 if (uio->uio_segflg != UIO_SYSSPACE) { 695 error = uiomove(symname, symlen, uio); 696 objcache_put(namei_oc, symname); 697 return (error); 698 } 699 uio->uio_resid -= symlen; 700 uio->uio_iov->iov_base = (char *)uio->uio_iov->iov_base + symlen; 701 uio->uio_iov->iov_len -= symlen; 702 return (0); 703 } 704 705 /* 706 * Calculate the logical to physical mapping if not done already, 707 * then call the device strategy routine. 708 * 709 * cd9660_strategy(struct buf *a_vp, struct buf *a_bio) 710 */ 711 static int 712 cd9660_strategy(struct vop_strategy_args *ap) 713 { 714 struct bio *bio = ap->a_bio; 715 struct bio *nbio; 716 struct buf *bp = bio->bio_buf; 717 struct vnode *vp = ap->a_vp; 718 struct iso_node *ip; 719 int error; 720 721 ip = VTOI(vp); 722 if (vp->v_type == VBLK || vp->v_type == VCHR) 723 panic("cd9660_strategy: spec"); 724 nbio = push_bio(bio); 725 if (nbio->bio_offset == NOOFFSET) { 726 error = VOP_BMAP(vp, bio->bio_offset, 727 &nbio->bio_offset, NULL, NULL, bp->b_cmd); 728 if (error) { 729 bp->b_error = error; 730 bp->b_flags |= B_ERROR; 731 /* I/O was never started on nbio, must biodone(bio) */ 732 biodone(bio); 733 return (error); 734 } 735 if (nbio->bio_offset == NOOFFSET) 736 clrbuf(bp); 737 } 738 if (nbio->bio_offset == NOOFFSET) { 739 /* I/O was never started on nbio, must biodone(bio) */ 740 biodone(bio); 741 return (0); 742 } 743 vp = ip->i_devvp; 744 vn_strategy(vp, nbio); 745 return (0); 746 } 747 748 /* 749 * Print out the contents of an inode. 750 * 751 * cd9660_print(struct vnode *a_vp) 752 */ 753 static int 754 cd9660_print(struct vop_print_args *ap) 755 { 756 kprintf("tag VT_ISOFS, isofs vnode\n"); 757 return (0); 758 } 759 760 /* 761 * Return POSIX pathconf information applicable to cd9660 filesystems. 762 * 763 * cd9660_pathconf(struct vnode *a_vp, int a_name, register_t *a_retval) 764 */ 765 static int 766 cd9660_pathconf(struct vop_pathconf_args *ap) 767 { 768 switch (ap->a_name) { 769 case _PC_LINK_MAX: 770 *ap->a_retval = 1; 771 return (0); 772 case _PC_NAME_MAX: 773 if (VTOI(ap->a_vp)->i_mnt->iso_ftype == ISO_FTYPE_RRIP) 774 *ap->a_retval = NAME_MAX; 775 else 776 *ap->a_retval = 37; 777 return (0); 778 case _PC_PATH_MAX: 779 *ap->a_retval = PATH_MAX; 780 return (0); 781 case _PC_PIPE_BUF: 782 *ap->a_retval = PIPE_BUF; 783 return (0); 784 case _PC_CHOWN_RESTRICTED: 785 *ap->a_retval = 1; 786 return (0); 787 case _PC_NO_TRUNC: 788 *ap->a_retval = 1; 789 return (0); 790 default: 791 return (EINVAL); 792 } 793 /* NOTREACHED */ 794 } 795 796 /* 797 * Advisory lock support 798 */ 799 static int 800 cd9660_advlock(struct vop_advlock_args *ap) 801 { 802 struct iso_node *ip = VTOI(ap->a_vp); 803 return (lf_advlock(ap, &(ip->i_lockf), ip->i_size)); 804 } 805 806 /* 807 * Global vfs data structures for cd9660 808 */ 809 struct vop_ops cd9660_vnode_vops = { 810 .vop_default = vop_defaultop, 811 .vop_open = cd9660_open, 812 .vop_access = cd9660_access, 813 .vop_advlock = cd9660_advlock, 814 .vop_bmap = cd9660_bmap, 815 .vop_old_lookup = cd9660_lookup, 816 .vop_getattr = cd9660_getattr, 817 .vop_inactive = cd9660_inactive, 818 .vop_ioctl = cd9660_ioctl, 819 .vop_pathconf = cd9660_pathconf, 820 .vop_print = cd9660_print, 821 .vop_read = cd9660_read, 822 .vop_readdir = cd9660_readdir, 823 .vop_readlink = cd9660_readlink, 824 .vop_reclaim = cd9660_reclaim, 825 .vop_setattr = cd9660_setattr, 826 .vop_strategy = cd9660_strategy, 827 .vop_getpages = vop_stdgetpages, 828 .vop_putpages = vop_stdputpages 829 }; 830 831 /* 832 * Special device vnode ops 833 */ 834 struct vop_ops cd9660_spec_vops = { 835 .vop_default = vop_defaultop, 836 .vop_read = vop_stdnoread, 837 .vop_access = cd9660_access, 838 .vop_getattr = cd9660_getattr, 839 .vop_inactive = cd9660_inactive, 840 .vop_print = cd9660_print, 841 .vop_reclaim = cd9660_reclaim, 842 .vop_setattr = cd9660_setattr, 843 }; 844 845 struct vop_ops cd9660_fifo_vops = { 846 .vop_default = fifo_vnoperate, 847 .vop_access = cd9660_access, 848 .vop_getattr = cd9660_getattr, 849 .vop_inactive = cd9660_inactive, 850 .vop_print = cd9660_print, 851 .vop_reclaim = cd9660_reclaim, 852 .vop_setattr = cd9660_setattr, 853 }; 854