1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * VFS operations for High Sierra filesystem 30 */ 31 32 #include <sys/types.h> 33 #include <sys/isa_defs.h> 34 #include <sys/t_lock.h> 35 #include <sys/param.h> 36 #include <sys/systm.h> 37 #include <sys/sysmacros.h> 38 #include <sys/kmem.h> 39 #include <sys/signal.h> 40 #include <sys/user.h> 41 #include <sys/proc.h> 42 #include <sys/disp.h> 43 #include <sys/buf.h> 44 #include <sys/pathname.h> 45 #include <sys/vfs.h> 46 #include <sys/vfs_opreg.h> 47 #include <sys/vnode.h> 48 #include <sys/file.h> 49 #include <sys/uio.h> 50 #include <sys/conf.h> 51 #include <sys/policy.h> 52 53 #include <vm/page.h> 54 55 #include <sys/fs/snode.h> 56 #include <sys/fs/hsfs_spec.h> 57 #include <sys/fs/hsfs_isospec.h> 58 #include <sys/fs/hsfs_node.h> 59 #include <sys/fs/hsfs_impl.h> 60 #include <sys/fs/hsfs_susp.h> 61 #include <sys/fs/hsfs_rrip.h> 62 63 #include <sys/statvfs.h> 64 #include <sys/mount.h> 65 #include <sys/mntent.h> 66 #include <sys/swap.h> 67 #include <sys/errno.h> 68 #include <sys/debug.h> 69 #include "fs/fs_subr.h" 70 #include <sys/cmn_err.h> 71 #include <sys/bootconf.h> 72 73 #include <sys/sdt.h> 74 75 /* 76 * These are needed for the CDROMREADOFFSET Code 77 */ 78 #include <sys/cdio.h> 79 #include <sys/sunddi.h> 80 81 #define HSFS_CLKSET 82 83 #include <sys/modctl.h> 84 85 /* 86 * Options for mount. 87 */ 88 #define HOPT_GLOBAL MNTOPT_GLOBAL 89 #define HOPT_NOGLOBAL MNTOPT_NOGLOBAL 90 #define HOPT_MAPLCASE "maplcase" 91 #define HOPT_NOMAPLCASE "nomaplcase" 92 #define HOPT_NOTRAILDOT "notraildot" 93 #define HOPT_TRAILDOT "traildot" 94 #define HOPT_NRR "nrr" 95 #define HOPT_RR "rr" 96 #define HOPT_JOLIET "joliet" 97 #define HOPT_NOJOLIET "nojoliet" 98 #define HOPT_JOLIETLONG "jolietlong" 99 #define HOPT_VERS2 "vers2" 100 #define HOPT_NOVERS2 "novers2" 101 #define HOPT_RO MNTOPT_RO 102 103 static char *global_cancel[] = { HOPT_NOGLOBAL, NULL }; 104 static char *noglobal_cancel[] = { HOPT_GLOBAL, NULL }; 105 static char *mapl_cancel[] = { HOPT_NOMAPLCASE, NULL }; 106 static char *nomapl_cancel[] = { HOPT_MAPLCASE, NULL }; 107 static char *ro_cancel[] = { MNTOPT_RW, NULL }; 108 static char *rr_cancel[] = { HOPT_NRR, NULL }; 109 static char *nrr_cancel[] = { HOPT_RR, NULL }; 110 static char *joliet_cancel[] = { HOPT_NOJOLIET, NULL }; 111 static char *nojoliet_cancel[] = { HOPT_JOLIET, NULL }; 112 static char *vers2_cancel[] = { HOPT_NOVERS2, NULL }; 113 static char *novers2_cancel[] = { HOPT_VERS2, NULL }; 114 static char *trail_cancel[] = { HOPT_NOTRAILDOT, NULL }; 115 static char *notrail_cancel[] = { HOPT_TRAILDOT, NULL }; 116 117 static mntopt_t hsfs_options[] = { 118 { HOPT_GLOBAL, global_cancel, NULL, 0, NULL }, 119 { HOPT_NOGLOBAL, noglobal_cancel, NULL, MO_DEFAULT, NULL }, 120 { HOPT_MAPLCASE, mapl_cancel, NULL, MO_DEFAULT, NULL }, 121 { HOPT_NOMAPLCASE, nomapl_cancel, NULL, 0, NULL }, 122 { HOPT_RO, ro_cancel, NULL, MO_DEFAULT, NULL }, 123 { HOPT_RR, rr_cancel, NULL, MO_DEFAULT, NULL }, 124 { HOPT_NRR, nrr_cancel, NULL, 0, NULL }, 125 { HOPT_JOLIET, joliet_cancel, NULL, 0, NULL }, 126 { HOPT_NOJOLIET, nojoliet_cancel, NULL, 0, NULL }, 127 { HOPT_JOLIETLONG, NULL, NULL, 0, NULL }, 128 { HOPT_VERS2, vers2_cancel, NULL, 0, NULL }, 129 { HOPT_NOVERS2, novers2_cancel, NULL, 0, NULL }, 130 { HOPT_TRAILDOT, trail_cancel, NULL, MO_DEFAULT, NULL }, 131 { HOPT_NOTRAILDOT, notrail_cancel, NULL, 0, NULL }, 132 { "sector", NULL, "0", MO_HASVALUE, NULL}, 133 }; 134 135 static mntopts_t hsfs_proto_opttbl = { 136 sizeof (hsfs_options) / sizeof (mntopt_t), 137 hsfs_options 138 }; 139 140 /* 141 * Indicates whether to enable the I/O scheduling and readahead logic 142 * 1 - Enable, 0 - Do not Enable. 143 * Debugging purposes. 144 */ 145 int do_schedio = 1; 146 static int hsfsfstype; 147 static int hsfsinit(int, char *); 148 149 static vfsdef_t vfw = { 150 VFSDEF_VERSION, 151 "hsfs", 152 hsfsinit, 153 VSW_HASPROTO|VSW_STATS, /* We don't suppport remounting */ 154 &hsfs_proto_opttbl 155 }; 156 157 static struct modlfs modlfs = { 158 &mod_fsops, "filesystem for HSFS", &vfw 159 }; 160 161 static struct modlinkage modlinkage = { 162 MODREV_1, (void *)&modlfs, NULL 163 }; 164 165 char _depends_on[] = "fs/specfs"; 166 167 extern void hsched_init_caches(void); 168 extern void hsched_fini_caches(void); 169 170 171 int 172 _init(void) 173 { 174 return (mod_install(&modlinkage)); 175 } 176 177 int 178 _fini(void) 179 { 180 int error; 181 182 error = mod_remove(&modlinkage); 183 184 DTRACE_PROBE1(mod_remove, int, error); 185 186 if (error) 187 return (error); 188 189 mutex_destroy(&hs_mounttab_lock); 190 191 /* 192 * Tear down the operations vectors 193 */ 194 (void) vfs_freevfsops_by_type(hsfsfstype); 195 vn_freevnodeops(hsfs_vnodeops); 196 197 hs_fini_hsnode_cache(); 198 hsched_fini_caches(); 199 return (0); 200 } 201 202 int 203 _info(struct modinfo *modinfop) 204 { 205 return (mod_info(&modlinkage, modinfop)); 206 } 207 208 #define BDEVFLAG(dev) ((devopsp[getmajor(dev)])->devo_cb_ops->cb_flag) 209 210 kmutex_t hs_mounttab_lock; 211 struct hsfs *hs_mounttab = NULL; 212 213 /* default mode, uid, gid */ 214 mode_t hsfs_default_mode = 0555; 215 uid_t hsfs_default_uid = 0; 216 gid_t hsfs_default_gid = 3; 217 218 extern void hsched_init(struct hsfs *fsp, int fsid, 219 struct modlinkage *modlinkage); 220 extern void hsched_fini(struct hsfs_queue *hqueue); 221 extern void hsfs_init_kstats(struct hsfs *fsp, int fsid); 222 extern void hsfs_fini_kstats(struct hsfs *fsp); 223 224 static int hsfs_mount(struct vfs *vfsp, struct vnode *mvp, 225 struct mounta *uap, struct cred *cr); 226 static int hsfs_unmount(struct vfs *vfsp, int, struct cred *cr); 227 static int hsfs_root(struct vfs *vfsp, struct vnode **vpp); 228 static int hsfs_statvfs(struct vfs *vfsp, struct statvfs64 *sbp); 229 static int hsfs_vget(struct vfs *vfsp, struct vnode **vpp, struct fid *fidp); 230 static int hsfs_mountroot(struct vfs *, enum whymountroot); 231 232 static int hs_mountfs(struct vfs *vfsp, dev_t dev, char *path, 233 mode_t mode, int flags, struct cred *cr, int isroot); 234 static int hs_getrootvp(struct vfs *vfsp, struct hsfs *fsp, size_t pathsize); 235 static int hs_findhsvol(struct hsfs *fsp, struct vnode *vp, 236 struct hs_volume *hvp); 237 static int hs_parsehsvol(struct hsfs *fsp, uchar_t *volp, 238 struct hs_volume *hvp); 239 static int hs_findisovol(struct hsfs *fsp, struct vnode *vp, 240 struct hs_volume *hvp, 241 struct hs_volume *svp, 242 struct hs_volume *jvp); 243 static int hs_joliet_level(uchar_t *volp); 244 static int hs_parseisovol(struct hsfs *fsp, uchar_t *volp, 245 struct hs_volume *hvp); 246 static void hs_copylabel(struct hs_volume *, unsigned char *, int); 247 static int hs_getmdev(struct vfs *, char *fspec, int flags, dev_t *pdev, 248 mode_t *mode, cred_t *cr); 249 static int hs_findvoldesc(dev_t rdev, int desc_sec); 250 251 static int 252 hsfsinit(int fstype, char *name) 253 { 254 static const fs_operation_def_t hsfs_vfsops_template[] = { 255 VFSNAME_MOUNT, { .vfs_mount = hsfs_mount }, 256 VFSNAME_UNMOUNT, { .vfs_unmount = hsfs_unmount }, 257 VFSNAME_ROOT, { .vfs_root = hsfs_root }, 258 VFSNAME_STATVFS, { .vfs_statvfs = hsfs_statvfs }, 259 VFSNAME_VGET, { .vfs_vget = hsfs_vget }, 260 VFSNAME_MOUNTROOT, { .vfs_mountroot = hsfs_mountroot }, 261 NULL, NULL 262 }; 263 int error; 264 265 error = vfs_setfsops(fstype, hsfs_vfsops_template, NULL); 266 if (error != 0) { 267 cmn_err(CE_WARN, "hsfsinit: bad vfs ops template"); 268 return (error); 269 } 270 271 error = vn_make_ops(name, hsfs_vnodeops_template, &hsfs_vnodeops); 272 if (error != 0) { 273 (void) vfs_freevfsops_by_type(fstype); 274 cmn_err(CE_WARN, "hsfsinit: bad vnode ops template"); 275 return (error); 276 } 277 278 hsfsfstype = fstype; 279 mutex_init(&hs_mounttab_lock, NULL, MUTEX_DEFAULT, NULL); 280 hs_init_hsnode_cache(); 281 hsched_init_caches(); 282 return (0); 283 } 284 285 /*ARGSUSED*/ 286 static int 287 hsfs_mount(struct vfs *vfsp, struct vnode *mvp, 288 struct mounta *uap, struct cred *cr) 289 { 290 int vnode_busy; 291 dev_t dev; 292 struct pathname dpn; 293 int error; 294 mode_t mode; 295 int flags; /* this will hold the mount specific data */ 296 297 if ((error = secpolicy_fs_mount(cr, mvp, vfsp)) != 0) 298 return (error); 299 300 if (mvp->v_type != VDIR) 301 return (ENOTDIR); 302 303 /* mount option must be read only, else mount will be rejected */ 304 if (!(uap->flags & MS_RDONLY)) 305 return (EROFS); 306 307 /* 308 * We already told the framework that we don't support remounting. 309 */ 310 ASSERT(!(uap->flags & MS_REMOUNT)); 311 312 mutex_enter(&mvp->v_lock); 313 vnode_busy = (mvp->v_count != 1) || (mvp->v_flag & VROOT); 314 mutex_exit(&mvp->v_lock); 315 316 if ((uap->flags & MS_OVERLAY) == 0 && vnode_busy) { 317 return (EBUSY); 318 } 319 320 /* 321 * Check for the options that actually affect things 322 * at our level. 323 */ 324 flags = 0; 325 if (vfs_optionisset(vfsp, HOPT_NOMAPLCASE, NULL)) 326 flags |= HSFSMNT_NOMAPLCASE; 327 if (vfs_optionisset(vfsp, HOPT_NOTRAILDOT, NULL)) 328 flags |= HSFSMNT_NOTRAILDOT; 329 if (vfs_optionisset(vfsp, HOPT_NRR, NULL)) 330 flags |= HSFSMNT_NORRIP; 331 if (vfs_optionisset(vfsp, HOPT_NOJOLIET, NULL)) 332 flags |= HSFSMNT_NOJOLIET; 333 if (vfs_optionisset(vfsp, HOPT_JOLIETLONG, NULL)) 334 flags |= HSFSMNT_JOLIETLONG; 335 if (vfs_optionisset(vfsp, HOPT_NOVERS2, NULL)) 336 flags |= HSFSMNT_NOVERS2; 337 338 error = pn_get(uap->dir, (uap->flags & MS_SYSSPACE) ? 339 UIO_SYSSPACE : UIO_USERSPACE, &dpn); 340 if (error) 341 return (error); 342 343 error = hs_getmdev(vfsp, uap->spec, uap->flags, &dev, &mode, cr); 344 if (error != 0) { 345 pn_free(&dpn); 346 return (error); 347 } 348 349 /* 350 * If the device is a tape, return error 351 */ 352 if ((BDEVFLAG(dev) & D_TAPE) == D_TAPE) { 353 pn_free(&dpn); 354 return (ENOTBLK); 355 } 356 357 /* 358 * Mount the filesystem. 359 */ 360 error = hs_mountfs(vfsp, dev, dpn.pn_path, mode, flags, cr, 0); 361 pn_free(&dpn); 362 return (error); 363 } 364 365 /*ARGSUSED*/ 366 static int 367 hsfs_unmount( 368 struct vfs *vfsp, 369 int flag, 370 struct cred *cr) 371 { 372 struct hsfs **tspp; 373 struct hsfs *fsp; 374 375 if (secpolicy_fs_unmount(cr, vfsp) != 0) 376 return (EPERM); 377 378 /* 379 * forced unmount is not supported by this file system 380 * and thus, ENOTSUP is being returned. 381 */ 382 if (flag & MS_FORCE) 383 return (ENOTSUP); 384 385 fsp = VFS_TO_HSFS(vfsp); 386 387 if (fsp->hsfs_rootvp->v_count != 1) 388 return (EBUSY); 389 390 /* destroy all old pages and hsnodes for this vfs */ 391 if (hs_synchash(vfsp)) 392 return (EBUSY); 393 394 mutex_enter(&hs_mounttab_lock); 395 for (tspp = &hs_mounttab; *tspp != NULL; tspp = &(*tspp)->hsfs_next) { 396 if (*tspp == fsp) 397 break; 398 } 399 if (*tspp == NULL) { 400 mutex_exit(&hs_mounttab_lock); 401 panic("hsfs_unmount: vfs not mounted?"); 402 /*NOTREACHED*/ 403 } 404 405 *tspp = fsp->hsfs_next; 406 407 mutex_exit(&hs_mounttab_lock); 408 409 hsfs_fini_kstats(fsp); 410 (void) VOP_CLOSE(fsp->hsfs_devvp, FREAD, 1, (offset_t)0, cr); 411 VN_RELE(fsp->hsfs_devvp); 412 /* free path table space */ 413 if (fsp->hsfs_ptbl != NULL) 414 kmem_free(fsp->hsfs_ptbl, (size_t)fsp->hsfs_vol.ptbl_len); 415 /* free path table index table */ 416 if (fsp->hsfs_ptbl_idx != NULL) 417 kmem_free(fsp->hsfs_ptbl_idx, (size_t) 418 (fsp->hsfs_ptbl_idx_size * sizeof (struct ptable_idx))); 419 420 /* free "mounted on" pathame */ 421 if (fsp->hsfs_fsmnt != NULL) 422 kmem_free(fsp->hsfs_fsmnt, strlen(fsp->hsfs_fsmnt) + 1); 423 424 hsched_fini(fsp->hqueue); 425 kmem_free(fsp->hqueue, sizeof (struct hsfs_queue)); 426 427 mutex_destroy(&fsp->hsfs_free_lock); 428 rw_destroy(&fsp->hsfs_hash_lock); 429 430 kmem_free(fsp, sizeof (*fsp)); 431 return (0); 432 } 433 434 /*ARGSUSED*/ 435 static int 436 hsfs_root(struct vfs *vfsp, struct vnode **vpp) 437 { 438 *vpp = (VFS_TO_HSFS(vfsp))->hsfs_rootvp; 439 VN_HOLD(*vpp); 440 return (0); 441 } 442 443 /*ARGSUSED*/ 444 static int 445 hsfs_statvfs(struct vfs *vfsp, struct statvfs64 *sbp) 446 { 447 struct hsfs *fsp; 448 dev32_t d32; 449 450 fsp = VFS_TO_HSFS(vfsp); 451 if (fsp->hsfs_magic != HSFS_MAGIC) 452 return (EINVAL); 453 bzero(sbp, sizeof (*sbp)); 454 sbp->f_bsize = vfsp->vfs_bsize; 455 sbp->f_frsize = sbp->f_bsize; /* no fragment, same as block size */ 456 sbp->f_blocks = (fsblkcnt64_t)fsp->hsfs_vol.vol_size; 457 458 sbp->f_bfree = (fsblkcnt64_t)0; 459 sbp->f_bavail = (fsblkcnt64_t)0; 460 sbp->f_files = (fsfilcnt64_t)-1; 461 sbp->f_ffree = (fsfilcnt64_t)0; 462 sbp->f_favail = (fsfilcnt64_t)0; 463 (void) cmpldev(&d32, vfsp->vfs_dev); 464 sbp->f_fsid = d32; 465 (void) strcpy(sbp->f_basetype, vfssw[vfsp->vfs_fstype].vsw_name); 466 sbp->f_flag = vf_to_stf(vfsp->vfs_flag); 467 sbp->f_namemax = fsp->hsfs_namemax; 468 (void) strcpy(sbp->f_fstr, fsp->hsfs_vol.vol_id); 469 470 return (0); 471 } 472 473 /* 474 * Previously nodeid was declared as uint32_t. This has been changed 475 * to conform better with the ISO9660 standard. The standard states that 476 * a LBN can be a 32 bit number, as the MAKE_NODEID macro shifts this 477 * LBN 11 places left (LBN_TO_BYTE) and then shifts the result 5 right 478 * (divide by 32) we are left with the potential of an overflow if 479 * confined to a 32 bit value. 480 */ 481 482 static int 483 hsfs_vget(struct vfs *vfsp, struct vnode **vpp, struct fid *fidp) 484 { 485 struct hsfid *fid; 486 struct hsfs *fsp; 487 ino64_t nodeid; 488 int error; 489 490 fsp = (struct hsfs *)VFS_TO_HSFS(vfsp); 491 fid = (struct hsfid *)fidp; 492 493 /* 494 * Look for vnode on hashlist. 495 * If found, it's now active and the refcnt was incremented. 496 */ 497 498 rw_enter(&fsp->hsfs_hash_lock, RW_READER); 499 500 nodeid = fid->hf_ino; 501 502 if ((*vpp = hs_findhash(nodeid, fid->hf_dir_lbn, 503 (uint_t)fid->hf_dir_off, vfsp)) == NULL) { 504 /* 505 * Not in cache, so we need to remake it. 506 * hs_remakenode() will read the directory entry 507 * and then check again to see if anyone else has 508 * put it in the cache. 509 */ 510 rw_exit(&fsp->hsfs_hash_lock); 511 error = hs_remakenode(fid->hf_dir_lbn, (uint_t)fid->hf_dir_off, 512 vfsp, vpp); 513 return (error); 514 } 515 rw_exit(&fsp->hsfs_hash_lock); 516 return (0); 517 } 518 519 520 #define CHECKSUM_SIZE (64 * 1024) 521 522 /* 523 * Compute a CD-ROM fsid by checksumming the first 64K of data on the CD 524 * We use the 'fsp' argument to determine the location of the root 525 * directory entry, and we start reading from there. 526 */ 527 static int 528 compute_cdrom_id(struct hsfs *fsp, vnode_t *devvp) 529 { 530 uint_t secno; 531 struct hs_volume *hsvp = &fsp->hsfs_vol; 532 struct buf *bp; 533 int error; 534 int fsid; 535 536 secno = hsvp->root_dir.ext_lbn >> hsvp->lbn_secshift; 537 bp = bread(devvp->v_rdev, secno * 4, CHECKSUM_SIZE); 538 error = geterror(bp); 539 540 /* 541 * An error on read or a partial read means we asked 542 * for a nonexistant/corrupted piece of the device 543 * (including past-the-end of the media). Don't 544 * try to use the checksumming method then. 545 */ 546 if (!error && bp->b_bcount == CHECKSUM_SIZE) { 547 int *ibuf = (int *)bp->b_un.b_addr; 548 int i; 549 550 fsid = 0; 551 552 for (i = 0; i < CHECKSUM_SIZE / sizeof (int); i++) 553 fsid ^= ibuf[ i ]; 554 } else { 555 /* 556 * Fallback - use creation date 557 */ 558 fsid = hsvp->cre_date.tv_sec; 559 } 560 561 brelse(bp); 562 563 return (fsid); 564 } 565 566 567 /*ARGSUSED*/ 568 static int 569 hs_mountfs( 570 struct vfs *vfsp, 571 dev_t dev, 572 char *path, 573 mode_t mode, 574 int mount_flags, 575 struct cred *cr, 576 int isroot) 577 { 578 struct vnode *devvp; 579 struct hsfs *tsp; 580 struct hsfs *fsp = NULL; 581 struct vattr vap; 582 struct hsnode *hp; 583 int error; 584 struct timeval tv; 585 int fsid; 586 int use_rrip; 587 int use_vers2; 588 int use_joliet; 589 int has_rrip = 0; 590 int has_vers2 = 0; 591 int has_joliet = 0; 592 int force_rrip_off; 593 int force_vers2_off; 594 int force_joliet_off; 595 size_t pathbufsz = strlen(path) + 1; 596 int redo_rootvp; 597 598 struct hs_volume *svp; /* Supplemental VD for ISO-9660:1999 */ 599 struct hs_volume *jvp; /* Joliet VD */ 600 601 /* 602 * The rules for which extension will be used are: 603 * 1. No specific mount options given: 604 * - use rrip if available 605 * - use ISO9660:1999 if available 606 * - use joliet if available. 607 * 2. rrip/ISO9660:1999/joliet explicitly disabled via mount option: 608 * - use next "lower" extension 609 * 3. joliet/ISO9660:1999/rrip explicitly requested via mount option: 610 * - disable rrip support even if available 611 * - disable IOS9660:1999 support even if available 612 * 613 * We need to adjust these flags as we discover the extensions 614 * present. See below. These are just the starting values. 615 */ 616 use_rrip = (mount_flags & HSFSMNT_NORRIP) == 0; 617 use_vers2 = (mount_flags & HSFSMNT_NOVERS2) == 0; 618 use_joliet = (mount_flags & HSFSMNT_NOJOLIET) == 0; 619 620 /* 621 * Open the device 622 */ 623 devvp = makespecvp(dev, VBLK); 624 ASSERT(devvp != 0); 625 626 /* 627 * Open the target device (file) for read only. 628 */ 629 if (error = VOP_OPEN(&devvp, FREAD, cr)) { 630 VN_RELE(devvp); 631 return (error); 632 } 633 634 /* 635 * Refuse to go any further if this 636 * device is being used for swapping 637 */ 638 if (IS_SWAPVP(common_specvp(devvp))) { 639 error = EBUSY; 640 goto cleanup; 641 } 642 643 vap.va_mask = AT_SIZE; 644 if ((error = VOP_GETATTR(devvp, &vap, ATTR_COMM, cr)) != 0) { 645 cmn_err(CE_NOTE, "Cannot get attributes of the CD-ROM driver"); 646 goto cleanup; 647 } 648 649 /* 650 * Make sure we have a nonzero size partition. 651 * The current version of the SD driver will *not* fail the open 652 * of such a partition so we have to check for it here. 653 */ 654 if (vap.va_size == 0) { 655 error = ENXIO; 656 goto cleanup; 657 } 658 659 /* 660 * Init a new hsfs structure. 661 */ 662 fsp = kmem_zalloc(sizeof (*fsp), KM_SLEEP); 663 svp = kmem_zalloc(sizeof (*svp), KM_SLEEP); 664 jvp = kmem_zalloc(sizeof (*jvp), KM_SLEEP); 665 666 /* hardwire perms, uid, gid */ 667 fsp->hsfs_vol.vol_uid = hsfs_default_uid; 668 fsp->hsfs_vol.vol_gid = hsfs_default_gid; 669 fsp->hsfs_vol.vol_prot = hsfs_default_mode; 670 svp->vol_uid = hsfs_default_uid; 671 svp->vol_gid = hsfs_default_gid; 672 svp->vol_prot = hsfs_default_mode; 673 jvp->vol_uid = hsfs_default_uid; 674 jvp->vol_gid = hsfs_default_gid; 675 jvp->vol_prot = hsfs_default_mode; 676 677 /* 678 * Look for a Standard File Structure Volume Descriptor, 679 * of which there must be at least one. 680 * If found, check for volume size consistency. 681 * 682 * If svp->lbn_size is != 0, we did find a ISO-9660:1999 SVD 683 * If jvp->lbn_size is != 0, we did find a Joliet SVD. 684 */ 685 fsp->hsfs_namemax = ISO_FILE_NAMELEN; 686 fsp->hsfs_namelen = ISO_FILE_NAMELEN; 687 error = hs_findisovol(fsp, devvp, &fsp->hsfs_vol, svp, jvp); 688 if (error == EINVAL) /* no iso 9660 - try high sierra ... */ 689 error = hs_findhsvol(fsp, devvp, &fsp->hsfs_vol); 690 691 if (error) 692 goto cleanup; 693 694 DTRACE_PROBE4(findvol, 695 struct hsfs *, fsp, 696 struct hs_volume *, &fsp->hsfs_vol, 697 struct hs_volume *, svp, 698 struct hs_volume *, jvp); 699 700 /* 701 * Generate a file system ID from the CD-ROM, 702 * and check it for uniqueness. 703 * 704 * What we are aiming for is some chance of integrity 705 * across disk change. That is, if a client has an fhandle, 706 * it will be valid as long as the same disk is mounted. 707 */ 708 fsid = compute_cdrom_id(fsp, devvp); 709 710 mutex_enter(&hs_mounttab_lock); 711 712 if (fsid == 0 || fsid == -1) { 713 uniqtime(&tv); 714 fsid = tv.tv_sec; 715 } else /* make sure that the fsid is unique */ 716 for (tsp = hs_mounttab; tsp != NULL; tsp = tsp->hsfs_next) { 717 if (fsid == tsp->hsfs_vfs->vfs_fsid.val[0]) { 718 uniqtime(&tv); 719 fsid = tv.tv_sec; 720 break; 721 } 722 } 723 724 fsp->hsfs_next = hs_mounttab; 725 hs_mounttab = fsp; 726 727 fsp->hsfs_devvp = devvp; 728 fsp->hsfs_vfs = vfsp; 729 fsp->hsfs_fsmnt = kmem_alloc(pathbufsz, KM_SLEEP); 730 (void) strlcpy(fsp->hsfs_fsmnt, path, pathbufsz); 731 732 mutex_init(&fsp->hsfs_free_lock, NULL, MUTEX_DEFAULT, NULL); 733 rw_init(&fsp->hsfs_hash_lock, NULL, RW_DEFAULT, NULL); 734 735 vfsp->vfs_data = (caddr_t)fsp; 736 vfsp->vfs_dev = dev; 737 vfsp->vfs_fstype = hsfsfstype; 738 vfsp->vfs_bsize = fsp->hsfs_vol.lbn_size; /* %% */ 739 vfsp->vfs_fsid.val[0] = fsid; 740 vfsp->vfs_fsid.val[1] = hsfsfstype; 741 742 if (!hs_getrootvp(vfsp, fsp, pathbufsz)) { 743 DTRACE_PROBE1(rootvp__failed, struct hsfs *, fsp); 744 error = EINVAL; 745 goto cleanup; 746 } 747 DTRACE_PROBE1(rootvp, struct hsfs *, fsp); 748 749 /* 750 * Attempt to discover a RR extension. 751 */ 752 if (use_rrip) { 753 hp = VTOH(fsp->hsfs_rootvp); 754 hs_check_root_dirent(fsp->hsfs_rootvp, &(hp->hs_dirent)); 755 } 756 757 has_rrip = IS_RRIP_IMPLEMENTED(fsp); 758 has_vers2 = (svp->lbn_size != 0); 759 has_joliet = (jvp->lbn_size != 0); 760 761 DTRACE_PROBE4(voltype__suggested, struct hsfs *, fsp, 762 int, use_rrip, int, use_vers2, int, use_joliet); 763 764 DTRACE_PROBE4(voltype__actual, struct hsfs *, fsp, 765 int, has_rrip, int, has_vers2, int, has_joliet); 766 767 DTRACE_PROBE4(findvol, 768 struct hsfs *, fsp, 769 struct hs_volume *, &fsp->hsfs_vol, 770 struct hs_volume *, svp, 771 struct hs_volume *, jvp); 772 773 force_rrip_off = !use_rrip || 774 (vfs_optionisset(vfsp, HOPT_JOLIET, NULL) && has_joliet) || 775 (vfs_optionisset(vfsp, HOPT_VERS2, NULL) && has_vers2); 776 777 force_vers2_off = !use_vers2 || 778 (vfs_optionisset(vfsp, HOPT_JOLIET, NULL) && has_joliet); 779 780 force_joliet_off = !use_joliet; 781 782 DTRACE_PROBE4(voltype__force_off, struct hsfs *, fsp, 783 int, force_rrip_off, int, force_vers2_off, int, force_joliet_off); 784 785 /* 786 * At the moment, we have references of all three possible 787 * extensions (RR, ISO9660:1999/v2 and Joliet) if present. 788 * 789 * The "active" volume descriptor is RRIP (or ISO9660:1988). 790 * We now switch to the user-requested one. 791 */ 792 redo_rootvp = 0; 793 794 if (force_rrip_off || !has_rrip) { 795 if (has_vers2 && !force_vers2_off) { 796 VN_RELE(fsp->hsfs_rootvp); 797 bcopy(svp, &fsp->hsfs_vol, sizeof (struct hs_volume)); 798 fsp->hsfs_vol_type = HS_VOL_TYPE_ISO_V2; 799 vfsp->vfs_bsize = fsp->hsfs_vol.lbn_size; 800 redo_rootvp = 1; 801 has_joliet = 0; 802 } else if (has_joliet && !force_joliet_off) { 803 VN_RELE(fsp->hsfs_rootvp); 804 bcopy(jvp, &fsp->hsfs_vol, sizeof (struct hs_volume)); 805 fsp->hsfs_vol_type = HS_VOL_TYPE_JOLIET; 806 vfsp->vfs_bsize = fsp->hsfs_vol.lbn_size; 807 redo_rootvp = 1; 808 has_vers2 = 0; 809 } 810 } 811 812 if (redo_rootvp) { 813 /* 814 * Make sure not to use Rock Ridge. 815 */ 816 UNSET_IMPL_BIT(fsp, RRIP_BIT); 817 UNSET_SUSP_BIT(fsp); 818 has_rrip = 0; 819 820 if (!hs_getrootvp(vfsp, fsp, pathbufsz)) { 821 DTRACE_PROBE1(rootvp__failed, struct hsfs *, fsp); 822 error = EINVAL; 823 goto cleanup; 824 } 825 DTRACE_PROBE1(rootvp, struct hsfs *, fsp); 826 } 827 if (IS_RRIP_IMPLEMENTED(fsp)) { 828 has_vers2 = 0; 829 has_joliet = 0; 830 } 831 if (force_vers2_off) 832 has_vers2 = 0; 833 if (force_joliet_off) 834 has_joliet = 0; 835 DTRACE_PROBE4(voltype__taken, struct hsfs *, fsp, 836 int, has_rrip, int, has_vers2, int, has_joliet); 837 838 /* 839 * mark root node as VROOT 840 */ 841 fsp->hsfs_rootvp->v_flag |= VROOT; 842 843 /* Here we take care of some special case stuff for mountroot */ 844 if (isroot) { 845 fsp->hsfs_rootvp->v_rdev = devvp->v_rdev; 846 rootvp = fsp->hsfs_rootvp; 847 } 848 849 if (IS_RRIP_IMPLEMENTED(fsp)) { 850 /* 851 * if RRIP, don't copy NOMAPLCASE or NOTRAILDOT to hsfs_flags 852 */ 853 mount_flags &= ~(HSFSMNT_NOMAPLCASE | HSFSMNT_NOTRAILDOT); 854 855 fsp->hsfs_namemax = RRIP_FILE_NAMELEN; 856 fsp->hsfs_namelen = RRIP_FILE_NAMELEN; 857 858 ASSERT(vfs_optionisset(vfsp, HOPT_RR, NULL)); 859 vfs_clearmntopt(vfsp, HOPT_VERS2); 860 vfs_clearmntopt(vfsp, HOPT_JOLIET); 861 862 } else switch (fsp->hsfs_vol_type) { 863 864 case HS_VOL_TYPE_HS: 865 case HS_VOL_TYPE_ISO: 866 default: 867 /* 868 * if iso v1, don't allow trailing spaces in iso file names 869 */ 870 mount_flags |= HSFSMNT_NOTRAILSPACE; 871 fsp->hsfs_namemax = ISO_NAMELEN_V2_MAX; 872 fsp->hsfs_namelen = ISO_FILE_NAMELEN; 873 vfs_clearmntopt(vfsp, HOPT_RR); 874 vfs_clearmntopt(vfsp, HOPT_VERS2); 875 vfs_clearmntopt(vfsp, HOPT_JOLIET); 876 break; 877 878 case HS_VOL_TYPE_ISO_V2: 879 /* 880 * if iso v2, don't copy NOTRAILDOT to hsfs_flags 881 */ 882 mount_flags &= ~HSFSMNT_NOTRAILDOT; 883 mount_flags |= HSFSMNT_NOMAPLCASE | HSFSMNT_NOVERSION; 884 fsp->hsfs_namemax = ISO_NAMELEN_V2_MAX; 885 fsp->hsfs_namelen = ISO_NAMELEN_V2; 886 vfs_setmntopt(vfsp, HOPT_VERS2, NULL, 0); 887 vfs_clearmntopt(vfsp, HOPT_RR); 888 vfs_clearmntopt(vfsp, HOPT_JOLIET); 889 break; 890 891 case HS_VOL_TYPE_JOLIET: 892 /* 893 * if Joliet, don't copy NOMAPLCASE or NOTRAILDOT to hsfs_flags 894 */ 895 mount_flags &= ~(HSFSMNT_NOMAPLCASE | HSFSMNT_NOTRAILDOT); 896 mount_flags |= HSFSMNT_NOMAPLCASE; 897 if (mount_flags & HSFSMNT_JOLIETLONG) 898 fsp->hsfs_namemax = JOLIET_NAMELEN_MAX*3; /* UTF-8 */ 899 else 900 fsp->hsfs_namemax = MAXNAMELEN-1; 901 fsp->hsfs_namelen = JOLIET_NAMELEN*2; 902 vfs_setmntopt(vfsp, HOPT_JOLIET, NULL, 0); 903 vfs_clearmntopt(vfsp, HOPT_RR); 904 vfs_clearmntopt(vfsp, HOPT_VERS2); 905 break; 906 } 907 908 /* 909 * Add the HSFSMNT_INODE pseudo mount flag to the current mount flags. 910 */ 911 fsp->hsfs_flags = mount_flags | (fsp->hsfs_flags & HSFSMNT_INODE); 912 913 /* 914 * Setup I/O Scheduling structures 915 */ 916 if (do_schedio) { 917 fsp->hqueue = kmem_alloc(sizeof (struct hsfs_queue), KM_SLEEP); 918 hsched_init(fsp, fsid, &modlinkage); 919 } 920 921 /* 922 * Setup kstats 923 */ 924 hsfs_init_kstats(fsp, fsid); 925 926 DTRACE_PROBE1(mount__done, struct hsfs *, fsp); 927 928 /* 929 * set the magic word 930 */ 931 fsp->hsfs_magic = HSFS_MAGIC; 932 mutex_exit(&hs_mounttab_lock); 933 934 kmem_free(svp, sizeof (*svp)); 935 kmem_free(jvp, sizeof (*jvp)); 936 937 return (0); 938 939 cleanup: 940 (void) VOP_CLOSE(devvp, FREAD, 1, (offset_t)0, cr); 941 VN_RELE(devvp); 942 if (fsp) 943 kmem_free(fsp, sizeof (*fsp)); 944 if (svp) 945 kmem_free(svp, sizeof (*svp)); 946 if (jvp) 947 kmem_free(jvp, sizeof (*jvp)); 948 return (error); 949 } 950 951 /* 952 * Get the rootvp associated with fsp->hsfs_vol 953 */ 954 static int 955 hs_getrootvp( 956 struct vfs *vfsp, 957 struct hsfs *fsp, 958 size_t pathsize) 959 { 960 struct hsnode *hp; 961 962 ASSERT(pathsize == strlen(fsp->hsfs_fsmnt) + 1); 963 964 /* 965 * If the root directory does not appear to be 966 * valid, use what it points to as "." instead. 967 * Some Defense Mapping Agency disks are non-conformant 968 * in this way. 969 */ 970 if (!hsfs_valid_dir(&fsp->hsfs_vol.root_dir)) { 971 hs_log_bogus_disk_warning(fsp, HSFS_ERR_BAD_ROOT_DIR, 0); 972 if (hs_remakenode(fsp->hsfs_vol.root_dir.ext_lbn, 973 (uint_t)0, vfsp, &fsp->hsfs_rootvp)) { 974 hs_mounttab = hs_mounttab->hsfs_next; 975 mutex_destroy(&fsp->hsfs_free_lock); 976 rw_destroy(&fsp->hsfs_hash_lock); 977 kmem_free(fsp->hsfs_fsmnt, pathsize); 978 mutex_exit(&hs_mounttab_lock); 979 return (0); 980 } 981 } else { 982 fsp->hsfs_rootvp = hs_makenode(&fsp->hsfs_vol.root_dir, 983 fsp->hsfs_vol.root_dir.ext_lbn, 0, vfsp); 984 } 985 986 /* XXX - ignore the path table for now */ 987 fsp->hsfs_ptbl = NULL; 988 hp = VTOH(fsp->hsfs_rootvp); 989 hp->hs_ptbl_idx = NULL; 990 991 return (1); 992 } 993 994 /* 995 * hs_findhsvol() 996 * 997 * Locate the Standard File Structure Volume Descriptor and 998 * parse it into an hs_volume structure. 999 * 1000 * XXX - May someday want to look for Coded Character Set FSVD, too. 1001 */ 1002 static int 1003 hs_findhsvol(struct hsfs *fsp, struct vnode *vp, struct hs_volume *hvp) 1004 { 1005 struct buf *secbp; 1006 int i; 1007 int n; 1008 uchar_t *volp; 1009 int error; 1010 uint_t secno; 1011 1012 secno = hs_findvoldesc(vp->v_rdev, HS_VOLDESC_SEC); 1013 secbp = bread(vp->v_rdev, secno * 4, HS_SECTOR_SIZE); 1014 error = geterror(secbp); 1015 1016 if (error != 0) { 1017 cmn_err(CE_NOTE, "hs_findhsvol: bread: error=(%d)", error); 1018 brelse(secbp); 1019 return (error); 1020 } 1021 1022 volp = (uchar_t *)secbp->b_un.b_addr; 1023 1024 /* 1025 * To avoid that we read the whole medium in case that someone prepares 1026 * a malicious "fs image", we read at most 32 blocks. 1027 */ 1028 for (n = 0; n < 32 && 1029 HSV_DESC_TYPE(volp) != VD_EOV; n++) { 1030 for (i = 0; i < HSV_ID_STRLEN; i++) 1031 if (HSV_STD_ID(volp)[i] != HSV_ID_STRING[i]) 1032 goto cantfind; 1033 if (HSV_STD_VER(volp) != HSV_ID_VER) 1034 goto cantfind; 1035 switch (HSV_DESC_TYPE(volp)) { 1036 case VD_SFS: 1037 /* Standard File Structure */ 1038 fsp->hsfs_vol_type = HS_VOL_TYPE_HS; 1039 error = hs_parsehsvol(fsp, volp, hvp); 1040 brelse(secbp); 1041 return (error); 1042 1043 case VD_CCFS: 1044 /* Coded Character File Structure */ 1045 case VD_BOOT: 1046 case VD_UNSPEC: 1047 case VD_EOV: 1048 break; 1049 } 1050 brelse(secbp); 1051 ++secno; 1052 secbp = bread(vp->v_rdev, secno * 4, HS_SECTOR_SIZE); 1053 1054 error = geterror(secbp); 1055 1056 if (error != 0) { 1057 cmn_err(CE_NOTE, "hs_findhsvol: bread: error=(%d)", 1058 error); 1059 brelse(secbp); 1060 return (error); 1061 } 1062 1063 volp = (uchar_t *)secbp->b_un.b_addr; 1064 } 1065 cantfind: 1066 brelse(secbp); 1067 return (EINVAL); 1068 } 1069 1070 /* 1071 * hs_parsehsvol 1072 * 1073 * Parse the Standard File Structure Volume Descriptor into 1074 * an hs_volume structure. We can't just bcopy it into the 1075 * structure because of byte-ordering problems. 1076 * 1077 */ 1078 static int 1079 hs_parsehsvol(struct hsfs *fsp, uchar_t *volp, struct hs_volume *hvp) 1080 { 1081 hvp->vol_size = HSV_VOL_SIZE(volp); 1082 hvp->lbn_size = HSV_BLK_SIZE(volp); 1083 if (hvp->lbn_size == 0) { 1084 cmn_err(CE_NOTE, "hs_parsehsvol: logical block size in the " 1085 "SFSVD is zero"); 1086 return (EINVAL); 1087 } 1088 hvp->lbn_shift = ffs((long)hvp->lbn_size) - 1; 1089 hvp->lbn_secshift = 1090 ffs((long)howmany(HS_SECTOR_SIZE, (int)hvp->lbn_size)) - 1; 1091 hvp->lbn_maxoffset = hvp->lbn_size - 1; 1092 hs_parse_longdate(HSV_cre_date(volp), &hvp->cre_date); 1093 hs_parse_longdate(HSV_mod_date(volp), &hvp->mod_date); 1094 hvp->file_struct_ver = HSV_FILE_STRUCT_VER(volp); 1095 hvp->ptbl_len = HSV_PTBL_SIZE(volp); 1096 hvp->vol_set_size = (ushort_t)HSV_SET_SIZE(volp); 1097 hvp->vol_set_seq = (ushort_t)HSV_SET_SEQ(volp); 1098 #if defined(_LITTLE_ENDIAN) 1099 hvp->ptbl_lbn = HSV_PTBL_MAN_LS(volp); 1100 #else 1101 hvp->ptbl_lbn = HSV_PTBL_MAN_MS(volp); 1102 #endif 1103 hs_copylabel(hvp, HSV_VOL_ID(volp), 0); 1104 1105 /* 1106 * Make sure that lbn_size is a power of two and otherwise valid. 1107 */ 1108 if (hvp->lbn_size & ~(1 << hvp->lbn_shift)) { 1109 cmn_err(CE_NOTE, 1110 "hsfs: %d-byte logical block size not supported", 1111 hvp->lbn_size); 1112 return (EINVAL); 1113 } 1114 return (hs_parsedir(fsp, HSV_ROOT_DIR(volp), &hvp->root_dir, 1115 (char *)NULL, (int *)NULL, HDE_ROOT_DIR_REC_SIZE)); 1116 } 1117 1118 /* 1119 * hs_findisovol() 1120 * 1121 * Locate the Primary Volume Descriptor 1122 * parse it into an hs_volume structure. 1123 * 1124 * XXX - Partition not yet done 1125 * 1126 * Except for fsp->hsfs_vol_type, no fsp member may be modified. 1127 * fsp->hsfs_vol is modified indirectly via the *hvp argument. 1128 */ 1129 static int 1130 hs_findisovol(struct hsfs *fsp, struct vnode *vp, 1131 struct hs_volume *hvp, 1132 struct hs_volume *svp, 1133 struct hs_volume *jvp) 1134 { 1135 struct buf *secbp; 1136 int i; 1137 int n; 1138 uchar_t *volp; 1139 int error; 1140 uint_t secno; 1141 int foundpvd = 0; 1142 int foundsvd = 0; 1143 int foundjvd = 0; 1144 int pvd_sum = 0; 1145 1146 secno = hs_findvoldesc(vp->v_rdev, ISO_VOLDESC_SEC); 1147 secbp = bread(vp->v_rdev, secno * 4, ISO_SECTOR_SIZE); 1148 error = geterror(secbp); 1149 1150 if (error != 0) { 1151 cmn_err(CE_NOTE, "hs_findisovol: bread: error=(%d)", error); 1152 brelse(secbp); 1153 return (error); 1154 } 1155 1156 volp = (uchar_t *)secbp->b_un.b_addr; 1157 1158 /* 1159 * To avoid that we read the whole medium in case that someone prepares 1160 * a malicious "fs image", we read at most 32 blocks. 1161 */ 1162 for (n = 0; n < 32 && 1163 (enum iso_voldesc_type) ISO_DESC_TYPE(volp) != ISO_VD_EOV; n++) { 1164 for (i = 0; i < ISO_ID_STRLEN; i++) 1165 if (ISO_STD_ID(volp)[i] != ISO_ID_STRING[i]) 1166 goto cantfind; 1167 switch (ISO_DESC_TYPE(volp)) { 1168 case ISO_VD_PVD: 1169 /* Standard File Structure */ 1170 if (ISO_STD_VER(volp) != ISO_ID_VER) 1171 goto cantfind; 1172 if (foundpvd != 1) { 1173 fsp->hsfs_vol_type = HS_VOL_TYPE_ISO; 1174 if (error = hs_parseisovol(fsp, volp, hvp)) { 1175 brelse(secbp); 1176 return (error); 1177 } 1178 foundpvd = 1; 1179 for (i = 0; i < ISO_SECTOR_SIZE; i++) 1180 pvd_sum += volp[i]; 1181 } 1182 break; 1183 case ISO_VD_SVD: 1184 /* Supplementary Volume Descriptor */ 1185 if (ISO_STD_VER(volp) == ISO_ID_VER2 && 1186 foundsvd != 1) { 1187 fsp->hsfs_vol_type = HS_VOL_TYPE_ISO; 1188 if (error = hs_parseisovol(fsp, volp, svp)) { 1189 brelse(secbp); 1190 return (error); 1191 } 1192 foundsvd = 1; 1193 } 1194 if (hs_joliet_level(volp) >= 1 && foundjvd != 1) { 1195 fsp->hsfs_vol_type = HS_VOL_TYPE_ISO; 1196 if (error = hs_parseisovol(fsp, volp, jvp)) { 1197 brelse(secbp); 1198 return (error); 1199 } 1200 foundjvd = 1; 1201 } 1202 break; 1203 case ISO_VD_BOOT: 1204 break; 1205 case ISO_VD_VPD: 1206 /* currently cannot handle partition */ 1207 break; 1208 case VD_EOV: 1209 break; 1210 } 1211 brelse(secbp); 1212 ++secno; 1213 secbp = bread(vp->v_rdev, secno * 4, HS_SECTOR_SIZE); 1214 error = geterror(secbp); 1215 1216 if (error != 0) { 1217 cmn_err(CE_NOTE, "hs_findisovol: bread: error=(%d)", 1218 error); 1219 brelse(secbp); 1220 return (error); 1221 } 1222 1223 volp = (uchar_t *)secbp->b_un.b_addr; 1224 } 1225 for (n = 0; n < 16; n++) { 1226 brelse(secbp); 1227 ++secno; 1228 secbp = bread(vp->v_rdev, secno * 4, HS_SECTOR_SIZE); 1229 error = geterror(secbp); 1230 1231 if (error != 0) { 1232 cmn_err(CE_NOTE, "hs_findisovol: bread: error=(%d)", 1233 error); 1234 brelse(secbp); 1235 return (error); 1236 } 1237 1238 /* 1239 * Check for the signature from mkisofs that grants that 1240 * the current filesystem allows to use the extent lbn as 1241 * inode number even in pure ISO9660 mode. 1242 */ 1243 volp = (uchar_t *)secbp->b_un.b_addr; 1244 if (strncmp((char *)volp, "MKI ", 4) == 0) { 1245 int sum; 1246 1247 sum = volp[2045]; 1248 sum *= 256; 1249 sum += volp[2046]; 1250 sum *= 256; 1251 sum += volp[2047]; 1252 if (sum == pvd_sum) 1253 fsp->hsfs_flags |= HSFSMNT_INODE; 1254 break; 1255 } 1256 } 1257 if (foundpvd) { 1258 brelse(secbp); 1259 return (0); 1260 } 1261 cantfind: 1262 brelse(secbp); 1263 return (EINVAL); 1264 } 1265 1266 /* 1267 * Return 0 if no Joliet is found 1268 * else return Joliet Level 1..3 1269 */ 1270 static int 1271 hs_joliet_level(uchar_t *volp) 1272 { 1273 if (ISO_std_ver(volp)[0] == ISO_ID_VER && 1274 ISO_svd_esc(volp)[0] == '%' && 1275 ISO_svd_esc(volp)[1] == '/') { 1276 1277 switch (ISO_svd_esc(volp)[2]) { 1278 1279 case '@': 1280 return (1); 1281 case 'C': 1282 return (2); 1283 case 'E': 1284 return (3); 1285 } 1286 } 1287 return (0); 1288 } 1289 1290 /* 1291 * hs_parseisovol 1292 * 1293 * Parse the Primary Volume Descriptor into an hs_volume structure. 1294 * 1295 */ 1296 static int 1297 hs_parseisovol(struct hsfs *fsp, uchar_t *volp, struct hs_volume *hvp) 1298 { 1299 hvp->vol_size = ISO_VOL_SIZE(volp); 1300 hvp->lbn_size = ISO_BLK_SIZE(volp); 1301 if (hvp->lbn_size == 0) { 1302 cmn_err(CE_NOTE, "hs_parseisovol: logical block size in the " 1303 "PVD is zero"); 1304 return (EINVAL); 1305 } 1306 hvp->lbn_shift = ffs((long)hvp->lbn_size) - 1; 1307 hvp->lbn_secshift = 1308 ffs((long)howmany(ISO_SECTOR_SIZE, (int)hvp->lbn_size)) - 1; 1309 hvp->lbn_maxoffset = hvp->lbn_size - 1; 1310 hs_parse_longdate(ISO_cre_date(volp), &hvp->cre_date); 1311 hs_parse_longdate(ISO_mod_date(volp), &hvp->mod_date); 1312 hvp->file_struct_ver = ISO_FILE_STRUCT_VER(volp); 1313 hvp->ptbl_len = ISO_PTBL_SIZE(volp); 1314 hvp->vol_set_size = (ushort_t)ISO_SET_SIZE(volp); 1315 hvp->vol_set_seq = (ushort_t)ISO_SET_SEQ(volp); 1316 #if defined(_LITTLE_ENDIAN) 1317 hvp->ptbl_lbn = ISO_PTBL_MAN_LS(volp); 1318 #else 1319 hvp->ptbl_lbn = ISO_PTBL_MAN_MS(volp); 1320 #endif 1321 hs_copylabel(hvp, ISO_VOL_ID(volp), hs_joliet_level(volp) >= 1); 1322 1323 /* 1324 * Make sure that lbn_size is a power of two and otherwise valid. 1325 */ 1326 if (hvp->lbn_size & ~(1 << hvp->lbn_shift)) { 1327 cmn_err(CE_NOTE, 1328 "hsfs: %d-byte logical block size not supported", 1329 hvp->lbn_size); 1330 return (EINVAL); 1331 } 1332 return (hs_parsedir(fsp, ISO_ROOT_DIR(volp), &hvp->root_dir, 1333 (char *)NULL, (int *)NULL, IDE_ROOT_DIR_REC_SIZE)); 1334 } 1335 1336 /* 1337 * Common code for mount and umount. 1338 * Check that the user's argument is a reasonable 1339 * thing on which to mount, and return the device number if so. 1340 */ 1341 static int 1342 hs_getmdev(struct vfs *vfsp, char *fspec, int flags, dev_t *pdev, mode_t *mode, 1343 cred_t *cr) 1344 { 1345 int error; 1346 struct vnode *vp; 1347 struct vattr vap; 1348 dev_t dev; 1349 1350 /* 1351 * Get the device to be mounted 1352 */ 1353 error = lookupname(fspec, (flags & MS_SYSSPACE) ? 1354 UIO_SYSSPACE : UIO_USERSPACE, FOLLOW, NULLVPP, &vp); 1355 if (error) { 1356 if (error == ENOENT) { 1357 return (ENODEV); /* needs translation */ 1358 } 1359 return (error); 1360 } 1361 if (vp->v_type != VBLK) { 1362 VN_RELE(vp); 1363 return (ENOTBLK); 1364 } 1365 /* 1366 * Can we read from the device? 1367 */ 1368 if ((error = VOP_ACCESS(vp, VREAD, 0, cr)) != 0 || 1369 (error = secpolicy_spec_open(cr, vp, FREAD)) != 0) { 1370 VN_RELE(vp); 1371 return (error); 1372 } 1373 1374 vap.va_mask = AT_MODE; /* get protection mode */ 1375 (void) VOP_GETATTR(vp, &vap, 0, CRED()); 1376 *mode = vap.va_mode; 1377 1378 dev = *pdev = vp->v_rdev; 1379 VN_RELE(vp); 1380 1381 /* 1382 * Ensure that this device isn't already mounted, 1383 * unless this is a REMOUNT request or we are told to suppress 1384 * mount checks. 1385 */ 1386 if ((flags & MS_NOCHECK) == 0) { 1387 if (vfs_devmounting(dev, vfsp)) 1388 return (EBUSY); 1389 if (vfs_devismounted(dev) && !(flags & MS_REMOUNT)) 1390 return (EBUSY); 1391 } 1392 1393 if (getmajor(*pdev) >= devcnt) 1394 return (ENXIO); 1395 return (0); 1396 } 1397 1398 static void 1399 hs_copylabel(struct hs_volume *hvp, unsigned char *label, int isjoliet) 1400 { 1401 char lbuf[64]; /* hs_joliet_cp() creates 48 bytes at most */ 1402 1403 if (isjoliet) { 1404 /* 1405 * hs_joliet_cp() will output 16..48 bytes. 1406 * We need to clear 'lbuf' to avoid junk chars past byte 15. 1407 */ 1408 bzero(lbuf, sizeof (lbuf)); 1409 (void) hs_joliet_cp((char *)label, lbuf, 32); 1410 label = (unsigned char *)lbuf; 1411 } 1412 /* cdrom volid is at most 32 bytes */ 1413 bcopy(label, hvp->vol_id, 32); 1414 hvp->vol_id[31] = NULL; 1415 } 1416 1417 /* 1418 * Mount root file system. 1419 * "why" is ROOT_INIT on initial call, ROOT_REMOUNT if called to 1420 * remount the root file system, and ROOT_UNMOUNT if called to 1421 * unmount the root (e.g., as part of a system shutdown). 1422 * 1423 * XXX - this may be partially machine-dependent; it, along with the VFS_SWAPVP 1424 * operation, goes along with auto-configuration. A mechanism should be 1425 * provided by which machine-INdependent code in the kernel can say "get me the 1426 * right root file system" and "get me the right initial swap area", and have 1427 * that done in what may well be a machine-dependent fashion. 1428 * Unfortunately, it is also file-system-type dependent (NFS gets it via 1429 * bootparams calls, UFS gets it from various and sundry machine-dependent 1430 * mechanisms, as SPECFS does for swap). 1431 */ 1432 static int 1433 hsfs_mountroot(struct vfs *vfsp, enum whymountroot why) 1434 { 1435 int error; 1436 struct hsfs *fsp; 1437 struct hs_volume *fvolp; 1438 static int hsfsrootdone = 0; 1439 dev_t rootdev; 1440 mode_t mode = 0; 1441 1442 if (why == ROOT_INIT) { 1443 if (hsfsrootdone++) 1444 return (EBUSY); 1445 rootdev = getrootdev(); 1446 if (rootdev == (dev_t)NODEV) 1447 return (ENODEV); 1448 vfsp->vfs_dev = rootdev; 1449 vfsp->vfs_flag |= VFS_RDONLY; 1450 } else if (why == ROOT_REMOUNT) { 1451 cmn_err(CE_NOTE, "hsfs_mountroot: ROOT_REMOUNT"); 1452 return (0); 1453 } else if (why == ROOT_UNMOUNT) { 1454 return (0); 1455 } 1456 error = vfs_lock(vfsp); 1457 if (error) { 1458 cmn_err(CE_NOTE, "hsfs_mountroot: couldn't get vfs_lock"); 1459 return (error); 1460 } 1461 1462 error = hs_mountfs(vfsp, rootdev, "/", mode, 1, CRED(), 1); 1463 /* 1464 * XXX - assumes root device is not indirect, because we don't set 1465 * rootvp. Is rootvp used for anything? If so, make another arg 1466 * to mountfs. 1467 */ 1468 if (error) { 1469 vfs_unlock(vfsp); 1470 if (rootvp) { 1471 VN_RELE(rootvp); 1472 rootvp = (struct vnode *)0; 1473 } 1474 return (error); 1475 } 1476 if (why == ROOT_INIT) 1477 vfs_add((struct vnode *)0, vfsp, 1478 (vfsp->vfs_flag & VFS_RDONLY) ? MS_RDONLY : 0); 1479 vfs_unlock(vfsp); 1480 fsp = VFS_TO_HSFS(vfsp); 1481 fvolp = &fsp->hsfs_vol; 1482 #ifdef HSFS_CLKSET 1483 if (fvolp->cre_date.tv_sec == 0) { 1484 cmn_err(CE_NOTE, "hsfs_mountroot: cre_date.tv_sec == 0"); 1485 if (fvolp->mod_date.tv_sec == 0) { 1486 cmn_err(CE_NOTE, 1487 "hsfs_mountroot: mod_date.tv_sec == 0"); 1488 cmn_err(CE_NOTE, "hsfs_mountroot: clkset(-1L)"); 1489 clkset(-1L); 1490 } else { 1491 clkset(fvolp->mod_date.tv_sec); 1492 } 1493 } else { 1494 clkset(fvolp->mod_date.tv_sec); 1495 } 1496 #else /* HSFS_CLKSET */ 1497 clkset(-1L); 1498 #endif /* HSFS_CLKSET */ 1499 return (0); 1500 } 1501 1502 /* 1503 * hs_findvoldesc() 1504 * 1505 * Return the sector where the volume descriptor lives. This is 1506 * a fixed value for "normal" cd-rom's, but can change for 1507 * multisession cd's. 1508 * 1509 * desc_sec is the same for high-sierra and iso 9660 formats, why 1510 * there are two differnt #defines used in the code for this is 1511 * beyond me. These are standards, cast in concrete, right? 1512 * To be general, however, this function supports passing in different 1513 * values. 1514 */ 1515 static int 1516 hs_findvoldesc(dev_t rdev, int desc_sec) 1517 { 1518 int secno; 1519 int error; 1520 int rval; /* ignored */ 1521 1522 #ifdef CDROMREADOFFSET 1523 /* 1524 * Issue the Read Offset ioctl directly to the 1525 * device. Ignore any errors and set starting 1526 * secno to the default, otherwise add the 1527 * VOLDESC sector number to the offset. 1528 */ 1529 error = cdev_ioctl(rdev, CDROMREADOFFSET, (intptr_t)&secno, 1530 FNATIVE|FKIOCTL|FREAD, CRED(), &rval); 1531 if (error) { 1532 secno = desc_sec; 1533 } else { 1534 secno += desc_sec; 1535 } 1536 #else 1537 secno = desc_sec; 1538 #endif 1539 1540 return (secno); 1541 } 1542