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