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 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 * Copyright (c) 2011 Bayard G. Bell. All rights reserved. 25 */ 26 27 #include <sys/types.h> 28 #include <sys/t_lock.h> 29 #include <sys/param.h> 30 #include <sys/time.h> 31 #include <sys/systm.h> 32 #include <sys/sysmacros.h> 33 #include <sys/resource.h> 34 #include <sys/signal.h> 35 #include <sys/cred.h> 36 #include <sys/user.h> 37 #include <sys/buf.h> 38 #include <sys/vfs.h> 39 #include <sys/vfs_opreg.h> 40 #include <sys/stat.h> 41 #include <sys/vnode.h> 42 #include <sys/mode.h> 43 #include <sys/proc.h> 44 #include <sys/disp.h> 45 #include <sys/file.h> 46 #include <sys/fcntl.h> 47 #include <sys/flock.h> 48 #include <sys/kmem.h> 49 #include <sys/uio.h> 50 #include <sys/dnlc.h> 51 #include <sys/conf.h> 52 #include <sys/errno.h> 53 #include <sys/mman.h> 54 #include <sys/fbuf.h> 55 #include <sys/pathname.h> 56 #include <sys/debug.h> 57 #include <sys/vmsystm.h> 58 #include <sys/cmn_err.h> 59 #include <sys/dirent.h> 60 #include <sys/errno.h> 61 #include <sys/modctl.h> 62 #include <sys/statvfs.h> 63 #include <sys/mount.h> 64 #include <sys/sunddi.h> 65 #include <sys/bootconf.h> 66 #include <sys/policy.h> 67 68 #include <vm/hat.h> 69 #include <vm/page.h> 70 #include <vm/pvn.h> 71 #include <vm/as.h> 72 #include <vm/seg.h> 73 #include <vm/seg_map.h> 74 #include <vm/seg_kmem.h> 75 #include <vm/seg_vn.h> 76 #include <vm/rm.h> 77 #include <vm/page.h> 78 #include <sys/swap.h> 79 #include <sys/mntent.h> 80 81 82 #include <fs/fs_subr.h> 83 84 85 #include <sys/fs/udf_volume.h> 86 #include <sys/fs/udf_inode.h> 87 88 89 extern struct vnode *common_specvp(struct vnode *vp); 90 91 extern kmutex_t ud_sync_busy; 92 static int32_t ud_mountfs(struct vfs *, 93 enum whymountroot, dev_t, char *, struct cred *, int32_t); 94 static struct udf_vfs *ud_validate_and_fill_superblock(dev_t, 95 int32_t, uint32_t); 96 void ud_destroy_fsp(struct udf_vfs *); 97 void ud_convert_to_superblock(struct udf_vfs *, 98 struct log_vol_int_desc *); 99 void ud_update_superblock(struct vfs *); 100 int32_t ud_get_last_block(dev_t, daddr_t *); 101 static int32_t ud_val_get_vat(struct udf_vfs *, 102 dev_t, daddr_t, struct ud_map *); 103 int32_t ud_read_sparing_tbls(struct udf_vfs *, 104 dev_t, struct ud_map *, struct pmap_typ2 *); 105 uint32_t ud_get_lbsize(dev_t, uint32_t *); 106 107 static int32_t udf_mount(struct vfs *, 108 struct vnode *, struct mounta *, struct cred *); 109 static int32_t udf_unmount(struct vfs *, int, struct cred *); 110 static int32_t udf_root(struct vfs *, struct vnode **); 111 static int32_t udf_statvfs(struct vfs *, struct statvfs64 *); 112 static int32_t udf_sync(struct vfs *, int16_t, struct cred *); 113 static int32_t udf_vget(struct vfs *, struct vnode **, struct fid *); 114 static int32_t udf_mountroot(struct vfs *vfsp, enum whymountroot); 115 116 static int udfinit(int, char *); 117 118 static mntopts_t udfs_mntopts; 119 120 static vfsdef_t vfw = { 121 VFSDEF_VERSION, 122 "udfs", 123 udfinit, 124 VSW_HASPROTO|VSW_CANREMOUNT|VSW_STATS|VSW_CANLOFI, 125 &udfs_mntopts 126 }; 127 128 static mntopts_t udfs_mntopts = { 129 0, 130 NULL 131 }; 132 133 /* 134 * Module linkage information for the kernel. 135 */ 136 extern struct mod_ops mod_fsops; 137 138 static struct modlfs modlfs = { 139 &mod_fsops, "filesystem for UDFS", &vfw 140 }; 141 142 static struct modlinkage modlinkage = { 143 MODREV_1, (void *)&modlfs, NULL 144 }; 145 146 int32_t udf_fstype = -1; 147 148 int 149 _init() 150 { 151 return (mod_install(&modlinkage)); 152 } 153 154 int 155 _fini() 156 { 157 return (EBUSY); 158 } 159 160 int 161 _info(struct modinfo *modinfop) 162 { 163 return (mod_info(&modlinkage, modinfop)); 164 } 165 166 167 /* -------------------- vfs routines -------------------- */ 168 169 /* 170 * XXX - this appears only to be used by the VM code to handle the case where 171 * UNIX is running off the mini-root. That probably wants to be done 172 * differently. 173 */ 174 struct vnode *rootvp; 175 176 static int32_t 177 udf_mount(struct vfs *vfsp, struct vnode *mvp, 178 struct mounta *uap, struct cred *cr) 179 { 180 dev_t dev; 181 struct vnode *lvp = NULL; 182 struct vnode *svp = NULL; 183 struct pathname dpn; 184 int32_t error; 185 enum whymountroot why; 186 int oflag, aflag; 187 188 ud_printf("udf_mount\n"); 189 190 if ((error = secpolicy_fs_mount(cr, mvp, vfsp)) != 0) { 191 return (error); 192 } 193 194 if (mvp->v_type != VDIR) { 195 return (ENOTDIR); 196 } 197 198 mutex_enter(&mvp->v_lock); 199 if ((uap->flags & MS_REMOUNT) == 0 && 200 (uap->flags & MS_OVERLAY) == 0 && 201 (mvp->v_count != 1 || (mvp->v_flag & VROOT))) { 202 mutex_exit(&mvp->v_lock); 203 return (EBUSY); 204 } 205 mutex_exit(&mvp->v_lock); 206 207 if (error = pn_get(uap->dir, UIO_USERSPACE, &dpn)) { 208 return (error); 209 } 210 211 /* 212 * Resolve path name of the file being mounted. 213 */ 214 if (error = lookupname(uap->spec, UIO_USERSPACE, FOLLOW, NULLVPP, 215 &svp)) { 216 pn_free(&dpn); 217 return (error); 218 } 219 220 error = vfs_get_lofi(vfsp, &lvp); 221 222 if (error > 0) { 223 if (error == ENOENT) 224 error = ENODEV; 225 goto out; 226 } else if (error == 0) { 227 dev = lvp->v_rdev; 228 } else { 229 dev = svp->v_rdev; 230 231 if (svp->v_type != VBLK) { 232 error = ENOTBLK; 233 goto out; 234 } 235 } 236 237 /* 238 * Ensure that this device isn't already mounted, 239 * unless this is a REMOUNT request 240 */ 241 if (vfs_devmounting(dev, vfsp)) { 242 error = EBUSY; 243 goto out; 244 } 245 if (vfs_devismounted(dev)) { 246 if (uap->flags & MS_REMOUNT) { 247 why = ROOT_REMOUNT; 248 } else { 249 error = EBUSY; 250 goto out; 251 } 252 } else { 253 why = ROOT_INIT; 254 } 255 if (getmajor(dev) >= devcnt) { 256 error = ENXIO; 257 goto out; 258 } 259 260 /* 261 * If the device is a tape, mount it read only 262 */ 263 if (devopsp[getmajor(dev)]->devo_cb_ops->cb_flag & D_TAPE) { 264 vfsp->vfs_flag |= VFS_RDONLY; 265 } 266 267 if (uap->flags & MS_RDONLY) { 268 vfsp->vfs_flag |= VFS_RDONLY; 269 } 270 271 /* 272 * Set mount options. 273 */ 274 if (uap->flags & MS_RDONLY) { 275 vfs_setmntopt(vfsp, MNTOPT_RO, NULL, 0); 276 } 277 if (uap->flags & MS_NOSUID) { 278 vfs_setmntopt(vfsp, MNTOPT_NOSUID, NULL, 0); 279 } 280 281 /* 282 * Verify that the caller can open the device special file as 283 * required. It is not until this moment that we know whether 284 * we're mounting "ro" or not. 285 */ 286 if ((vfsp->vfs_flag & VFS_RDONLY) != 0) { 287 oflag = FREAD; 288 aflag = VREAD; 289 } else { 290 oflag = FREAD | FWRITE; 291 aflag = VREAD | VWRITE; 292 } 293 294 if (lvp == NULL && 295 (error = secpolicy_spec_open(cr, svp, oflag)) != 0) 296 goto out; 297 298 if ((error = VOP_ACCESS(svp, aflag, 0, cr, NULL)) != 0) 299 goto out; 300 301 /* 302 * Mount the filesystem. 303 */ 304 error = ud_mountfs(vfsp, why, dev, dpn.pn_path, cr, 0); 305 out: 306 VN_RELE(svp); 307 if (lvp != NULL) 308 VN_RELE(lvp); 309 pn_free(&dpn); 310 return (error); 311 } 312 313 314 315 /* 316 * unmount the file system pointed 317 * by vfsp 318 */ 319 /* ARGSUSED */ 320 static int32_t 321 udf_unmount(struct vfs *vfsp, int fflag, struct cred *cr) 322 { 323 struct udf_vfs *udf_vfsp; 324 struct vnode *bvp, *rvp; 325 struct ud_inode *rip; 326 int32_t flag; 327 328 ud_printf("udf_unmount\n"); 329 330 if (secpolicy_fs_unmount(cr, vfsp) != 0) { 331 return (EPERM); 332 } 333 334 /* 335 * forced unmount is not supported by this file system 336 * and thus, ENOTSUP, is being returned. 337 */ 338 if (fflag & MS_FORCE) 339 return (ENOTSUP); 340 341 udf_vfsp = (struct udf_vfs *)vfsp->vfs_data; 342 flag = !(udf_vfsp->udf_flags & UDF_FL_RDONLY); 343 bvp = udf_vfsp->udf_devvp; 344 345 rvp = udf_vfsp->udf_root; 346 ASSERT(rvp != NULL); 347 rip = VTOI(rvp); 348 349 (void) ud_release_cache(udf_vfsp); 350 351 352 /* Flush all inodes except root */ 353 if (ud_iflush(vfsp) < 0) { 354 return (EBUSY); 355 } 356 357 rw_enter(&rip->i_contents, RW_WRITER); 358 (void) ud_syncip(rip, B_INVAL, I_SYNC); 359 rw_exit(&rip->i_contents); 360 361 mutex_enter(&ud_sync_busy); 362 if ((udf_vfsp->udf_flags & UDF_FL_RDONLY) == 0) { 363 bflush(vfsp->vfs_dev); 364 mutex_enter(&udf_vfsp->udf_lock); 365 udf_vfsp->udf_clean = UDF_CLEAN; 366 mutex_exit(&udf_vfsp->udf_lock); 367 ud_update_superblock(vfsp); 368 } 369 mutex_exit(&ud_sync_busy); 370 371 mutex_destroy(&udf_vfsp->udf_lock); 372 mutex_destroy(&udf_vfsp->udf_rename_lck); 373 374 ud_delcache(rip); 375 ITIMES(rip); 376 VN_RELE(rvp); 377 378 ud_destroy_fsp(udf_vfsp); 379 380 (void) VOP_PUTPAGE(bvp, (offset_t)0, (uint32_t)0, B_INVAL, cr, NULL); 381 (void) VOP_CLOSE(bvp, flag, 1, (offset_t)0, cr, NULL); 382 383 (void) bfinval(vfsp->vfs_dev, 1); 384 VN_RELE(bvp); 385 386 387 return (0); 388 } 389 390 391 /* 392 * Get the root vp for the 393 * file system 394 */ 395 static int32_t 396 udf_root(struct vfs *vfsp, struct vnode **vpp) 397 { 398 struct udf_vfs *udf_vfsp; 399 struct vnode *vp; 400 401 ud_printf("udf_root\n"); 402 403 udf_vfsp = (struct udf_vfs *)vfsp->vfs_data; 404 405 ASSERT(udf_vfsp != NULL); 406 ASSERT(udf_vfsp->udf_root != NULL); 407 408 vp = udf_vfsp->udf_root; 409 VN_HOLD(vp); 410 *vpp = vp; 411 return (0); 412 } 413 414 415 /* 416 * Get file system statistics. 417 */ 418 static int32_t 419 udf_statvfs(struct vfs *vfsp, struct statvfs64 *sp) 420 { 421 struct udf_vfs *udf_vfsp; 422 struct ud_part *parts; 423 dev32_t d32; 424 int32_t index; 425 426 ud_printf("udf_statvfs\n"); 427 428 udf_vfsp = (struct udf_vfs *)vfsp->vfs_data; 429 (void) bzero(sp, sizeof (struct statvfs64)); 430 431 mutex_enter(&udf_vfsp->udf_lock); 432 sp->f_bsize = udf_vfsp->udf_lbsize; 433 sp->f_frsize = udf_vfsp->udf_lbsize; 434 sp->f_blocks = 0; 435 sp->f_bfree = 0; 436 parts = udf_vfsp->udf_parts; 437 for (index = 0; index < udf_vfsp->udf_npart; index++) { 438 sp->f_blocks += parts->udp_nblocks; 439 sp->f_bfree += parts->udp_nfree; 440 parts++; 441 } 442 sp->f_bavail = sp->f_bfree; 443 444 /* 445 * Since there are no real inodes allocated 446 * we will approximate 447 * each new file will occupy : 448 * 38(over head each dent) + MAXNAMLEN / 2 + inode_size(==block size) 449 */ 450 sp->f_ffree = sp->f_favail = 451 (sp->f_bavail * sp->f_bsize) / (146 + sp->f_bsize); 452 453 /* 454 * The total number of inodes is 455 * the sum of files + directories + free inodes 456 */ 457 sp->f_files = sp->f_ffree + udf_vfsp->udf_nfiles + udf_vfsp->udf_ndirs; 458 (void) cmpldev(&d32, vfsp->vfs_dev); 459 sp->f_fsid = d32; 460 (void) strcpy(sp->f_basetype, vfssw[vfsp->vfs_fstype].vsw_name); 461 sp->f_flag = vf_to_stf(vfsp->vfs_flag); 462 sp->f_namemax = MAXNAMLEN; 463 (void) strcpy(sp->f_fstr, udf_vfsp->udf_volid); 464 465 mutex_exit(&udf_vfsp->udf_lock); 466 467 return (0); 468 } 469 470 471 /* 472 * Flush any pending I/O to file system vfsp. 473 * The ud_update() routine will only flush *all* udf files. 474 */ 475 /*ARGSUSED*/ 476 /* ARGSUSED */ 477 static int32_t 478 udf_sync(struct vfs *vfsp, int16_t flag, struct cred *cr) 479 { 480 ud_printf("udf_sync\n"); 481 482 ud_update(flag); 483 return (0); 484 } 485 486 487 488 /* ARGSUSED */ 489 static int32_t 490 udf_vget(struct vfs *vfsp, 491 struct vnode **vpp, struct fid *fidp) 492 { 493 int32_t error = 0; 494 struct udf_fid *udfid; 495 struct udf_vfs *udf_vfsp; 496 struct ud_inode *ip; 497 498 ud_printf("udf_vget\n"); 499 500 udf_vfsp = (struct udf_vfs *)vfsp->vfs_data; 501 if (udf_vfsp == NULL) { 502 *vpp = NULL; 503 return (0); 504 } 505 506 udfid = (struct udf_fid *)fidp; 507 if ((error = ud_iget(vfsp, udfid->udfid_prn, 508 udfid->udfid_icb_lbn, &ip, NULL, CRED())) != 0) { 509 *vpp = NULL; 510 return (error); 511 } 512 513 rw_enter(&ip->i_contents, RW_READER); 514 if ((udfid->udfid_uinq_lo != (ip->i_uniqid & 0xffffffff)) || 515 (udfid->udfid_prn != ip->i_icb_prn)) { 516 rw_exit(&ip->i_contents); 517 VN_RELE(ITOV(ip)); 518 *vpp = NULL; 519 return (EINVAL); 520 } 521 rw_exit(&ip->i_contents); 522 523 *vpp = ITOV(ip); 524 return (0); 525 } 526 527 528 /* 529 * Mount root file system. 530 * "why" is ROOT_INIT on initial call, ROOT_REMOUNT if called to 531 * remount the root file system, and ROOT_UNMOUNT if called to 532 * unmount the root (e.g., as part of a system shutdown). 533 * 534 * XXX - this may be partially machine-dependent; it, along with the VFS_SWAPVP 535 * operation, goes along with auto-configuration. A mechanism should be 536 * provided by which machine-INdependent code in the kernel can say "get me the 537 * right root file system" and "get me the right initial swap area", and have 538 * that done in what may well be a machine-dependent fashion. 539 * Unfortunately, it is also file-system-type dependent (NFS gets it via 540 * bootparams calls, UFS gets it from various and sundry machine-dependent 541 * mechanisms, as SPECFS does for swap). 542 */ 543 /* ARGSUSED */ 544 static int32_t 545 udf_mountroot(struct vfs *vfsp, enum whymountroot why) 546 { 547 dev_t rootdev; 548 static int32_t udf_rootdone = 0; 549 struct vnode *vp = NULL; 550 int32_t ovflags, error; 551 ud_printf("udf_mountroot\n"); 552 553 if (why == ROOT_INIT) { 554 if (udf_rootdone++) { 555 return (EBUSY); 556 } 557 rootdev = getrootdev(); 558 if (rootdev == (dev_t)NODEV) { 559 return (ENODEV); 560 } 561 vfsp->vfs_dev = rootdev; 562 vfsp->vfs_flag |= VFS_RDONLY; 563 } else if (why == ROOT_REMOUNT) { 564 vp = ((struct udf_vfs *)vfsp->vfs_data)->udf_devvp; 565 (void) dnlc_purge_vfsp(vfsp, 0); 566 vp = common_specvp(vp); 567 (void) VOP_PUTPAGE(vp, (offset_t)0, 568 (uint32_t)0, B_INVAL, CRED(), NULL); 569 binval(vfsp->vfs_dev); 570 571 ovflags = vfsp->vfs_flag; 572 vfsp->vfs_flag &= ~VFS_RDONLY; 573 vfsp->vfs_flag |= VFS_REMOUNT; 574 rootdev = vfsp->vfs_dev; 575 } else if (why == ROOT_UNMOUNT) { 576 ud_update(0); 577 vp = ((struct udf_vfs *)vfsp->vfs_data)->udf_devvp; 578 (void) VOP_CLOSE(vp, FREAD|FWRITE, 1, 579 (offset_t)0, CRED(), NULL); 580 return (0); 581 } 582 583 if ((error = vfs_lock(vfsp)) != 0) { 584 return (error); 585 } 586 587 error = ud_mountfs(vfsp, why, rootdev, "/", CRED(), 1); 588 if (error) { 589 vfs_unlock(vfsp); 590 if (why == ROOT_REMOUNT) { 591 vfsp->vfs_flag = ovflags; 592 } 593 if (rootvp) { 594 VN_RELE(rootvp); 595 rootvp = (struct vnode *)0; 596 } 597 return (error); 598 } 599 600 if (why == ROOT_INIT) { 601 vfs_add((struct vnode *)0, vfsp, 602 (vfsp->vfs_flag & VFS_RDONLY) ? MS_RDONLY : 0); 603 } 604 vfs_unlock(vfsp); 605 return (0); 606 } 607 608 609 /* ------------------------- local routines ------------------------- */ 610 611 612 static int32_t 613 ud_mountfs(struct vfs *vfsp, 614 enum whymountroot why, dev_t dev, char *name, 615 struct cred *cr, int32_t isroot) 616 { 617 struct vnode *devvp = NULL; 618 int32_t error = 0; 619 int32_t needclose = 0; 620 struct udf_vfs *udf_vfsp = NULL; 621 struct log_vol_int_desc *lvid; 622 struct ud_inode *rip = NULL; 623 struct vnode *rvp = NULL; 624 int32_t i, lbsize; 625 uint32_t avd_loc; 626 struct ud_map *map; 627 int32_t desc_len; 628 629 ud_printf("ud_mountfs\n"); 630 631 if (why == ROOT_INIT) { 632 /* 633 * Open the device. 634 */ 635 devvp = makespecvp(dev, VBLK); 636 637 /* 638 * Open block device mounted on. 639 * When bio is fixed for vnodes this can all be vnode 640 * operations. 641 */ 642 error = VOP_OPEN(&devvp, 643 (vfsp->vfs_flag & VFS_RDONLY) ? FREAD : FREAD|FWRITE, 644 cr, NULL); 645 if (error) { 646 goto out; 647 } 648 needclose = 1; 649 650 /* 651 * Refuse to go any further if this 652 * device is being used for swapping. 653 */ 654 if (IS_SWAPVP(devvp)) { 655 error = EBUSY; 656 goto out; 657 } 658 } 659 660 /* 661 * check for dev already mounted on 662 */ 663 if (vfsp->vfs_flag & VFS_REMOUNT) { 664 struct tag *ttag; 665 int32_t index, count; 666 struct buf *tpt = 0; 667 caddr_t addr; 668 669 670 /* cannot remount to RDONLY */ 671 if (vfsp->vfs_flag & VFS_RDONLY) { 672 return (EINVAL); 673 } 674 675 if (vfsp->vfs_dev != dev) { 676 return (EINVAL); 677 } 678 679 udf_vfsp = (struct udf_vfs *)vfsp->vfs_data; 680 devvp = udf_vfsp->udf_devvp; 681 682 /* 683 * fsck may have altered the file system; discard 684 * as much incore data as possible. Don't flush 685 * if this is a rw to rw remount; it's just resetting 686 * the options. 687 */ 688 if (udf_vfsp->udf_flags & UDF_FL_RDONLY) { 689 (void) dnlc_purge_vfsp(vfsp, 0); 690 (void) VOP_PUTPAGE(devvp, (offset_t)0, (uint_t)0, 691 B_INVAL, CRED(), NULL); 692 (void) ud_iflush(vfsp); 693 bflush(dev); 694 binval(dev); 695 } 696 697 /* 698 * We could read UDF1.50 and write UDF1.50 only 699 * disallow mount of any highier version 700 */ 701 if ((udf_vfsp->udf_miread > UDF_150) || 702 (udf_vfsp->udf_miwrite > UDF_150)) { 703 error = EINVAL; 704 goto remountout; 705 } 706 707 /* 708 * read/write to read/write; all done 709 */ 710 if (udf_vfsp->udf_flags & UDF_FL_RW) { 711 goto remountout; 712 } 713 714 /* 715 * Does the media type allow a writable mount 716 */ 717 if (udf_vfsp->udf_mtype != UDF_MT_OW) { 718 error = EINVAL; 719 goto remountout; 720 } 721 722 /* 723 * Read the metadata 724 * and check if it is possible to 725 * mount in rw mode 726 */ 727 tpt = ud_bread(vfsp->vfs_dev, 728 udf_vfsp->udf_iseq_loc << udf_vfsp->udf_l2d_shift, 729 udf_vfsp->udf_iseq_len); 730 if (tpt->b_flags & B_ERROR) { 731 error = EIO; 732 goto remountout; 733 } 734 count = udf_vfsp->udf_iseq_len / DEV_BSIZE; 735 addr = tpt->b_un.b_addr; 736 for (index = 0; index < count; index ++) { 737 ttag = (struct tag *)(addr + index * DEV_BSIZE); 738 desc_len = udf_vfsp->udf_iseq_len - (index * DEV_BSIZE); 739 if (ud_verify_tag_and_desc(ttag, UD_LOG_VOL_INT, 740 udf_vfsp->udf_iseq_loc + 741 (index >> udf_vfsp->udf_l2d_shift), 742 1, desc_len) == 0) { 743 struct log_vol_int_desc *lvid; 744 745 lvid = (struct log_vol_int_desc *)ttag; 746 747 if (SWAP_32(lvid->lvid_int_type) != 748 LOG_VOL_CLOSE_INT) { 749 error = EINVAL; 750 goto remountout; 751 } 752 753 /* 754 * Copy new data to old data 755 */ 756 bcopy(udf_vfsp->udf_iseq->b_un.b_addr, 757 tpt->b_un.b_addr, udf_vfsp->udf_iseq_len); 758 break; 759 } 760 } 761 762 udf_vfsp->udf_flags = UDF_FL_RW; 763 764 mutex_enter(&udf_vfsp->udf_lock); 765 ud_sbwrite(udf_vfsp); 766 mutex_exit(&udf_vfsp->udf_lock); 767 remountout: 768 if (tpt != NULL) { 769 tpt->b_flags = B_AGE | B_STALE; 770 brelse(tpt); 771 } 772 return (error); 773 } 774 775 ASSERT(devvp != 0); 776 /* 777 * Flush back any dirty pages on the block device to 778 * try and keep the buffer cache in sync with the page 779 * cache if someone is trying to use block devices when 780 * they really should be using the raw device. 781 */ 782 (void) VOP_PUTPAGE(common_specvp(devvp), (offset_t)0, 783 (uint32_t)0, B_INVAL, cr, NULL); 784 785 786 /* 787 * Check if the file system 788 * is a valid udfs and fill 789 * the required fields in udf_vfs 790 */ 791 if ((lbsize = ud_get_lbsize(dev, &avd_loc)) == 0) { 792 error = EINVAL; 793 goto out; 794 } 795 796 udf_vfsp = ud_validate_and_fill_superblock(dev, lbsize, avd_loc); 797 if (udf_vfsp == NULL) { 798 error = EINVAL; 799 goto out; 800 } 801 802 /* 803 * Fill in vfs private data 804 */ 805 vfsp->vfs_fstype = udf_fstype; 806 vfs_make_fsid(&vfsp->vfs_fsid, dev, udf_fstype); 807 vfsp->vfs_data = (caddr_t)udf_vfsp; 808 vfsp->vfs_dev = dev; 809 vfsp->vfs_flag |= VFS_NOTRUNC; 810 udf_vfsp->udf_devvp = devvp; 811 812 udf_vfsp->udf_fsmnt = kmem_zalloc(strlen(name) + 1, KM_SLEEP); 813 (void) strcpy(udf_vfsp->udf_fsmnt, name); 814 815 udf_vfsp->udf_vfs = vfsp; 816 udf_vfsp->udf_rdclustsz = udf_vfsp->udf_wrclustsz = maxphys; 817 818 udf_vfsp->udf_mod = 0; 819 820 821 lvid = udf_vfsp->udf_lvid; 822 if (vfsp->vfs_flag & VFS_RDONLY) { 823 /* 824 * We could read only UDF1.50 825 * disallow mount of any highier version 826 */ 827 if (udf_vfsp->udf_miread > UDF_150) { 828 error = EINVAL; 829 goto out; 830 } 831 udf_vfsp->udf_flags = UDF_FL_RDONLY; 832 if (SWAP_32(lvid->lvid_int_type) == LOG_VOL_CLOSE_INT) { 833 udf_vfsp->udf_clean = UDF_CLEAN; 834 } else { 835 /* Do we have a VAT at the end of the recorded media */ 836 map = udf_vfsp->udf_maps; 837 for (i = 0; i < udf_vfsp->udf_nmaps; i++) { 838 if (map->udm_flags & UDM_MAP_VPM) { 839 break; 840 } 841 map++; 842 } 843 if (i == udf_vfsp->udf_nmaps) { 844 error = ENOSPC; 845 goto out; 846 } 847 udf_vfsp->udf_clean = UDF_CLEAN; 848 } 849 } else { 850 /* 851 * We could read UDF1.50 and write UDF1.50 only 852 * disallow mount of any highier version 853 */ 854 if ((udf_vfsp->udf_miread > UDF_150) || 855 (udf_vfsp->udf_miwrite > UDF_150)) { 856 error = EINVAL; 857 goto out; 858 } 859 /* 860 * Check if the media allows 861 * us to mount read/write 862 */ 863 if (udf_vfsp->udf_mtype != UDF_MT_OW) { 864 error = EACCES; 865 goto out; 866 } 867 868 /* 869 * Check if we have VAT on a writable media 870 * we cannot use the media in presence of VAT 871 * Dent RW mount. 872 */ 873 map = udf_vfsp->udf_maps; 874 ASSERT(map != NULL); 875 for (i = 0; i < udf_vfsp->udf_nmaps; i++) { 876 if (map->udm_flags & UDM_MAP_VPM) { 877 error = EACCES; 878 goto out; 879 } 880 map++; 881 } 882 883 /* 884 * Check if the domain Id allows 885 * us to write 886 */ 887 if (udf_vfsp->udf_lvd->lvd_dom_id.reg_ids[2] & 0x3) { 888 error = EACCES; 889 goto out; 890 } 891 udf_vfsp->udf_flags = UDF_FL_RW; 892 893 if (SWAP_32(lvid->lvid_int_type) == LOG_VOL_CLOSE_INT) { 894 udf_vfsp->udf_clean = UDF_CLEAN; 895 } else { 896 if (isroot) { 897 udf_vfsp->udf_clean = UDF_DIRTY; 898 } else { 899 error = ENOSPC; 900 goto out; 901 } 902 } 903 } 904 905 mutex_init(&udf_vfsp->udf_lock, NULL, MUTEX_DEFAULT, NULL); 906 907 mutex_init(&udf_vfsp->udf_rename_lck, NULL, MUTEX_DEFAULT, NULL); 908 909 if (error = ud_iget(vfsp, udf_vfsp->udf_ricb_prn, 910 udf_vfsp->udf_ricb_loc, &rip, NULL, cr)) { 911 mutex_destroy(&udf_vfsp->udf_lock); 912 goto out; 913 } 914 915 916 /* 917 * Get the root inode and 918 * initialize the root vnode 919 */ 920 rvp = ITOV(rip); 921 mutex_enter(&rvp->v_lock); 922 rvp->v_flag |= VROOT; 923 mutex_exit(&rvp->v_lock); 924 udf_vfsp->udf_root = rvp; 925 926 927 if (why == ROOT_INIT && isroot) 928 rootvp = devvp; 929 930 ud_vfs_add(udf_vfsp); 931 932 if (udf_vfsp->udf_flags == UDF_FL_RW) { 933 udf_vfsp->udf_clean = UDF_DIRTY; 934 ud_update_superblock(vfsp); 935 } 936 937 return (0); 938 939 out: 940 ud_destroy_fsp(udf_vfsp); 941 if (needclose) { 942 (void) VOP_CLOSE(devvp, (vfsp->vfs_flag & VFS_RDONLY) ? 943 FREAD : FREAD|FWRITE, 1, (offset_t)0, cr, NULL); 944 bflush(dev); 945 binval(dev); 946 } 947 VN_RELE(devvp); 948 949 return (error); 950 } 951 952 953 static struct udf_vfs * 954 ud_validate_and_fill_superblock(dev_t dev, int32_t bsize, uint32_t avd_loc) 955 { 956 int32_t error, count, index, shift; 957 uint32_t dummy, vds_loc; 958 caddr_t addr; 959 daddr_t blkno, lblkno; 960 struct buf *secbp, *bp; 961 struct tag *ttag; 962 struct anch_vol_desc_ptr *avdp; 963 struct file_set_desc *fsd; 964 struct udf_vfs *udf_vfsp = NULL; 965 struct pmap_hdr *hdr; 966 struct pmap_typ1 *typ1; 967 struct pmap_typ2 *typ2; 968 struct ud_map *map; 969 int32_t desc_len; 970 971 ud_printf("ud_validate_and_fill_superblock\n"); 972 973 if (bsize < DEV_BSIZE) { 974 return (NULL); 975 } 976 shift = 0; 977 while ((bsize >> shift) > DEV_BSIZE) { 978 shift++; 979 } 980 981 /* 982 * Read Anchor Volume Descriptor 983 * Verify it and get the location of 984 * Main Volume Descriptor Sequence 985 */ 986 secbp = ud_bread(dev, avd_loc << shift, ANCHOR_VOL_DESC_LEN); 987 if ((error = geterror(secbp)) != 0) { 988 cmn_err(CE_NOTE, "udfs : Could not read Anchor Volume Desc %x", 989 error); 990 brelse(secbp); 991 return (NULL); 992 } 993 avdp = (struct anch_vol_desc_ptr *)secbp->b_un.b_addr; 994 if (ud_verify_tag_and_desc(&avdp->avd_tag, UD_ANCH_VOL_DESC, 995 avd_loc, 1, ANCHOR_VOL_DESC_LEN) != 0) { 996 brelse(secbp); 997 return (NULL); 998 } 999 udf_vfsp = (struct udf_vfs *) 1000 kmem_zalloc(sizeof (struct udf_vfs), KM_SLEEP); 1001 udf_vfsp->udf_mvds_loc = SWAP_32(avdp->avd_main_vdse.ext_loc); 1002 udf_vfsp->udf_mvds_len = SWAP_32(avdp->avd_main_vdse.ext_len); 1003 udf_vfsp->udf_rvds_loc = SWAP_32(avdp->avd_res_vdse.ext_loc); 1004 udf_vfsp->udf_rvds_len = SWAP_32(avdp->avd_res_vdse.ext_len); 1005 secbp->b_flags = B_AGE | B_STALE; 1006 brelse(secbp); 1007 1008 /* 1009 * Read Main Volume Descriptor Sequence 1010 * and process it 1011 */ 1012 vds_loc = udf_vfsp->udf_mvds_loc; 1013 secbp = ud_bread(dev, vds_loc << shift, 1014 udf_vfsp->udf_mvds_len); 1015 if ((error = geterror(secbp)) != 0) { 1016 brelse(secbp); 1017 cmn_err(CE_NOTE, "udfs : Could not read Main Volume Desc %x", 1018 error); 1019 1020 vds_loc = udf_vfsp->udf_rvds_loc; 1021 secbp = ud_bread(dev, vds_loc << shift, 1022 udf_vfsp->udf_rvds_len); 1023 if ((error = geterror(secbp)) != 0) { 1024 brelse(secbp); 1025 cmn_err(CE_NOTE, 1026 "udfs : Could not read Res Volume Desc %x", error); 1027 return (NULL); 1028 } 1029 } 1030 1031 udf_vfsp->udf_vds = ngeteblk(udf_vfsp->udf_mvds_len); 1032 bp = udf_vfsp->udf_vds; 1033 bp->b_edev = dev; 1034 bp->b_dev = cmpdev(dev); 1035 bp->b_blkno = vds_loc << shift; 1036 bp->b_bcount = udf_vfsp->udf_mvds_len; 1037 bcopy(secbp->b_un.b_addr, bp->b_un.b_addr, udf_vfsp->udf_mvds_len); 1038 secbp->b_flags |= B_STALE | B_AGE; 1039 brelse(secbp); 1040 1041 1042 count = udf_vfsp->udf_mvds_len / DEV_BSIZE; 1043 addr = bp->b_un.b_addr; 1044 for (index = 0; index < count; index ++) { 1045 ttag = (struct tag *)(addr + index * DEV_BSIZE); 1046 desc_len = udf_vfsp->udf_mvds_len - (index * DEV_BSIZE); 1047 if (ud_verify_tag_and_desc(ttag, UD_PRI_VOL_DESC, 1048 vds_loc + (index >> shift), 1049 1, desc_len) == 0) { 1050 if (udf_vfsp->udf_pvd == NULL) { 1051 udf_vfsp->udf_pvd = 1052 (struct pri_vol_desc *)ttag; 1053 } else { 1054 struct pri_vol_desc *opvd, *npvd; 1055 1056 opvd = udf_vfsp->udf_pvd; 1057 npvd = (struct pri_vol_desc *)ttag; 1058 1059 if ((strncmp(opvd->pvd_vsi, 1060 npvd->pvd_vsi, 128) == 0) && 1061 (strncmp(opvd->pvd_vol_id, 1062 npvd->pvd_vol_id, 32) == 0) && 1063 (strncmp((caddr_t)&opvd->pvd_desc_cs, 1064 (caddr_t)&npvd->pvd_desc_cs, 1065 sizeof (charspec_t)) == 0)) { 1066 1067 if (SWAP_32(opvd->pvd_vdsn) < 1068 SWAP_32(npvd->pvd_vdsn)) { 1069 udf_vfsp->udf_pvd = npvd; 1070 } 1071 } else { 1072 goto out; 1073 } 1074 } 1075 } else if (ud_verify_tag_and_desc(ttag, UD_LOG_VOL_DESC, 1076 vds_loc + (index >> shift), 1077 1, desc_len) == 0) { 1078 struct log_vol_desc *lvd; 1079 1080 lvd = (struct log_vol_desc *)ttag; 1081 if (strncmp(lvd->lvd_dom_id.reg_id, 1082 UDF_DOMAIN_NAME, 23) != 0) { 1083 printf("Domain ID in lvd is not valid\n"); 1084 goto out; 1085 } 1086 1087 if (udf_vfsp->udf_lvd == NULL) { 1088 udf_vfsp->udf_lvd = lvd; 1089 } else { 1090 struct log_vol_desc *olvd; 1091 1092 olvd = udf_vfsp->udf_lvd; 1093 if ((strncmp((caddr_t)&olvd->lvd_desc_cs, 1094 (caddr_t)&lvd->lvd_desc_cs, 1095 sizeof (charspec_t)) == 0) && 1096 (strncmp(olvd->lvd_lvid, 1097 lvd->lvd_lvid, 128) == 0)) { 1098 if (SWAP_32(olvd->lvd_vdsn) < 1099 SWAP_32(lvd->lvd_vdsn)) { 1100 udf_vfsp->udf_lvd = lvd; 1101 } 1102 } else { 1103 goto out; 1104 } 1105 } 1106 } else if (ud_verify_tag_and_desc(ttag, UD_PART_DESC, 1107 vds_loc + (index >> shift), 1108 1, desc_len) == 0) { 1109 int32_t i; 1110 struct phdr_desc *hdr; 1111 struct part_desc *pdesc; 1112 struct ud_part *pnew, *pold, *part; 1113 1114 pdesc = (struct part_desc *)ttag; 1115 pold = udf_vfsp->udf_parts; 1116 for (i = 0; i < udf_vfsp->udf_npart; i++) { 1117 if (pold->udp_number != 1118 SWAP_16(pdesc->pd_pnum)) { 1119 pold++; 1120 continue; 1121 } 1122 1123 if (SWAP_32(pdesc->pd_vdsn) > 1124 pold->udp_seqno) { 1125 pold->udp_seqno = 1126 SWAP_32(pdesc->pd_vdsn); 1127 pold->udp_access = 1128 SWAP_32(pdesc->pd_acc_type); 1129 pold->udp_start = 1130 SWAP_32(pdesc->pd_part_start); 1131 pold->udp_length = 1132 SWAP_32(pdesc->pd_part_length); 1133 } 1134 goto loop_end; 1135 } 1136 pold = udf_vfsp->udf_parts; 1137 udf_vfsp->udf_npart++; 1138 pnew = kmem_zalloc(udf_vfsp->udf_npart * 1139 sizeof (struct ud_part), KM_SLEEP); 1140 udf_vfsp->udf_parts = pnew; 1141 if (pold) { 1142 bcopy(pold, pnew, 1143 sizeof (struct ud_part) * 1144 (udf_vfsp->udf_npart - 1)); 1145 kmem_free(pold, 1146 sizeof (struct ud_part) * 1147 (udf_vfsp->udf_npart - 1)); 1148 } 1149 part = pnew + (udf_vfsp->udf_npart - 1); 1150 part->udp_number = SWAP_16(pdesc->pd_pnum); 1151 part->udp_seqno = SWAP_32(pdesc->pd_vdsn); 1152 part->udp_access = SWAP_32(pdesc->pd_acc_type); 1153 part->udp_start = SWAP_32(pdesc->pd_part_start); 1154 part->udp_length = SWAP_32(pdesc->pd_part_length); 1155 part->udp_last_alloc = 0; 1156 1157 /* 1158 * Figure out space bitmaps 1159 * or space tables 1160 */ 1161 hdr = (struct phdr_desc *)pdesc->pd_pc_use; 1162 if (hdr->phdr_ust.sad_ext_len) { 1163 part->udp_flags = UDP_SPACETBLS; 1164 part->udp_unall_loc = 1165 SWAP_32(hdr->phdr_ust.sad_ext_loc); 1166 part->udp_unall_len = 1167 SWAP_32(hdr->phdr_ust.sad_ext_len); 1168 part->udp_freed_loc = 1169 SWAP_32(hdr->phdr_fst.sad_ext_loc); 1170 part->udp_freed_len = 1171 SWAP_32(hdr->phdr_fst.sad_ext_len); 1172 } else { 1173 part->udp_flags = UDP_BITMAPS; 1174 part->udp_unall_loc = 1175 SWAP_32(hdr->phdr_usb.sad_ext_loc); 1176 part->udp_unall_len = 1177 SWAP_32(hdr->phdr_usb.sad_ext_len); 1178 part->udp_freed_loc = 1179 SWAP_32(hdr->phdr_fsb.sad_ext_loc); 1180 part->udp_freed_len = 1181 SWAP_32(hdr->phdr_fsb.sad_ext_len); 1182 } 1183 } else if (ud_verify_tag_and_desc(ttag, UD_TERM_DESC, 1184 vds_loc + (index >> shift), 1185 1, desc_len) == 0) { 1186 1187 break; 1188 } 1189 loop_end: 1190 ; 1191 } 1192 if ((udf_vfsp->udf_pvd == NULL) || 1193 (udf_vfsp->udf_lvd == NULL) || 1194 (udf_vfsp->udf_parts == NULL)) { 1195 goto out; 1196 } 1197 1198 /* 1199 * Process Primary Volume Descriptor 1200 */ 1201 (void) strncpy(udf_vfsp->udf_volid, udf_vfsp->udf_pvd->pvd_vol_id, 32); 1202 udf_vfsp->udf_volid[31] = '\0'; 1203 udf_vfsp->udf_tsno = SWAP_16(udf_vfsp->udf_pvd->pvd_tag.tag_sno); 1204 1205 /* 1206 * Process Logical Volume Descriptor 1207 */ 1208 udf_vfsp->udf_lbsize = 1209 SWAP_32(udf_vfsp->udf_lvd->lvd_log_bsize); 1210 udf_vfsp->udf_lbmask = udf_vfsp->udf_lbsize - 1; 1211 udf_vfsp->udf_l2d_shift = shift; 1212 udf_vfsp->udf_l2b_shift = shift + DEV_BSHIFT; 1213 1214 /* 1215 * Check if the media is in 1216 * proper domain. 1217 */ 1218 if (strcmp(udf_vfsp->udf_lvd->lvd_dom_id.reg_id, 1219 UDF_DOMAIN_NAME) != 0) { 1220 goto out; 1221 } 1222 1223 /* 1224 * AVDS offset does not match with the lbsize 1225 * in the lvd 1226 */ 1227 if (udf_vfsp->udf_lbsize != bsize) { 1228 goto out; 1229 } 1230 1231 udf_vfsp->udf_iseq_loc = 1232 SWAP_32(udf_vfsp->udf_lvd->lvd_int_seq_ext.ext_loc); 1233 udf_vfsp->udf_iseq_len = 1234 SWAP_32(udf_vfsp->udf_lvd->lvd_int_seq_ext.ext_len); 1235 1236 udf_vfsp->udf_fsd_prn = 1237 SWAP_16(udf_vfsp->udf_lvd->lvd_lvcu.lad_ext_prn); 1238 udf_vfsp->udf_fsd_loc = 1239 SWAP_32(udf_vfsp->udf_lvd->lvd_lvcu.lad_ext_loc); 1240 udf_vfsp->udf_fsd_len = 1241 SWAP_32(udf_vfsp->udf_lvd->lvd_lvcu.lad_ext_len); 1242 1243 1244 /* 1245 * process paritions 1246 */ 1247 udf_vfsp->udf_mtype = udf_vfsp->udf_parts[0].udp_access; 1248 for (index = 0; index < udf_vfsp->udf_npart; index ++) { 1249 if (udf_vfsp->udf_parts[index].udp_access < 1250 udf_vfsp->udf_mtype) { 1251 udf_vfsp->udf_mtype = 1252 udf_vfsp->udf_parts[index].udp_access; 1253 } 1254 } 1255 if ((udf_vfsp->udf_mtype < UDF_MT_RO) || 1256 (udf_vfsp->udf_mtype > UDF_MT_OW)) { 1257 udf_vfsp->udf_mtype = UDF_MT_RO; 1258 } 1259 1260 udf_vfsp->udf_nmaps = 0; 1261 hdr = (struct pmap_hdr *)udf_vfsp->udf_lvd->lvd_pmaps; 1262 count = SWAP_32(udf_vfsp->udf_lvd->lvd_num_pmaps); 1263 for (index = 0; index < count; index++) { 1264 1265 if ((hdr->maph_type == MAP_TYPE1) && 1266 (hdr->maph_length == MAP_TYPE1_LEN)) { 1267 typ1 = (struct pmap_typ1 *)hdr; 1268 1269 map = udf_vfsp->udf_maps; 1270 udf_vfsp->udf_maps = 1271 kmem_zalloc(sizeof (struct ud_map) * 1272 (udf_vfsp->udf_nmaps + 1), KM_SLEEP); 1273 if (map != NULL) { 1274 bcopy(map, udf_vfsp->udf_maps, 1275 sizeof (struct ud_map) * 1276 udf_vfsp->udf_nmaps); 1277 kmem_free(map, sizeof (struct ud_map) * 1278 udf_vfsp->udf_nmaps); 1279 } 1280 map = udf_vfsp->udf_maps + udf_vfsp->udf_nmaps; 1281 map->udm_flags = UDM_MAP_NORM; 1282 map->udm_vsn = SWAP_16(typ1->map1_vsn); 1283 map->udm_pn = SWAP_16(typ1->map1_pn); 1284 udf_vfsp->udf_nmaps ++; 1285 } else if ((hdr->maph_type == MAP_TYPE2) && 1286 (hdr->maph_length == MAP_TYPE2_LEN)) { 1287 typ2 = (struct pmap_typ2 *)hdr; 1288 1289 if (strncmp(typ2->map2_pti.reg_id, 1290 UDF_VIRT_PART, 23) == 0) { 1291 /* 1292 * Add this to the normal 1293 * partition table so that 1294 * we donot 1295 */ 1296 map = udf_vfsp->udf_maps; 1297 udf_vfsp->udf_maps = 1298 kmem_zalloc(sizeof (struct ud_map) * 1299 (udf_vfsp->udf_nmaps + 1), KM_SLEEP); 1300 if (map != NULL) { 1301 bcopy(map, udf_vfsp->udf_maps, 1302 sizeof (struct ud_map) * 1303 udf_vfsp->udf_nmaps); 1304 kmem_free(map, 1305 sizeof (struct ud_map) * 1306 udf_vfsp->udf_nmaps); 1307 } 1308 map = udf_vfsp->udf_maps + udf_vfsp->udf_nmaps; 1309 map->udm_flags = UDM_MAP_VPM; 1310 map->udm_vsn = SWAP_16(typ2->map2_vsn); 1311 map->udm_pn = SWAP_16(typ2->map2_pn); 1312 udf_vfsp->udf_nmaps ++; 1313 if (error = ud_get_last_block(dev, &lblkno)) { 1314 goto out; 1315 } 1316 if (error = ud_val_get_vat(udf_vfsp, dev, 1317 lblkno, map)) { 1318 goto out; 1319 } 1320 } else if (strncmp(typ2->map2_pti.reg_id, 1321 UDF_SPAR_PART, 23) == 0) { 1322 1323 if (SWAP_16(typ2->map2_pl) != 32) { 1324 printf( 1325 "Packet Length is not valid %x\n", 1326 SWAP_16(typ2->map2_pl)); 1327 goto out; 1328 } 1329 if ((typ2->map2_nst < 1) || 1330 (typ2->map2_nst > 4)) { 1331 goto out; 1332 } 1333 map = udf_vfsp->udf_maps; 1334 udf_vfsp->udf_maps = 1335 kmem_zalloc(sizeof (struct ud_map) * 1336 (udf_vfsp->udf_nmaps + 1), 1337 KM_SLEEP); 1338 if (map != NULL) { 1339 bcopy(map, udf_vfsp->udf_maps, 1340 sizeof (struct ud_map) * 1341 udf_vfsp->udf_nmaps); 1342 kmem_free(map, 1343 sizeof (struct ud_map) * 1344 udf_vfsp->udf_nmaps); 1345 } 1346 map = udf_vfsp->udf_maps + udf_vfsp->udf_nmaps; 1347 map->udm_flags = UDM_MAP_SPM; 1348 map->udm_vsn = SWAP_16(typ2->map2_vsn); 1349 map->udm_pn = SWAP_16(typ2->map2_pn); 1350 1351 udf_vfsp->udf_nmaps ++; 1352 1353 if (error = ud_read_sparing_tbls(udf_vfsp, 1354 dev, map, typ2)) { 1355 goto out; 1356 } 1357 } else { 1358 /* 1359 * Unknown type of partition 1360 * Bail out 1361 */ 1362 goto out; 1363 } 1364 } else { 1365 /* 1366 * Unknown type of partition 1367 * Bail out 1368 */ 1369 goto out; 1370 } 1371 hdr = (struct pmap_hdr *)(((uint8_t *)hdr) + hdr->maph_length); 1372 } 1373 1374 1375 /* 1376 * Read Logical Volume Integrity Sequence 1377 * and process it 1378 */ 1379 secbp = ud_bread(dev, udf_vfsp->udf_iseq_loc << shift, 1380 udf_vfsp->udf_iseq_len); 1381 if ((error = geterror(secbp)) != 0) { 1382 cmn_err(CE_NOTE, 1383 "udfs : Could not read Logical Volume Integrity Sequence %x", 1384 error); 1385 brelse(secbp); 1386 goto out; 1387 } 1388 udf_vfsp->udf_iseq = ngeteblk(udf_vfsp->udf_iseq_len); 1389 bp = udf_vfsp->udf_iseq; 1390 bp->b_edev = dev; 1391 bp->b_dev = cmpdev(dev); 1392 bp->b_blkno = udf_vfsp->udf_iseq_loc << shift; 1393 bp->b_bcount = udf_vfsp->udf_iseq_len; 1394 bcopy(secbp->b_un.b_addr, bp->b_un.b_addr, udf_vfsp->udf_iseq_len); 1395 secbp->b_flags |= B_STALE | B_AGE; 1396 brelse(secbp); 1397 1398 count = udf_vfsp->udf_iseq_len / DEV_BSIZE; 1399 addr = bp->b_un.b_addr; 1400 for (index = 0; index < count; index ++) { 1401 ttag = (struct tag *)(addr + index * DEV_BSIZE); 1402 desc_len = udf_vfsp->udf_iseq_len - (index * DEV_BSIZE); 1403 if (ud_verify_tag_and_desc(ttag, UD_LOG_VOL_INT, 1404 udf_vfsp->udf_iseq_loc + (index >> shift), 1405 1, desc_len) == 0) { 1406 1407 struct log_vol_int_desc *lvid; 1408 1409 lvid = (struct log_vol_int_desc *)ttag; 1410 udf_vfsp->udf_lvid = lvid; 1411 1412 if (SWAP_32(lvid->lvid_int_type) == LOG_VOL_CLOSE_INT) { 1413 udf_vfsp->udf_clean = UDF_CLEAN; 1414 } else { 1415 udf_vfsp->udf_clean = UDF_DIRTY; 1416 } 1417 1418 /* 1419 * update superblock with the metadata 1420 */ 1421 ud_convert_to_superblock(udf_vfsp, lvid); 1422 break; 1423 } 1424 } 1425 1426 if (udf_vfsp->udf_lvid == NULL) { 1427 goto out; 1428 } 1429 1430 if ((blkno = ud_xlate_to_daddr(udf_vfsp, 1431 udf_vfsp->udf_fsd_prn, udf_vfsp->udf_fsd_loc, 1432 1, &dummy)) == 0) { 1433 goto out; 1434 } 1435 secbp = ud_bread(dev, blkno << shift, udf_vfsp->udf_fsd_len); 1436 if ((error = geterror(secbp)) != 0) { 1437 cmn_err(CE_NOTE, 1438 "udfs : Could not read File Set Descriptor %x", error); 1439 brelse(secbp); 1440 goto out; 1441 } 1442 fsd = (struct file_set_desc *)secbp->b_un.b_addr; 1443 if (ud_verify_tag_and_desc(&fsd->fsd_tag, UD_FILE_SET_DESC, 1444 udf_vfsp->udf_fsd_loc, 1445 1, udf_vfsp->udf_fsd_len) != 0) { 1446 secbp->b_flags = B_AGE | B_STALE; 1447 brelse(secbp); 1448 goto out; 1449 } 1450 udf_vfsp->udf_ricb_prn = SWAP_16(fsd->fsd_root_icb.lad_ext_prn); 1451 udf_vfsp->udf_ricb_loc = SWAP_32(fsd->fsd_root_icb.lad_ext_loc); 1452 udf_vfsp->udf_ricb_len = SWAP_32(fsd->fsd_root_icb.lad_ext_len); 1453 secbp->b_flags = B_AGE | B_STALE; 1454 brelse(secbp); 1455 udf_vfsp->udf_root_blkno = ud_xlate_to_daddr(udf_vfsp, 1456 udf_vfsp->udf_ricb_prn, udf_vfsp->udf_ricb_loc, 1457 1, &dummy); 1458 1459 return (udf_vfsp); 1460 out: 1461 ud_destroy_fsp(udf_vfsp); 1462 1463 return (NULL); 1464 } 1465 1466 /* 1467 * release/free resources from one ud_map; map data was zalloc'd in 1468 * ud_validate_and_fill_superblock() and fields may later point to 1469 * valid data 1470 */ 1471 static void 1472 ud_free_map(struct ud_map *map) 1473 { 1474 uint32_t n; 1475 1476 if (map->udm_flags & UDM_MAP_VPM) { 1477 if (map->udm_count) { 1478 kmem_free(map->udm_count, 1479 map->udm_nent * sizeof (*map->udm_count)); 1480 map->udm_count = NULL; 1481 } 1482 if (map->udm_bp) { 1483 for (n = 0; n < map->udm_nent; n++) { 1484 if (map->udm_bp[n]) 1485 brelse(map->udm_bp[n]); 1486 } 1487 kmem_free(map->udm_bp, 1488 map->udm_nent * sizeof (*map->udm_bp)); 1489 map->udm_bp = NULL; 1490 } 1491 if (map->udm_addr) { 1492 kmem_free(map->udm_addr, 1493 map->udm_nent * sizeof (*map->udm_addr)); 1494 map->udm_addr = NULL; 1495 } 1496 } 1497 if (map->udm_flags & UDM_MAP_SPM) { 1498 for (n = 0; n < MAX_SPM; n++) { 1499 if (map->udm_sbp[n]) { 1500 brelse(map->udm_sbp[n]); 1501 map->udm_sbp[n] = NULL; 1502 map->udm_spaddr[n] = NULL; 1503 } 1504 } 1505 } 1506 } 1507 1508 void 1509 ud_destroy_fsp(struct udf_vfs *udf_vfsp) 1510 { 1511 int32_t i; 1512 1513 ud_printf("ud_destroy_fsp\n"); 1514 if (udf_vfsp == NULL) 1515 return; 1516 1517 if (udf_vfsp->udf_maps) { 1518 for (i = 0; i < udf_vfsp->udf_nmaps; i++) 1519 ud_free_map(&udf_vfsp->udf_maps[i]); 1520 1521 kmem_free(udf_vfsp->udf_maps, 1522 udf_vfsp->udf_nmaps * sizeof (*udf_vfsp->udf_maps)); 1523 } 1524 1525 if (udf_vfsp->udf_parts) { 1526 kmem_free(udf_vfsp->udf_parts, 1527 udf_vfsp->udf_npart * sizeof (*udf_vfsp->udf_parts)); 1528 } 1529 if (udf_vfsp->udf_iseq) { 1530 udf_vfsp->udf_iseq->b_flags |= (B_STALE|B_AGE); 1531 brelse(udf_vfsp->udf_iseq); 1532 } 1533 if (udf_vfsp->udf_vds) { 1534 udf_vfsp->udf_vds->b_flags |= (B_STALE|B_AGE); 1535 brelse(udf_vfsp->udf_vds); 1536 } 1537 if (udf_vfsp->udf_vfs) 1538 ud_vfs_remove(udf_vfsp); 1539 if (udf_vfsp->udf_fsmnt) { 1540 kmem_free(udf_vfsp->udf_fsmnt, 1541 strlen(udf_vfsp->udf_fsmnt) + 1); 1542 } 1543 kmem_free(udf_vfsp, sizeof (*udf_vfsp)); 1544 } 1545 1546 void 1547 ud_convert_to_superblock(struct udf_vfs *udf_vfsp, 1548 struct log_vol_int_desc *lvid) 1549 { 1550 int32_t i, c; 1551 uint32_t *temp; 1552 struct ud_part *ud_part; 1553 struct lvid_iu *iu; 1554 1555 udf_vfsp->udf_maxuniq = SWAP_64(lvid->lvid_uniqid); 1556 temp = lvid->lvid_fst; 1557 c = SWAP_32(lvid->lvid_npart); 1558 ud_part = udf_vfsp->udf_parts; 1559 for (i = 0; i < c; i++) { 1560 if (i >= udf_vfsp->udf_npart) { 1561 continue; 1562 } 1563 ud_part->udp_nfree = SWAP_32(temp[i]); 1564 ud_part->udp_nblocks = SWAP_32(temp[c + i]); 1565 udf_vfsp->udf_freeblks += SWAP_32(temp[i]); 1566 udf_vfsp->udf_totalblks += SWAP_32(temp[c + i]); 1567 ud_part++; 1568 } 1569 1570 iu = (struct lvid_iu *)(temp + c * 2); 1571 udf_vfsp->udf_nfiles = SWAP_32(iu->lvidiu_nfiles); 1572 udf_vfsp->udf_ndirs = SWAP_32(iu->lvidiu_ndirs); 1573 udf_vfsp->udf_miread = BCD2HEX_16(SWAP_16(iu->lvidiu_mread)); 1574 udf_vfsp->udf_miwrite = BCD2HEX_16(SWAP_16(iu->lvidiu_mwrite)); 1575 udf_vfsp->udf_mawrite = BCD2HEX_16(SWAP_16(iu->lvidiu_maxwr)); 1576 } 1577 1578 void 1579 ud_update_superblock(struct vfs *vfsp) 1580 { 1581 struct udf_vfs *udf_vfsp; 1582 1583 ud_printf("ud_update_superblock\n"); 1584 1585 udf_vfsp = (struct udf_vfs *)vfsp->vfs_data; 1586 1587 mutex_enter(&udf_vfsp->udf_lock); 1588 ud_sbwrite(udf_vfsp); 1589 mutex_exit(&udf_vfsp->udf_lock); 1590 } 1591 1592 1593 #include <sys/dkio.h> 1594 #include <sys/cdio.h> 1595 #include <sys/vtoc.h> 1596 1597 /* 1598 * This part of the code is known 1599 * to work with only sparc. It needs 1600 * to be evluated before using it with x86 1601 */ 1602 int32_t 1603 ud_get_last_block(dev_t dev, daddr_t *blkno) 1604 { 1605 struct vtoc vtoc; 1606 struct dk_cinfo dki_info; 1607 int32_t rval, error; 1608 1609 if ((error = cdev_ioctl(dev, DKIOCGVTOC, (intptr_t)&vtoc, 1610 FKIOCTL|FREAD|FNATIVE, CRED(), &rval)) != 0) { 1611 cmn_err(CE_NOTE, "Could not get the vtoc information"); 1612 return (error); 1613 } 1614 1615 if (vtoc.v_sanity != VTOC_SANE) { 1616 return (EINVAL); 1617 } 1618 if ((error = cdev_ioctl(dev, DKIOCINFO, (intptr_t)&dki_info, 1619 FKIOCTL|FREAD|FNATIVE, CRED(), &rval)) != 0) { 1620 cmn_err(CE_NOTE, "Could not get the slice information"); 1621 return (error); 1622 } 1623 1624 if (dki_info.dki_partition > V_NUMPAR) { 1625 return (EINVAL); 1626 } 1627 1628 1629 *blkno = vtoc.v_part[dki_info.dki_partition].p_size; 1630 1631 return (0); 1632 } 1633 1634 /* Search sequentially N - 2, N, N - 152, N - 150 for vat icb */ 1635 /* 1636 * int32_t ud_sub_blks[] = {2, 0, 152, 150}; 1637 */ 1638 int32_t ud_sub_blks[] = {152, 150, 2, 0}; 1639 int32_t ud_sub_count = 4; 1640 1641 /* 1642 * Validate the VAT ICB 1643 */ 1644 static int32_t 1645 ud_val_get_vat(struct udf_vfs *udf_vfsp, dev_t dev, 1646 daddr_t blkno, struct ud_map *udm) 1647 { 1648 struct buf *secbp; 1649 struct file_entry *fe; 1650 int32_t end_loc, i, j, ad_type; 1651 struct short_ad *sad; 1652 struct long_ad *lad; 1653 uint32_t count, blk; 1654 struct ud_part *ud_part; 1655 int err = 0; 1656 1657 end_loc = (blkno >> udf_vfsp->udf_l2d_shift) - 1; 1658 1659 for (i = 0; i < ud_sub_count; i++) { 1660 udm->udm_vat_icb = end_loc - ud_sub_blks[i]; 1661 1662 secbp = ud_bread(dev, 1663 udm->udm_vat_icb << udf_vfsp->udf_l2d_shift, 1664 udf_vfsp->udf_lbsize); 1665 ASSERT(secbp->b_un.b_addr); 1666 1667 fe = (struct file_entry *)secbp->b_un.b_addr; 1668 if (ud_verify_tag_and_desc(&fe->fe_tag, UD_FILE_ENTRY, 0, 1669 0, 0) == 0) { 1670 if (ud_verify_tag_and_desc(&fe->fe_tag, UD_FILE_ENTRY, 1671 SWAP_32(fe->fe_tag.tag_loc), 1672 1, udf_vfsp->udf_lbsize) == 0) { 1673 if (fe->fe_icb_tag.itag_ftype == 0) { 1674 break; 1675 } 1676 } 1677 } 1678 secbp->b_flags |= B_AGE | B_STALE; 1679 brelse(secbp); 1680 } 1681 if (i == ud_sub_count) { 1682 return (EINVAL); 1683 } 1684 1685 ad_type = SWAP_16(fe->fe_icb_tag.itag_flags) & 0x3; 1686 if (ad_type == ICB_FLAG_ONE_AD) { 1687 udm->udm_nent = 1; 1688 } else if (ad_type == ICB_FLAG_SHORT_AD) { 1689 udm->udm_nent = 1690 SWAP_32(fe->fe_len_adesc) / sizeof (struct short_ad); 1691 } else if (ad_type == ICB_FLAG_LONG_AD) { 1692 udm->udm_nent = 1693 SWAP_32(fe->fe_len_adesc) / sizeof (struct long_ad); 1694 } else { 1695 err = EINVAL; 1696 goto end; 1697 } 1698 1699 udm->udm_count = kmem_zalloc(udm->udm_nent * sizeof (*udm->udm_count), 1700 KM_SLEEP); 1701 udm->udm_bp = kmem_zalloc(udm->udm_nent * sizeof (*udm->udm_bp), 1702 KM_SLEEP); 1703 udm->udm_addr = kmem_zalloc(udm->udm_nent * sizeof (*udm->udm_addr), 1704 KM_SLEEP); 1705 1706 if (ad_type == ICB_FLAG_ONE_AD) { 1707 udm->udm_count[0] = (SWAP_64(fe->fe_info_len) - 36) / 1708 sizeof (uint32_t); 1709 udm->udm_bp[0] = secbp; 1710 udm->udm_addr[0] = (uint32_t *) 1711 &fe->fe_spec[SWAP_32(fe->fe_len_ear)]; 1712 return (0); 1713 } 1714 for (i = 0; i < udm->udm_nent; i++) { 1715 if (ad_type == ICB_FLAG_SHORT_AD) { 1716 sad = (struct short_ad *) 1717 (fe->fe_spec + SWAP_32(fe->fe_len_ear)); 1718 sad += i; 1719 count = SWAP_32(sad->sad_ext_len); 1720 blk = SWAP_32(sad->sad_ext_loc); 1721 } else { 1722 lad = (struct long_ad *) 1723 (fe->fe_spec + SWAP_32(fe->fe_len_ear)); 1724 lad += i; 1725 count = SWAP_32(lad->lad_ext_len); 1726 blk = SWAP_32(lad->lad_ext_loc); 1727 ASSERT(SWAP_16(lad->lad_ext_prn) == udm->udm_pn); 1728 } 1729 if ((count & 0x3FFFFFFF) == 0) { 1730 break; 1731 } 1732 if (i < udm->udm_nent - 1) { 1733 udm->udm_count[i] = count / 4; 1734 } else { 1735 udm->udm_count[i] = (count - 36) / 4; 1736 } 1737 ud_part = udf_vfsp->udf_parts; 1738 for (j = 0; j < udf_vfsp->udf_npart; j++) { 1739 if (udm->udm_pn == ud_part->udp_number) { 1740 blk = ud_part->udp_start + blk; 1741 break; 1742 } 1743 } 1744 if (j == udf_vfsp->udf_npart) { 1745 err = EINVAL; 1746 break; 1747 } 1748 1749 count = (count + DEV_BSIZE - 1) & ~(DEV_BSIZE - 1); 1750 udm->udm_bp[i] = ud_bread(dev, 1751 blk << udf_vfsp->udf_l2d_shift, count); 1752 if ((udm->udm_bp[i]->b_error != 0) || 1753 (udm->udm_bp[i]->b_resid)) { 1754 err = EINVAL; 1755 break; 1756 } 1757 udm->udm_addr[i] = (uint32_t *)udm->udm_bp[i]->b_un.b_addr; 1758 } 1759 1760 end: 1761 if (err) 1762 ud_free_map(udm); 1763 secbp->b_flags |= B_AGE | B_STALE; 1764 brelse(secbp); 1765 return (err); 1766 } 1767 1768 int32_t 1769 ud_read_sparing_tbls(struct udf_vfs *udf_vfsp, 1770 dev_t dev, struct ud_map *map, struct pmap_typ2 *typ2) 1771 { 1772 int32_t index, valid = 0; 1773 uint32_t sz; 1774 struct buf *bp; 1775 struct stbl *stbl; 1776 1777 map->udm_plen = SWAP_16(typ2->map2_pl); 1778 map->udm_nspm = typ2->map2_nst; 1779 map->udm_spsz = SWAP_32(typ2->map2_sest); 1780 sz = (map->udm_spsz + udf_vfsp->udf_lbmask) & ~udf_vfsp->udf_lbmask; 1781 if (sz == 0) { 1782 return (0); 1783 } 1784 1785 for (index = 0; index < map->udm_nspm; index++) { 1786 map->udm_loc[index] = SWAP_32(typ2->map2_st[index]); 1787 1788 bp = ud_bread(dev, 1789 map->udm_loc[index] << udf_vfsp->udf_l2d_shift, sz); 1790 if ((bp->b_error != 0) || (bp->b_resid)) { 1791 brelse(bp); 1792 continue; 1793 } 1794 stbl = (struct stbl *)bp->b_un.b_addr; 1795 if (strncmp(stbl->stbl_si.reg_id, UDF_SPAR_TBL, 23) != 0) { 1796 printf("Sparing Identifier does not match\n"); 1797 bp->b_flags |= B_AGE | B_STALE; 1798 brelse(bp); 1799 continue; 1800 } 1801 map->udm_sbp[index] = bp; 1802 map->udm_spaddr[index] = bp->b_un.b_addr; 1803 #ifdef UNDEF 1804 { 1805 struct stbl_entry *te; 1806 int32_t i, tbl_len; 1807 1808 te = (struct stbl_entry *)&stbl->stbl_entry; 1809 tbl_len = SWAP_16(stbl->stbl_len); 1810 1811 printf("%x %x\n", tbl_len, SWAP_32(stbl->stbl_seqno)); 1812 printf("%x %x\n", bp->b_un.b_addr, te); 1813 1814 for (i = 0; i < tbl_len; i++) { 1815 printf("%x %x\n", SWAP_32(te->sent_ol), SWAP_32(te->sent_ml)); 1816 te ++; 1817 } 1818 } 1819 #endif 1820 valid ++; 1821 } 1822 1823 if (valid) { 1824 return (0); 1825 } 1826 return (EINVAL); 1827 } 1828 1829 uint32_t 1830 ud_get_lbsize(dev_t dev, uint32_t *loc) 1831 { 1832 int32_t bsize, shift, index, end_index; 1833 daddr_t last_block; 1834 uint32_t avd_loc; 1835 struct buf *bp; 1836 struct anch_vol_desc_ptr *avdp; 1837 uint32_t session_offset = 0; 1838 int32_t rval; 1839 1840 if (ud_get_last_block(dev, &last_block) != 0) { 1841 end_index = 1; 1842 } else { 1843 end_index = 3; 1844 } 1845 1846 if (cdev_ioctl(dev, CDROMREADOFFSET, (intptr_t)&session_offset, 1847 FKIOCTL|FREAD|FNATIVE, CRED(), &rval) != 0) { 1848 session_offset = 0; 1849 } 1850 1851 for (index = 0; index < end_index; index++) { 1852 1853 for (bsize = DEV_BSIZE, shift = 0; 1854 bsize <= MAXBSIZE; bsize <<= 1, shift++) { 1855 1856 if (index == 0) { 1857 avd_loc = 256; 1858 if (bsize <= 2048) { 1859 avd_loc += 1860 session_offset * 2048 / bsize; 1861 } else { 1862 avd_loc += 1863 session_offset / (bsize / 2048); 1864 } 1865 } else if (index == 1) { 1866 avd_loc = last_block - (1 << shift); 1867 } else { 1868 avd_loc = last_block - (256 << shift); 1869 } 1870 1871 bp = ud_bread(dev, avd_loc << shift, 1872 ANCHOR_VOL_DESC_LEN); 1873 if (geterror(bp) != 0) { 1874 brelse(bp); 1875 continue; 1876 } 1877 1878 /* 1879 * Verify if we have avdp here 1880 */ 1881 avdp = (struct anch_vol_desc_ptr *)bp->b_un.b_addr; 1882 if (ud_verify_tag_and_desc(&avdp->avd_tag, 1883 UD_ANCH_VOL_DESC, avd_loc, 1884 1, ANCHOR_VOL_DESC_LEN) != 0) { 1885 bp->b_flags |= B_AGE | B_STALE; 1886 brelse(bp); 1887 continue; 1888 } 1889 bp->b_flags |= B_AGE | B_STALE; 1890 brelse(bp); 1891 *loc = avd_loc; 1892 return (bsize); 1893 } 1894 } 1895 1896 /* 1897 * Did not find AVD at all the locations 1898 */ 1899 return (0); 1900 } 1901 1902 static int 1903 udfinit(int fstype, char *name) 1904 { 1905 static const fs_operation_def_t udf_vfsops_template[] = { 1906 VFSNAME_MOUNT, { .vfs_mount = udf_mount }, 1907 VFSNAME_UNMOUNT, { .vfs_unmount = udf_unmount }, 1908 VFSNAME_ROOT, { .vfs_root = udf_root }, 1909 VFSNAME_STATVFS, { .vfs_statvfs = udf_statvfs }, 1910 VFSNAME_SYNC, { .vfs_sync = udf_sync }, 1911 VFSNAME_VGET, { .vfs_vget = udf_vget }, 1912 VFSNAME_MOUNTROOT, { .vfs_mountroot = udf_mountroot }, 1913 NULL, NULL 1914 }; 1915 extern struct vnodeops *udf_vnodeops; 1916 extern const fs_operation_def_t udf_vnodeops_template[]; 1917 int error; 1918 1919 ud_printf("udfinit\n"); 1920 1921 error = vfs_setfsops(fstype, udf_vfsops_template, NULL); 1922 if (error != 0) { 1923 cmn_err(CE_WARN, "udfinit: bad vfs ops template"); 1924 return (error); 1925 } 1926 1927 error = vn_make_ops(name, udf_vnodeops_template, &udf_vnodeops); 1928 if (error != 0) { 1929 (void) vfs_freevfsops_by_type(fstype); 1930 cmn_err(CE_WARN, "udfinit: bad vnode ops template"); 1931 return (error); 1932 } 1933 1934 udf_fstype = fstype; 1935 1936 ud_init_inodes(); 1937 1938 return (0); 1939 }