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