17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 55a59a8b3Srsb * Common Development and Distribution License (the "License"). 65a59a8b3Srsb * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 2293239addSjohnlev * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 24*89b43686SBayard Bell * Copyright (c) 2011 Bayard G. Bell. All rights reserved. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #include <sys/types.h> 287c478bd9Sstevel@tonic-gate #include <sys/t_lock.h> 297c478bd9Sstevel@tonic-gate #include <sys/param.h> 307c478bd9Sstevel@tonic-gate #include <sys/time.h> 317c478bd9Sstevel@tonic-gate #include <sys/systm.h> 327c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 337c478bd9Sstevel@tonic-gate #include <sys/resource.h> 347c478bd9Sstevel@tonic-gate #include <sys/signal.h> 357c478bd9Sstevel@tonic-gate #include <sys/cred.h> 367c478bd9Sstevel@tonic-gate #include <sys/user.h> 377c478bd9Sstevel@tonic-gate #include <sys/buf.h> 387c478bd9Sstevel@tonic-gate #include <sys/vfs.h> 39aa59c4cbSrsb #include <sys/vfs_opreg.h> 407c478bd9Sstevel@tonic-gate #include <sys/stat.h> 417c478bd9Sstevel@tonic-gate #include <sys/vnode.h> 427c478bd9Sstevel@tonic-gate #include <sys/mode.h> 437c478bd9Sstevel@tonic-gate #include <sys/proc.h> 447c478bd9Sstevel@tonic-gate #include <sys/disp.h> 457c478bd9Sstevel@tonic-gate #include <sys/file.h> 467c478bd9Sstevel@tonic-gate #include <sys/fcntl.h> 477c478bd9Sstevel@tonic-gate #include <sys/flock.h> 487c478bd9Sstevel@tonic-gate #include <sys/kmem.h> 497c478bd9Sstevel@tonic-gate #include <sys/uio.h> 507c478bd9Sstevel@tonic-gate #include <sys/dnlc.h> 517c478bd9Sstevel@tonic-gate #include <sys/conf.h> 527c478bd9Sstevel@tonic-gate #include <sys/errno.h> 537c478bd9Sstevel@tonic-gate #include <sys/mman.h> 547c478bd9Sstevel@tonic-gate #include <sys/fbuf.h> 557c478bd9Sstevel@tonic-gate #include <sys/pathname.h> 567c478bd9Sstevel@tonic-gate #include <sys/debug.h> 577c478bd9Sstevel@tonic-gate #include <sys/vmsystm.h> 587c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h> 597c478bd9Sstevel@tonic-gate #include <sys/dirent.h> 607c478bd9Sstevel@tonic-gate #include <sys/errno.h> 617c478bd9Sstevel@tonic-gate #include <sys/modctl.h> 627c478bd9Sstevel@tonic-gate #include <sys/statvfs.h> 637c478bd9Sstevel@tonic-gate #include <sys/mount.h> 647c478bd9Sstevel@tonic-gate #include <sys/sunddi.h> 657c478bd9Sstevel@tonic-gate #include <sys/bootconf.h> 667c478bd9Sstevel@tonic-gate #include <sys/policy.h> 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate #include <vm/hat.h> 697c478bd9Sstevel@tonic-gate #include <vm/page.h> 707c478bd9Sstevel@tonic-gate #include <vm/pvn.h> 717c478bd9Sstevel@tonic-gate #include <vm/as.h> 727c478bd9Sstevel@tonic-gate #include <vm/seg.h> 737c478bd9Sstevel@tonic-gate #include <vm/seg_map.h> 747c478bd9Sstevel@tonic-gate #include <vm/seg_kmem.h> 757c478bd9Sstevel@tonic-gate #include <vm/seg_vn.h> 767c478bd9Sstevel@tonic-gate #include <vm/rm.h> 777c478bd9Sstevel@tonic-gate #include <vm/page.h> 787c478bd9Sstevel@tonic-gate #include <sys/swap.h> 797c478bd9Sstevel@tonic-gate #include <sys/mntent.h> 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate 827c478bd9Sstevel@tonic-gate #include <fs/fs_subr.h> 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate 857c478bd9Sstevel@tonic-gate #include <sys/fs/udf_volume.h> 867c478bd9Sstevel@tonic-gate #include <sys/fs/udf_inode.h> 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate 897c478bd9Sstevel@tonic-gate extern struct vnode *common_specvp(struct vnode *vp); 907c478bd9Sstevel@tonic-gate 917c478bd9Sstevel@tonic-gate extern kmutex_t ud_sync_busy; 927c478bd9Sstevel@tonic-gate static int32_t ud_mountfs(struct vfs *, 937c478bd9Sstevel@tonic-gate enum whymountroot, dev_t, char *, struct cred *, int32_t); 947c478bd9Sstevel@tonic-gate static struct udf_vfs *ud_validate_and_fill_superblock(dev_t, 957c478bd9Sstevel@tonic-gate int32_t, uint32_t); 967c478bd9Sstevel@tonic-gate void ud_destroy_fsp(struct udf_vfs *); 977c478bd9Sstevel@tonic-gate void ud_convert_to_superblock(struct udf_vfs *, 987c478bd9Sstevel@tonic-gate struct log_vol_int_desc *); 997c478bd9Sstevel@tonic-gate void ud_update_superblock(struct vfs *); 1007c478bd9Sstevel@tonic-gate int32_t ud_get_last_block(dev_t, daddr_t *); 1017c478bd9Sstevel@tonic-gate static int32_t ud_val_get_vat(struct udf_vfs *, 1027c478bd9Sstevel@tonic-gate dev_t, daddr_t, struct ud_map *); 1037c478bd9Sstevel@tonic-gate int32_t ud_read_sparing_tbls(struct udf_vfs *, 1047c478bd9Sstevel@tonic-gate dev_t, struct ud_map *, struct pmap_typ2 *); 1057c478bd9Sstevel@tonic-gate uint32_t ud_get_lbsize(dev_t, uint32_t *); 1067c478bd9Sstevel@tonic-gate 1077c478bd9Sstevel@tonic-gate static int32_t udf_mount(struct vfs *, 1087c478bd9Sstevel@tonic-gate struct vnode *, struct mounta *, struct cred *); 1097c478bd9Sstevel@tonic-gate static int32_t udf_unmount(struct vfs *, int, struct cred *); 1107c478bd9Sstevel@tonic-gate static int32_t udf_root(struct vfs *, struct vnode **); 1117c478bd9Sstevel@tonic-gate static int32_t udf_statvfs(struct vfs *, struct statvfs64 *); 1127c478bd9Sstevel@tonic-gate static int32_t udf_sync(struct vfs *, int16_t, struct cred *); 1137c478bd9Sstevel@tonic-gate static int32_t udf_vget(struct vfs *, struct vnode **, struct fid *); 1147c478bd9Sstevel@tonic-gate static int32_t udf_mountroot(struct vfs *vfsp, enum whymountroot); 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate static int udfinit(int, char *); 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate static mntopts_t udfs_mntopts; 1197c478bd9Sstevel@tonic-gate 1207c478bd9Sstevel@tonic-gate static vfsdef_t vfw = { 1217c478bd9Sstevel@tonic-gate VFSDEF_VERSION, 1227c478bd9Sstevel@tonic-gate "udfs", 1237c478bd9Sstevel@tonic-gate udfinit, 12443d5cd3dSjohnlev VSW_HASPROTO|VSW_CANREMOUNT|VSW_STATS|VSW_CANLOFI, 1257c478bd9Sstevel@tonic-gate &udfs_mntopts 1267c478bd9Sstevel@tonic-gate }; 1277c478bd9Sstevel@tonic-gate 1287c478bd9Sstevel@tonic-gate static mntopts_t udfs_mntopts = { 1297c478bd9Sstevel@tonic-gate 0, 1307c478bd9Sstevel@tonic-gate NULL 1317c478bd9Sstevel@tonic-gate }; 1327c478bd9Sstevel@tonic-gate 1337c478bd9Sstevel@tonic-gate /* 1347c478bd9Sstevel@tonic-gate * Module linkage information for the kernel. 1357c478bd9Sstevel@tonic-gate */ 1367c478bd9Sstevel@tonic-gate extern struct mod_ops mod_fsops; 1377c478bd9Sstevel@tonic-gate 1387c478bd9Sstevel@tonic-gate static struct modlfs modlfs = { 1397c478bd9Sstevel@tonic-gate &mod_fsops, "filesystem for UDFS", &vfw 1407c478bd9Sstevel@tonic-gate }; 1417c478bd9Sstevel@tonic-gate 1427c478bd9Sstevel@tonic-gate static struct modlinkage modlinkage = { 1437c478bd9Sstevel@tonic-gate MODREV_1, (void *)&modlfs, NULL 1447c478bd9Sstevel@tonic-gate }; 1457c478bd9Sstevel@tonic-gate 1467c478bd9Sstevel@tonic-gate int32_t udf_fstype = -1; 1477c478bd9Sstevel@tonic-gate 1487c478bd9Sstevel@tonic-gate int 1497c478bd9Sstevel@tonic-gate _init() 1507c478bd9Sstevel@tonic-gate { 1517c478bd9Sstevel@tonic-gate return (mod_install(&modlinkage)); 1527c478bd9Sstevel@tonic-gate } 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate int 1557c478bd9Sstevel@tonic-gate _fini() 1567c478bd9Sstevel@tonic-gate { 1577c478bd9Sstevel@tonic-gate return (EBUSY); 1587c478bd9Sstevel@tonic-gate } 1597c478bd9Sstevel@tonic-gate 1607c478bd9Sstevel@tonic-gate int 1617c478bd9Sstevel@tonic-gate _info(struct modinfo *modinfop) 1627c478bd9Sstevel@tonic-gate { 1637c478bd9Sstevel@tonic-gate return (mod_info(&modlinkage, modinfop)); 1647c478bd9Sstevel@tonic-gate } 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate 1677c478bd9Sstevel@tonic-gate /* -------------------- vfs routines -------------------- */ 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gate /* 1707c478bd9Sstevel@tonic-gate * XXX - this appears only to be used by the VM code to handle the case where 1717c478bd9Sstevel@tonic-gate * UNIX is running off the mini-root. That probably wants to be done 1727c478bd9Sstevel@tonic-gate * differently. 1737c478bd9Sstevel@tonic-gate */ 1747c478bd9Sstevel@tonic-gate struct vnode *rootvp; 1757c478bd9Sstevel@tonic-gate #ifndef __lint 1767c478bd9Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("safe sharing", rootvp)) 1777c478bd9Sstevel@tonic-gate #endif 1787c478bd9Sstevel@tonic-gate static int32_t 1797c478bd9Sstevel@tonic-gate udf_mount(struct vfs *vfsp, struct vnode *mvp, 1807c478bd9Sstevel@tonic-gate struct mounta *uap, struct cred *cr) 1817c478bd9Sstevel@tonic-gate { 1827c478bd9Sstevel@tonic-gate dev_t dev; 18393239addSjohnlev struct vnode *lvp = NULL; 18493239addSjohnlev struct vnode *svp = NULL; 1857c478bd9Sstevel@tonic-gate struct pathname dpn; 1867c478bd9Sstevel@tonic-gate int32_t error; 1877c478bd9Sstevel@tonic-gate enum whymountroot why; 1887c478bd9Sstevel@tonic-gate int oflag, aflag; 1897c478bd9Sstevel@tonic-gate 1907c478bd9Sstevel@tonic-gate ud_printf("udf_mount\n"); 1917c478bd9Sstevel@tonic-gate 1927c478bd9Sstevel@tonic-gate if ((error = secpolicy_fs_mount(cr, mvp, vfsp)) != 0) { 1937c478bd9Sstevel@tonic-gate return (error); 1947c478bd9Sstevel@tonic-gate } 1957c478bd9Sstevel@tonic-gate 1967c478bd9Sstevel@tonic-gate if (mvp->v_type != VDIR) { 1977c478bd9Sstevel@tonic-gate return (ENOTDIR); 1987c478bd9Sstevel@tonic-gate } 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate mutex_enter(&mvp->v_lock); 2017c478bd9Sstevel@tonic-gate if ((uap->flags & MS_REMOUNT) == 0 && 2027c478bd9Sstevel@tonic-gate (uap->flags & MS_OVERLAY) == 0 && 2037c478bd9Sstevel@tonic-gate (mvp->v_count != 1 || (mvp->v_flag & VROOT))) { 2047c478bd9Sstevel@tonic-gate mutex_exit(&mvp->v_lock); 2057c478bd9Sstevel@tonic-gate return (EBUSY); 2067c478bd9Sstevel@tonic-gate } 2077c478bd9Sstevel@tonic-gate mutex_exit(&mvp->v_lock); 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate if (error = pn_get(uap->dir, UIO_USERSPACE, &dpn)) { 2107c478bd9Sstevel@tonic-gate return (error); 2117c478bd9Sstevel@tonic-gate } 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate /* 21493239addSjohnlev * Resolve path name of the file being mounted. 2157c478bd9Sstevel@tonic-gate */ 2167c478bd9Sstevel@tonic-gate if (error = lookupname(uap->spec, UIO_USERSPACE, FOLLOW, NULLVPP, 21793239addSjohnlev &svp)) { 2187c478bd9Sstevel@tonic-gate pn_free(&dpn); 2197c478bd9Sstevel@tonic-gate return (error); 2207c478bd9Sstevel@tonic-gate } 22193239addSjohnlev 22293239addSjohnlev error = vfs_get_lofi(vfsp, &lvp); 22393239addSjohnlev 22493239addSjohnlev if (error > 0) { 22593239addSjohnlev if (error == ENOENT) 22693239addSjohnlev error = ENODEV; 22793239addSjohnlev goto out; 22893239addSjohnlev } else if (error == 0) { 22993239addSjohnlev dev = lvp->v_rdev; 23093239addSjohnlev } else { 23193239addSjohnlev dev = svp->v_rdev; 23293239addSjohnlev 23393239addSjohnlev if (svp->v_type != VBLK) { 2347c478bd9Sstevel@tonic-gate error = ENOTBLK; 2357c478bd9Sstevel@tonic-gate goto out; 2367c478bd9Sstevel@tonic-gate } 23793239addSjohnlev } 2387c478bd9Sstevel@tonic-gate 2397c478bd9Sstevel@tonic-gate /* 2407c478bd9Sstevel@tonic-gate * Ensure that this device isn't already mounted, 2417c478bd9Sstevel@tonic-gate * unless this is a REMOUNT request 2427c478bd9Sstevel@tonic-gate */ 2437c478bd9Sstevel@tonic-gate if (vfs_devmounting(dev, vfsp)) { 2447c478bd9Sstevel@tonic-gate error = EBUSY; 2457c478bd9Sstevel@tonic-gate goto out; 2467c478bd9Sstevel@tonic-gate } 2477c478bd9Sstevel@tonic-gate if (vfs_devismounted(dev)) { 2487c478bd9Sstevel@tonic-gate if (uap->flags & MS_REMOUNT) { 2497c478bd9Sstevel@tonic-gate why = ROOT_REMOUNT; 2507c478bd9Sstevel@tonic-gate } else { 2517c478bd9Sstevel@tonic-gate error = EBUSY; 2527c478bd9Sstevel@tonic-gate goto out; 2537c478bd9Sstevel@tonic-gate } 2547c478bd9Sstevel@tonic-gate } else { 2557c478bd9Sstevel@tonic-gate why = ROOT_INIT; 2567c478bd9Sstevel@tonic-gate } 2577c478bd9Sstevel@tonic-gate if (getmajor(dev) >= devcnt) { 2587c478bd9Sstevel@tonic-gate error = ENXIO; 2597c478bd9Sstevel@tonic-gate goto out; 2607c478bd9Sstevel@tonic-gate } 2617c478bd9Sstevel@tonic-gate 2627c478bd9Sstevel@tonic-gate /* 2637c478bd9Sstevel@tonic-gate * If the device is a tape, mount it read only 2647c478bd9Sstevel@tonic-gate */ 2657c478bd9Sstevel@tonic-gate if (devopsp[getmajor(dev)]->devo_cb_ops->cb_flag & D_TAPE) { 2667c478bd9Sstevel@tonic-gate vfsp->vfs_flag |= VFS_RDONLY; 2677c478bd9Sstevel@tonic-gate } 2687c478bd9Sstevel@tonic-gate 2697c478bd9Sstevel@tonic-gate if (uap->flags & MS_RDONLY) { 2707c478bd9Sstevel@tonic-gate vfsp->vfs_flag |= VFS_RDONLY; 2717c478bd9Sstevel@tonic-gate } 2727c478bd9Sstevel@tonic-gate 2737c478bd9Sstevel@tonic-gate /* 2747c478bd9Sstevel@tonic-gate * Set mount options. 2757c478bd9Sstevel@tonic-gate */ 2767c478bd9Sstevel@tonic-gate if (uap->flags & MS_RDONLY) { 2777c478bd9Sstevel@tonic-gate vfs_setmntopt(vfsp, MNTOPT_RO, NULL, 0); 2787c478bd9Sstevel@tonic-gate } 2797c478bd9Sstevel@tonic-gate if (uap->flags & MS_NOSUID) { 2807c478bd9Sstevel@tonic-gate vfs_setmntopt(vfsp, MNTOPT_NOSUID, NULL, 0); 2817c478bd9Sstevel@tonic-gate } 2827c478bd9Sstevel@tonic-gate 2837c478bd9Sstevel@tonic-gate /* 2847c478bd9Sstevel@tonic-gate * Verify that the caller can open the device special file as 2857c478bd9Sstevel@tonic-gate * required. It is not until this moment that we know whether 2867c478bd9Sstevel@tonic-gate * we're mounting "ro" or not. 2877c478bd9Sstevel@tonic-gate */ 2887c478bd9Sstevel@tonic-gate if ((vfsp->vfs_flag & VFS_RDONLY) != 0) { 2897c478bd9Sstevel@tonic-gate oflag = FREAD; 2907c478bd9Sstevel@tonic-gate aflag = VREAD; 2917c478bd9Sstevel@tonic-gate } else { 2927c478bd9Sstevel@tonic-gate oflag = FREAD | FWRITE; 2937c478bd9Sstevel@tonic-gate aflag = VREAD | VWRITE; 2947c478bd9Sstevel@tonic-gate } 29593239addSjohnlev 29693239addSjohnlev if (lvp == NULL && 29793239addSjohnlev (error = secpolicy_spec_open(cr, svp, oflag)) != 0) 2987c478bd9Sstevel@tonic-gate goto out; 29993239addSjohnlev 30093239addSjohnlev if ((error = VOP_ACCESS(svp, aflag, 0, cr, NULL)) != 0) 30193239addSjohnlev goto out; 3027c478bd9Sstevel@tonic-gate 3037c478bd9Sstevel@tonic-gate /* 3047c478bd9Sstevel@tonic-gate * Mount the filesystem. 3057c478bd9Sstevel@tonic-gate */ 3067c478bd9Sstevel@tonic-gate error = ud_mountfs(vfsp, why, dev, dpn.pn_path, cr, 0); 3077c478bd9Sstevel@tonic-gate out: 30893239addSjohnlev VN_RELE(svp); 30993239addSjohnlev if (lvp != NULL) 31093239addSjohnlev VN_RELE(lvp); 3117c478bd9Sstevel@tonic-gate pn_free(&dpn); 3127c478bd9Sstevel@tonic-gate return (error); 3137c478bd9Sstevel@tonic-gate } 3147c478bd9Sstevel@tonic-gate 3157c478bd9Sstevel@tonic-gate 3167c478bd9Sstevel@tonic-gate 3177c478bd9Sstevel@tonic-gate /* 3187c478bd9Sstevel@tonic-gate * unmount the file system pointed 3197c478bd9Sstevel@tonic-gate * by vfsp 3207c478bd9Sstevel@tonic-gate */ 3217c478bd9Sstevel@tonic-gate /* ARGSUSED */ 3227c478bd9Sstevel@tonic-gate static int32_t 3237c478bd9Sstevel@tonic-gate udf_unmount(struct vfs *vfsp, int fflag, struct cred *cr) 3247c478bd9Sstevel@tonic-gate { 3257c478bd9Sstevel@tonic-gate struct udf_vfs *udf_vfsp; 3267c478bd9Sstevel@tonic-gate struct vnode *bvp, *rvp; 3277c478bd9Sstevel@tonic-gate struct ud_inode *rip; 3287c478bd9Sstevel@tonic-gate int32_t flag; 3297c478bd9Sstevel@tonic-gate 3307c478bd9Sstevel@tonic-gate ud_printf("udf_unmount\n"); 3317c478bd9Sstevel@tonic-gate 3327c478bd9Sstevel@tonic-gate if (secpolicy_fs_unmount(cr, vfsp) != 0) { 3337c478bd9Sstevel@tonic-gate return (EPERM); 3347c478bd9Sstevel@tonic-gate } 3357c478bd9Sstevel@tonic-gate 3367c478bd9Sstevel@tonic-gate /* 3377c478bd9Sstevel@tonic-gate * forced unmount is not supported by this file system 3387c478bd9Sstevel@tonic-gate * and thus, ENOTSUP, is being returned. 3397c478bd9Sstevel@tonic-gate */ 3407c478bd9Sstevel@tonic-gate if (fflag & MS_FORCE) 3417c478bd9Sstevel@tonic-gate return (ENOTSUP); 3427c478bd9Sstevel@tonic-gate 3437c478bd9Sstevel@tonic-gate udf_vfsp = (struct udf_vfs *)vfsp->vfs_data; 3447c478bd9Sstevel@tonic-gate flag = !(udf_vfsp->udf_flags & UDF_FL_RDONLY); 3457c478bd9Sstevel@tonic-gate bvp = udf_vfsp->udf_devvp; 3467c478bd9Sstevel@tonic-gate 3477c478bd9Sstevel@tonic-gate rvp = udf_vfsp->udf_root; 3487c478bd9Sstevel@tonic-gate ASSERT(rvp != NULL); 3497c478bd9Sstevel@tonic-gate rip = VTOI(rvp); 3507c478bd9Sstevel@tonic-gate 3517c478bd9Sstevel@tonic-gate (void) ud_release_cache(udf_vfsp); 3527c478bd9Sstevel@tonic-gate 3537c478bd9Sstevel@tonic-gate 3547c478bd9Sstevel@tonic-gate /* Flush all inodes except root */ 3557c478bd9Sstevel@tonic-gate if (ud_iflush(vfsp) < 0) { 3567c478bd9Sstevel@tonic-gate return (EBUSY); 3577c478bd9Sstevel@tonic-gate } 3587c478bd9Sstevel@tonic-gate 3597c478bd9Sstevel@tonic-gate rw_enter(&rip->i_contents, RW_WRITER); 3607c478bd9Sstevel@tonic-gate (void) ud_syncip(rip, B_INVAL, I_SYNC); 3617c478bd9Sstevel@tonic-gate rw_exit(&rip->i_contents); 3627c478bd9Sstevel@tonic-gate 3637c478bd9Sstevel@tonic-gate mutex_enter(&ud_sync_busy); 3647c478bd9Sstevel@tonic-gate if ((udf_vfsp->udf_flags & UDF_FL_RDONLY) == 0) { 3657c478bd9Sstevel@tonic-gate bflush(vfsp->vfs_dev); 3667c478bd9Sstevel@tonic-gate mutex_enter(&udf_vfsp->udf_lock); 3677c478bd9Sstevel@tonic-gate udf_vfsp->udf_clean = UDF_CLEAN; 3687c478bd9Sstevel@tonic-gate mutex_exit(&udf_vfsp->udf_lock); 3697c478bd9Sstevel@tonic-gate ud_update_superblock(vfsp); 3707c478bd9Sstevel@tonic-gate } 3717c478bd9Sstevel@tonic-gate mutex_exit(&ud_sync_busy); 3727c478bd9Sstevel@tonic-gate 3737c478bd9Sstevel@tonic-gate mutex_destroy(&udf_vfsp->udf_lock); 3747c478bd9Sstevel@tonic-gate mutex_destroy(&udf_vfsp->udf_rename_lck); 3757c478bd9Sstevel@tonic-gate 3767c478bd9Sstevel@tonic-gate ud_delcache(rip); 3777c478bd9Sstevel@tonic-gate ITIMES(rip); 3787c478bd9Sstevel@tonic-gate VN_RELE(rvp); 3797c478bd9Sstevel@tonic-gate 3807c478bd9Sstevel@tonic-gate ud_destroy_fsp(udf_vfsp); 3817c478bd9Sstevel@tonic-gate 382da6c28aaSamw (void) VOP_PUTPAGE(bvp, (offset_t)0, (uint32_t)0, B_INVAL, cr, NULL); 383da6c28aaSamw (void) VOP_CLOSE(bvp, flag, 1, (offset_t)0, cr, NULL); 3847c478bd9Sstevel@tonic-gate 3857c478bd9Sstevel@tonic-gate (void) bfinval(vfsp->vfs_dev, 1); 3867c478bd9Sstevel@tonic-gate VN_RELE(bvp); 3877c478bd9Sstevel@tonic-gate 3887c478bd9Sstevel@tonic-gate 3897c478bd9Sstevel@tonic-gate return (0); 3907c478bd9Sstevel@tonic-gate } 3917c478bd9Sstevel@tonic-gate 3927c478bd9Sstevel@tonic-gate 3937c478bd9Sstevel@tonic-gate /* 3947c478bd9Sstevel@tonic-gate * Get the root vp for the 3957c478bd9Sstevel@tonic-gate * file system 3967c478bd9Sstevel@tonic-gate */ 3977c478bd9Sstevel@tonic-gate static int32_t 3987c478bd9Sstevel@tonic-gate udf_root(struct vfs *vfsp, struct vnode **vpp) 3997c478bd9Sstevel@tonic-gate { 4007c478bd9Sstevel@tonic-gate struct udf_vfs *udf_vfsp; 4017c478bd9Sstevel@tonic-gate struct vnode *vp; 4027c478bd9Sstevel@tonic-gate 4037c478bd9Sstevel@tonic-gate ud_printf("udf_root\n"); 4047c478bd9Sstevel@tonic-gate 4057c478bd9Sstevel@tonic-gate udf_vfsp = (struct udf_vfs *)vfsp->vfs_data; 4067c478bd9Sstevel@tonic-gate 4077c478bd9Sstevel@tonic-gate ASSERT(udf_vfsp != NULL); 4087c478bd9Sstevel@tonic-gate ASSERT(udf_vfsp->udf_root != NULL); 4097c478bd9Sstevel@tonic-gate 4107c478bd9Sstevel@tonic-gate vp = udf_vfsp->udf_root; 4117c478bd9Sstevel@tonic-gate VN_HOLD(vp); 4127c478bd9Sstevel@tonic-gate *vpp = vp; 4137c478bd9Sstevel@tonic-gate return (0); 4147c478bd9Sstevel@tonic-gate } 4157c478bd9Sstevel@tonic-gate 4167c478bd9Sstevel@tonic-gate 4177c478bd9Sstevel@tonic-gate /* 4187c478bd9Sstevel@tonic-gate * Get file system statistics. 4197c478bd9Sstevel@tonic-gate */ 4207c478bd9Sstevel@tonic-gate static int32_t 4217c478bd9Sstevel@tonic-gate udf_statvfs(struct vfs *vfsp, struct statvfs64 *sp) 4227c478bd9Sstevel@tonic-gate { 4237c478bd9Sstevel@tonic-gate struct udf_vfs *udf_vfsp; 4247c478bd9Sstevel@tonic-gate struct ud_part *parts; 4257c478bd9Sstevel@tonic-gate dev32_t d32; 4267c478bd9Sstevel@tonic-gate int32_t index; 4277c478bd9Sstevel@tonic-gate 4287c478bd9Sstevel@tonic-gate ud_printf("udf_statvfs\n"); 4297c478bd9Sstevel@tonic-gate 4307c478bd9Sstevel@tonic-gate udf_vfsp = (struct udf_vfs *)vfsp->vfs_data; 4317c478bd9Sstevel@tonic-gate (void) bzero(sp, sizeof (struct statvfs64)); 4327c478bd9Sstevel@tonic-gate 4337c478bd9Sstevel@tonic-gate mutex_enter(&udf_vfsp->udf_lock); 4347c478bd9Sstevel@tonic-gate sp->f_bsize = udf_vfsp->udf_lbsize; 4357c478bd9Sstevel@tonic-gate sp->f_frsize = udf_vfsp->udf_lbsize; 4367c478bd9Sstevel@tonic-gate sp->f_blocks = 0; 4377c478bd9Sstevel@tonic-gate sp->f_bfree = 0; 4387c478bd9Sstevel@tonic-gate parts = udf_vfsp->udf_parts; 4397c478bd9Sstevel@tonic-gate for (index = 0; index < udf_vfsp->udf_npart; index++) { 4407c478bd9Sstevel@tonic-gate sp->f_blocks += parts->udp_nblocks; 4417c478bd9Sstevel@tonic-gate sp->f_bfree += parts->udp_nfree; 4427c478bd9Sstevel@tonic-gate parts++; 4437c478bd9Sstevel@tonic-gate } 4447c478bd9Sstevel@tonic-gate sp->f_bavail = sp->f_bfree; 4457c478bd9Sstevel@tonic-gate 4467c478bd9Sstevel@tonic-gate /* 4477c478bd9Sstevel@tonic-gate * Since there are no real inodes allocated 4487c478bd9Sstevel@tonic-gate * we will approximate 4497c478bd9Sstevel@tonic-gate * each new file will occupy : 4507c478bd9Sstevel@tonic-gate * 38(over head each dent) + MAXNAMLEN / 2 + inode_size(==block size) 4517c478bd9Sstevel@tonic-gate */ 4527c478bd9Sstevel@tonic-gate sp->f_ffree = sp->f_favail = 4537c478bd9Sstevel@tonic-gate (sp->f_bavail * sp->f_bsize) / (146 + sp->f_bsize); 4547c478bd9Sstevel@tonic-gate 4557c478bd9Sstevel@tonic-gate /* 4567c478bd9Sstevel@tonic-gate * The total number of inodes is 4577c478bd9Sstevel@tonic-gate * the sum of files + directories + free inodes 4587c478bd9Sstevel@tonic-gate */ 45993239addSjohnlev sp->f_files = sp->f_ffree + udf_vfsp->udf_nfiles + udf_vfsp->udf_ndirs; 4607c478bd9Sstevel@tonic-gate (void) cmpldev(&d32, vfsp->vfs_dev); 4617c478bd9Sstevel@tonic-gate sp->f_fsid = d32; 4627c478bd9Sstevel@tonic-gate (void) strcpy(sp->f_basetype, vfssw[vfsp->vfs_fstype].vsw_name); 4637c478bd9Sstevel@tonic-gate sp->f_flag = vf_to_stf(vfsp->vfs_flag); 4647c478bd9Sstevel@tonic-gate sp->f_namemax = MAXNAMLEN; 4657c478bd9Sstevel@tonic-gate (void) strcpy(sp->f_fstr, udf_vfsp->udf_volid); 4667c478bd9Sstevel@tonic-gate 4677c478bd9Sstevel@tonic-gate mutex_exit(&udf_vfsp->udf_lock); 4687c478bd9Sstevel@tonic-gate 4697c478bd9Sstevel@tonic-gate return (0); 4707c478bd9Sstevel@tonic-gate } 4717c478bd9Sstevel@tonic-gate 4727c478bd9Sstevel@tonic-gate 4737c478bd9Sstevel@tonic-gate /* 4747c478bd9Sstevel@tonic-gate * Flush any pending I/O to file system vfsp. 4757c478bd9Sstevel@tonic-gate * The ud_update() routine will only flush *all* udf files. 4767c478bd9Sstevel@tonic-gate */ 4777c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 4787c478bd9Sstevel@tonic-gate /* ARGSUSED */ 4797c478bd9Sstevel@tonic-gate static int32_t 4807c478bd9Sstevel@tonic-gate udf_sync(struct vfs *vfsp, int16_t flag, struct cred *cr) 4817c478bd9Sstevel@tonic-gate { 4827c478bd9Sstevel@tonic-gate ud_printf("udf_sync\n"); 4837c478bd9Sstevel@tonic-gate 4847c478bd9Sstevel@tonic-gate ud_update(flag); 4857c478bd9Sstevel@tonic-gate return (0); 4867c478bd9Sstevel@tonic-gate } 4877c478bd9Sstevel@tonic-gate 4887c478bd9Sstevel@tonic-gate 4897c478bd9Sstevel@tonic-gate 4907c478bd9Sstevel@tonic-gate /* ARGSUSED */ 4917c478bd9Sstevel@tonic-gate static int32_t 4927c478bd9Sstevel@tonic-gate udf_vget(struct vfs *vfsp, 4937c478bd9Sstevel@tonic-gate struct vnode **vpp, struct fid *fidp) 4947c478bd9Sstevel@tonic-gate { 4957c478bd9Sstevel@tonic-gate int32_t error = 0; 4967c478bd9Sstevel@tonic-gate struct udf_fid *udfid; 4977c478bd9Sstevel@tonic-gate struct udf_vfs *udf_vfsp; 4987c478bd9Sstevel@tonic-gate struct ud_inode *ip; 4997c478bd9Sstevel@tonic-gate 5007c478bd9Sstevel@tonic-gate ud_printf("udf_vget\n"); 5017c478bd9Sstevel@tonic-gate 5027c478bd9Sstevel@tonic-gate udf_vfsp = (struct udf_vfs *)vfsp->vfs_data; 5037c478bd9Sstevel@tonic-gate if (udf_vfsp == NULL) { 5047c478bd9Sstevel@tonic-gate *vpp = NULL; 5057c478bd9Sstevel@tonic-gate return (0); 5067c478bd9Sstevel@tonic-gate } 5077c478bd9Sstevel@tonic-gate 5087c478bd9Sstevel@tonic-gate udfid = (struct udf_fid *)fidp; 5097c478bd9Sstevel@tonic-gate if ((error = ud_iget(vfsp, udfid->udfid_prn, 5107c478bd9Sstevel@tonic-gate udfid->udfid_icb_lbn, &ip, NULL, CRED())) != 0) { 5117c478bd9Sstevel@tonic-gate *vpp = NULL; 5127c478bd9Sstevel@tonic-gate return (error); 5137c478bd9Sstevel@tonic-gate } 5147c478bd9Sstevel@tonic-gate 5157c478bd9Sstevel@tonic-gate rw_enter(&ip->i_contents, RW_READER); 5167c478bd9Sstevel@tonic-gate if ((udfid->udfid_uinq_lo != (ip->i_uniqid & 0xffffffff)) || 5177c478bd9Sstevel@tonic-gate (udfid->udfid_prn != ip->i_icb_prn)) { 5187c478bd9Sstevel@tonic-gate rw_exit(&ip->i_contents); 5197c478bd9Sstevel@tonic-gate VN_RELE(ITOV(ip)); 5207c478bd9Sstevel@tonic-gate *vpp = NULL; 5217c478bd9Sstevel@tonic-gate return (EINVAL); 5227c478bd9Sstevel@tonic-gate } 5237c478bd9Sstevel@tonic-gate rw_exit(&ip->i_contents); 5247c478bd9Sstevel@tonic-gate 5257c478bd9Sstevel@tonic-gate *vpp = ITOV(ip); 5267c478bd9Sstevel@tonic-gate return (0); 5277c478bd9Sstevel@tonic-gate } 5287c478bd9Sstevel@tonic-gate 5297c478bd9Sstevel@tonic-gate 5307c478bd9Sstevel@tonic-gate /* 5317c478bd9Sstevel@tonic-gate * Mount root file system. 5327c478bd9Sstevel@tonic-gate * "why" is ROOT_INIT on initial call, ROOT_REMOUNT if called to 5337c478bd9Sstevel@tonic-gate * remount the root file system, and ROOT_UNMOUNT if called to 5347c478bd9Sstevel@tonic-gate * unmount the root (e.g., as part of a system shutdown). 5357c478bd9Sstevel@tonic-gate * 5367c478bd9Sstevel@tonic-gate * XXX - this may be partially machine-dependent; it, along with the VFS_SWAPVP 5377c478bd9Sstevel@tonic-gate * operation, goes along with auto-configuration. A mechanism should be 5387c478bd9Sstevel@tonic-gate * provided by which machine-INdependent code in the kernel can say "get me the 5397c478bd9Sstevel@tonic-gate * right root file system" and "get me the right initial swap area", and have 5407c478bd9Sstevel@tonic-gate * that done in what may well be a machine-dependent fashion. 5417c478bd9Sstevel@tonic-gate * Unfortunately, it is also file-system-type dependent (NFS gets it via 5427c478bd9Sstevel@tonic-gate * bootparams calls, UFS gets it from various and sundry machine-dependent 5437c478bd9Sstevel@tonic-gate * mechanisms, as SPECFS does for swap). 5447c478bd9Sstevel@tonic-gate */ 5457c478bd9Sstevel@tonic-gate /* ARGSUSED */ 5467c478bd9Sstevel@tonic-gate static int32_t 5477c478bd9Sstevel@tonic-gate udf_mountroot(struct vfs *vfsp, enum whymountroot why) 5487c478bd9Sstevel@tonic-gate { 5497c478bd9Sstevel@tonic-gate dev_t rootdev; 5507c478bd9Sstevel@tonic-gate static int32_t udf_rootdone = 0; 5517c478bd9Sstevel@tonic-gate struct vnode *vp = NULL; 5527c478bd9Sstevel@tonic-gate int32_t ovflags, error; 5537c478bd9Sstevel@tonic-gate ud_printf("udf_mountroot\n"); 5547c478bd9Sstevel@tonic-gate 5557c478bd9Sstevel@tonic-gate if (why == ROOT_INIT) { 5567c478bd9Sstevel@tonic-gate if (udf_rootdone++) { 5577c478bd9Sstevel@tonic-gate return (EBUSY); 5587c478bd9Sstevel@tonic-gate } 5597c478bd9Sstevel@tonic-gate rootdev = getrootdev(); 5607c478bd9Sstevel@tonic-gate if (rootdev == (dev_t)NODEV) { 5617c478bd9Sstevel@tonic-gate return (ENODEV); 5627c478bd9Sstevel@tonic-gate } 5637c478bd9Sstevel@tonic-gate vfsp->vfs_dev = rootdev; 5647c478bd9Sstevel@tonic-gate vfsp->vfs_flag |= VFS_RDONLY; 5657c478bd9Sstevel@tonic-gate } else if (why == ROOT_REMOUNT) { 5667c478bd9Sstevel@tonic-gate vp = ((struct udf_vfs *)vfsp->vfs_data)->udf_devvp; 5677c478bd9Sstevel@tonic-gate (void) dnlc_purge_vfsp(vfsp, 0); 5687c478bd9Sstevel@tonic-gate vp = common_specvp(vp); 5697c478bd9Sstevel@tonic-gate (void) VOP_PUTPAGE(vp, (offset_t)0, 570da6c28aaSamw (uint32_t)0, B_INVAL, CRED(), NULL); 5717c478bd9Sstevel@tonic-gate binval(vfsp->vfs_dev); 5727c478bd9Sstevel@tonic-gate 5737c478bd9Sstevel@tonic-gate ovflags = vfsp->vfs_flag; 5747c478bd9Sstevel@tonic-gate vfsp->vfs_flag &= ~VFS_RDONLY; 5757c478bd9Sstevel@tonic-gate vfsp->vfs_flag |= VFS_REMOUNT; 5767c478bd9Sstevel@tonic-gate rootdev = vfsp->vfs_dev; 5777c478bd9Sstevel@tonic-gate } else if (why == ROOT_UNMOUNT) { 5787c478bd9Sstevel@tonic-gate ud_update(0); 5797c478bd9Sstevel@tonic-gate vp = ((struct udf_vfs *)vfsp->vfs_data)->udf_devvp; 5807c478bd9Sstevel@tonic-gate (void) VOP_CLOSE(vp, FREAD|FWRITE, 1, 581da6c28aaSamw (offset_t)0, CRED(), NULL); 5827c478bd9Sstevel@tonic-gate return (0); 5837c478bd9Sstevel@tonic-gate } 5847c478bd9Sstevel@tonic-gate 5857c478bd9Sstevel@tonic-gate if ((error = vfs_lock(vfsp)) != 0) { 5867c478bd9Sstevel@tonic-gate return (error); 5877c478bd9Sstevel@tonic-gate } 5887c478bd9Sstevel@tonic-gate 5897c478bd9Sstevel@tonic-gate error = ud_mountfs(vfsp, why, rootdev, "/", CRED(), 1); 5907c478bd9Sstevel@tonic-gate if (error) { 5917c478bd9Sstevel@tonic-gate vfs_unlock(vfsp); 5927c478bd9Sstevel@tonic-gate if (why == ROOT_REMOUNT) { 5937c478bd9Sstevel@tonic-gate vfsp->vfs_flag = ovflags; 5947c478bd9Sstevel@tonic-gate } 5957c478bd9Sstevel@tonic-gate if (rootvp) { 5967c478bd9Sstevel@tonic-gate VN_RELE(rootvp); 5977c478bd9Sstevel@tonic-gate rootvp = (struct vnode *)0; 5987c478bd9Sstevel@tonic-gate } 5997c478bd9Sstevel@tonic-gate return (error); 6007c478bd9Sstevel@tonic-gate } 6017c478bd9Sstevel@tonic-gate 6027c478bd9Sstevel@tonic-gate if (why == ROOT_INIT) { 6037c478bd9Sstevel@tonic-gate vfs_add((struct vnode *)0, vfsp, 6047c478bd9Sstevel@tonic-gate (vfsp->vfs_flag & VFS_RDONLY) ? MS_RDONLY : 0); 6057c478bd9Sstevel@tonic-gate } 6067c478bd9Sstevel@tonic-gate vfs_unlock(vfsp); 6077c478bd9Sstevel@tonic-gate return (0); 6087c478bd9Sstevel@tonic-gate } 6097c478bd9Sstevel@tonic-gate 6107c478bd9Sstevel@tonic-gate 6117c478bd9Sstevel@tonic-gate /* ------------------------- local routines ------------------------- */ 6127c478bd9Sstevel@tonic-gate 6137c478bd9Sstevel@tonic-gate 6147c478bd9Sstevel@tonic-gate static int32_t 6157c478bd9Sstevel@tonic-gate ud_mountfs(struct vfs *vfsp, 6167c478bd9Sstevel@tonic-gate enum whymountroot why, dev_t dev, char *name, 6177c478bd9Sstevel@tonic-gate struct cred *cr, int32_t isroot) 6187c478bd9Sstevel@tonic-gate { 6197c478bd9Sstevel@tonic-gate struct vnode *devvp = NULL; 6207c478bd9Sstevel@tonic-gate int32_t error = 0; 6217c478bd9Sstevel@tonic-gate int32_t needclose = 0; 6227c478bd9Sstevel@tonic-gate struct udf_vfs *udf_vfsp = NULL; 6237c478bd9Sstevel@tonic-gate struct log_vol_int_desc *lvid; 6247c478bd9Sstevel@tonic-gate struct ud_inode *rip = NULL; 6257c478bd9Sstevel@tonic-gate struct vnode *rvp = NULL; 6267c478bd9Sstevel@tonic-gate int32_t i, lbsize; 6277c478bd9Sstevel@tonic-gate uint32_t avd_loc; 6287c478bd9Sstevel@tonic-gate struct ud_map *map; 6297c478bd9Sstevel@tonic-gate int32_t desc_len; 6307c478bd9Sstevel@tonic-gate 6317c478bd9Sstevel@tonic-gate ud_printf("ud_mountfs\n"); 6327c478bd9Sstevel@tonic-gate 6337c478bd9Sstevel@tonic-gate if (why == ROOT_INIT) { 6347c478bd9Sstevel@tonic-gate /* 6357c478bd9Sstevel@tonic-gate * Open the device. 6367c478bd9Sstevel@tonic-gate */ 6377c478bd9Sstevel@tonic-gate devvp = makespecvp(dev, VBLK); 6387c478bd9Sstevel@tonic-gate 6397c478bd9Sstevel@tonic-gate /* 6407c478bd9Sstevel@tonic-gate * Open block device mounted on. 6417c478bd9Sstevel@tonic-gate * When bio is fixed for vnodes this can all be vnode 6427c478bd9Sstevel@tonic-gate * operations. 6437c478bd9Sstevel@tonic-gate */ 6447c478bd9Sstevel@tonic-gate error = VOP_OPEN(&devvp, 645da6c28aaSamw (vfsp->vfs_flag & VFS_RDONLY) ? FREAD : FREAD|FWRITE, 646da6c28aaSamw cr, NULL); 6477c478bd9Sstevel@tonic-gate if (error) { 6487c478bd9Sstevel@tonic-gate goto out; 6497c478bd9Sstevel@tonic-gate } 6507c478bd9Sstevel@tonic-gate needclose = 1; 6517c478bd9Sstevel@tonic-gate 6527c478bd9Sstevel@tonic-gate /* 6537c478bd9Sstevel@tonic-gate * Refuse to go any further if this 6547c478bd9Sstevel@tonic-gate * device is being used for swapping. 6557c478bd9Sstevel@tonic-gate */ 6567c478bd9Sstevel@tonic-gate if (IS_SWAPVP(devvp)) { 6577c478bd9Sstevel@tonic-gate error = EBUSY; 6587c478bd9Sstevel@tonic-gate goto out; 6597c478bd9Sstevel@tonic-gate } 6607c478bd9Sstevel@tonic-gate } 6617c478bd9Sstevel@tonic-gate 6627c478bd9Sstevel@tonic-gate /* 6637c478bd9Sstevel@tonic-gate * check for dev already mounted on 6647c478bd9Sstevel@tonic-gate */ 6657c478bd9Sstevel@tonic-gate if (vfsp->vfs_flag & VFS_REMOUNT) { 6667c478bd9Sstevel@tonic-gate struct tag *ttag; 6677c478bd9Sstevel@tonic-gate int32_t index, count; 6687c478bd9Sstevel@tonic-gate struct buf *tpt = 0; 6697c478bd9Sstevel@tonic-gate caddr_t addr; 6707c478bd9Sstevel@tonic-gate 6717c478bd9Sstevel@tonic-gate 6727c478bd9Sstevel@tonic-gate /* cannot remount to RDONLY */ 6737c478bd9Sstevel@tonic-gate if (vfsp->vfs_flag & VFS_RDONLY) { 6747c478bd9Sstevel@tonic-gate return (EINVAL); 6757c478bd9Sstevel@tonic-gate } 6767c478bd9Sstevel@tonic-gate 6777c478bd9Sstevel@tonic-gate if (vfsp->vfs_dev != dev) { 6787c478bd9Sstevel@tonic-gate return (EINVAL); 6797c478bd9Sstevel@tonic-gate } 6807c478bd9Sstevel@tonic-gate 6817c478bd9Sstevel@tonic-gate udf_vfsp = (struct udf_vfs *)vfsp->vfs_data; 6827c478bd9Sstevel@tonic-gate devvp = udf_vfsp->udf_devvp; 6837c478bd9Sstevel@tonic-gate 6847c478bd9Sstevel@tonic-gate /* 6857c478bd9Sstevel@tonic-gate * fsck may have altered the file system; discard 6867c478bd9Sstevel@tonic-gate * as much incore data as possible. Don't flush 6877c478bd9Sstevel@tonic-gate * if this is a rw to rw remount; it's just resetting 6887c478bd9Sstevel@tonic-gate * the options. 6897c478bd9Sstevel@tonic-gate */ 6907c478bd9Sstevel@tonic-gate if (udf_vfsp->udf_flags & UDF_FL_RDONLY) { 6917c478bd9Sstevel@tonic-gate (void) dnlc_purge_vfsp(vfsp, 0); 6927c478bd9Sstevel@tonic-gate (void) VOP_PUTPAGE(devvp, (offset_t)0, (uint_t)0, 693da6c28aaSamw B_INVAL, CRED(), NULL); 6947c478bd9Sstevel@tonic-gate (void) ud_iflush(vfsp); 6957c478bd9Sstevel@tonic-gate bflush(dev); 6967c478bd9Sstevel@tonic-gate binval(dev); 6977c478bd9Sstevel@tonic-gate } 6987c478bd9Sstevel@tonic-gate 6997c478bd9Sstevel@tonic-gate /* 7007c478bd9Sstevel@tonic-gate * We could read UDF1.50 and write UDF1.50 only 7017c478bd9Sstevel@tonic-gate * disallow mount of any highier version 7027c478bd9Sstevel@tonic-gate */ 7037c478bd9Sstevel@tonic-gate if ((udf_vfsp->udf_miread > UDF_150) || 7047c478bd9Sstevel@tonic-gate (udf_vfsp->udf_miwrite > UDF_150)) { 7057c478bd9Sstevel@tonic-gate error = EINVAL; 7067c478bd9Sstevel@tonic-gate goto remountout; 7077c478bd9Sstevel@tonic-gate } 7087c478bd9Sstevel@tonic-gate 7097c478bd9Sstevel@tonic-gate /* 7107c478bd9Sstevel@tonic-gate * read/write to read/write; all done 7117c478bd9Sstevel@tonic-gate */ 7127c478bd9Sstevel@tonic-gate if (udf_vfsp->udf_flags & UDF_FL_RW) { 7137c478bd9Sstevel@tonic-gate goto remountout; 7147c478bd9Sstevel@tonic-gate } 7157c478bd9Sstevel@tonic-gate 7167c478bd9Sstevel@tonic-gate /* 7177c478bd9Sstevel@tonic-gate * Does the media type allow a writable mount 7187c478bd9Sstevel@tonic-gate */ 7197c478bd9Sstevel@tonic-gate if (udf_vfsp->udf_mtype != UDF_MT_OW) { 7207c478bd9Sstevel@tonic-gate error = EINVAL; 7217c478bd9Sstevel@tonic-gate goto remountout; 7227c478bd9Sstevel@tonic-gate } 7237c478bd9Sstevel@tonic-gate 7247c478bd9Sstevel@tonic-gate /* 7257c478bd9Sstevel@tonic-gate * Read the metadata 7267c478bd9Sstevel@tonic-gate * and check if it is possible to 7277c478bd9Sstevel@tonic-gate * mount in rw mode 7287c478bd9Sstevel@tonic-gate */ 7297c478bd9Sstevel@tonic-gate tpt = ud_bread(vfsp->vfs_dev, 7307c478bd9Sstevel@tonic-gate udf_vfsp->udf_iseq_loc << udf_vfsp->udf_l2d_shift, 7317c478bd9Sstevel@tonic-gate udf_vfsp->udf_iseq_len); 7327c478bd9Sstevel@tonic-gate if (tpt->b_flags & B_ERROR) { 7337c478bd9Sstevel@tonic-gate error = EIO; 7347c478bd9Sstevel@tonic-gate goto remountout; 7357c478bd9Sstevel@tonic-gate } 7367c478bd9Sstevel@tonic-gate count = udf_vfsp->udf_iseq_len / DEV_BSIZE; 7377c478bd9Sstevel@tonic-gate addr = tpt->b_un.b_addr; 7387c478bd9Sstevel@tonic-gate for (index = 0; index < count; index ++) { 7397c478bd9Sstevel@tonic-gate ttag = (struct tag *)(addr + index * DEV_BSIZE); 7407c478bd9Sstevel@tonic-gate desc_len = udf_vfsp->udf_iseq_len - (index * DEV_BSIZE); 7417c478bd9Sstevel@tonic-gate if (ud_verify_tag_and_desc(ttag, UD_LOG_VOL_INT, 7427c478bd9Sstevel@tonic-gate udf_vfsp->udf_iseq_loc + 7437c478bd9Sstevel@tonic-gate (index >> udf_vfsp->udf_l2d_shift), 7447c478bd9Sstevel@tonic-gate 1, desc_len) == 0) { 7457c478bd9Sstevel@tonic-gate struct log_vol_int_desc *lvid; 7467c478bd9Sstevel@tonic-gate 7477c478bd9Sstevel@tonic-gate lvid = (struct log_vol_int_desc *)ttag; 7487c478bd9Sstevel@tonic-gate 7497c478bd9Sstevel@tonic-gate if (SWAP_32(lvid->lvid_int_type) != 7507c478bd9Sstevel@tonic-gate LOG_VOL_CLOSE_INT) { 7517c478bd9Sstevel@tonic-gate error = EINVAL; 7527c478bd9Sstevel@tonic-gate goto remountout; 7537c478bd9Sstevel@tonic-gate } 7547c478bd9Sstevel@tonic-gate 7557c478bd9Sstevel@tonic-gate /* 7567c478bd9Sstevel@tonic-gate * Copy new data to old data 7577c478bd9Sstevel@tonic-gate */ 7587c478bd9Sstevel@tonic-gate bcopy(udf_vfsp->udf_iseq->b_un.b_addr, 7597c478bd9Sstevel@tonic-gate tpt->b_un.b_addr, udf_vfsp->udf_iseq_len); 7607c478bd9Sstevel@tonic-gate break; 7617c478bd9Sstevel@tonic-gate } 7627c478bd9Sstevel@tonic-gate } 7637c478bd9Sstevel@tonic-gate 7647c478bd9Sstevel@tonic-gate udf_vfsp->udf_flags = UDF_FL_RW; 7657c478bd9Sstevel@tonic-gate 7667c478bd9Sstevel@tonic-gate mutex_enter(&udf_vfsp->udf_lock); 7677c478bd9Sstevel@tonic-gate ud_sbwrite(udf_vfsp); 7687c478bd9Sstevel@tonic-gate mutex_exit(&udf_vfsp->udf_lock); 7697c478bd9Sstevel@tonic-gate remountout: 7707c478bd9Sstevel@tonic-gate if (tpt != NULL) { 7717c478bd9Sstevel@tonic-gate tpt->b_flags = B_AGE | B_STALE; 7727c478bd9Sstevel@tonic-gate brelse(tpt); 7737c478bd9Sstevel@tonic-gate } 7747c478bd9Sstevel@tonic-gate return (error); 7757c478bd9Sstevel@tonic-gate } 7767c478bd9Sstevel@tonic-gate 7777c478bd9Sstevel@tonic-gate ASSERT(devvp != 0); 7787c478bd9Sstevel@tonic-gate /* 7797c478bd9Sstevel@tonic-gate * Flush back any dirty pages on the block device to 7807c478bd9Sstevel@tonic-gate * try and keep the buffer cache in sync with the page 7817c478bd9Sstevel@tonic-gate * cache if someone is trying to use block devices when 7827c478bd9Sstevel@tonic-gate * they really should be using the raw device. 7837c478bd9Sstevel@tonic-gate */ 7847c478bd9Sstevel@tonic-gate (void) VOP_PUTPAGE(common_specvp(devvp), (offset_t)0, 785da6c28aaSamw (uint32_t)0, B_INVAL, cr, NULL); 7867c478bd9Sstevel@tonic-gate 7877c478bd9Sstevel@tonic-gate 7887c478bd9Sstevel@tonic-gate /* 7897c478bd9Sstevel@tonic-gate * Check if the file system 7907c478bd9Sstevel@tonic-gate * is a valid udfs and fill 7917c478bd9Sstevel@tonic-gate * the required fields in udf_vfs 7927c478bd9Sstevel@tonic-gate */ 7937c478bd9Sstevel@tonic-gate #ifndef __lint 7947c478bd9Sstevel@tonic-gate _NOTE(NO_COMPETING_THREADS_NOW); 7957c478bd9Sstevel@tonic-gate #endif 7967c478bd9Sstevel@tonic-gate 7977c478bd9Sstevel@tonic-gate if ((lbsize = ud_get_lbsize(dev, &avd_loc)) == 0) { 7987c478bd9Sstevel@tonic-gate error = EINVAL; 7997c478bd9Sstevel@tonic-gate goto out; 8007c478bd9Sstevel@tonic-gate } 8017c478bd9Sstevel@tonic-gate 8027c478bd9Sstevel@tonic-gate udf_vfsp = ud_validate_and_fill_superblock(dev, lbsize, avd_loc); 8037c478bd9Sstevel@tonic-gate if (udf_vfsp == NULL) { 8047c478bd9Sstevel@tonic-gate error = EINVAL; 8057c478bd9Sstevel@tonic-gate goto out; 8067c478bd9Sstevel@tonic-gate } 8077c478bd9Sstevel@tonic-gate 8087c478bd9Sstevel@tonic-gate /* 8097c478bd9Sstevel@tonic-gate * Fill in vfs private data 8107c478bd9Sstevel@tonic-gate */ 8117c478bd9Sstevel@tonic-gate vfsp->vfs_fstype = udf_fstype; 8127c478bd9Sstevel@tonic-gate vfs_make_fsid(&vfsp->vfs_fsid, dev, udf_fstype); 8137c478bd9Sstevel@tonic-gate vfsp->vfs_data = (caddr_t)udf_vfsp; 8147c478bd9Sstevel@tonic-gate vfsp->vfs_dev = dev; 8157c478bd9Sstevel@tonic-gate vfsp->vfs_flag |= VFS_NOTRUNC; 8167c478bd9Sstevel@tonic-gate udf_vfsp->udf_devvp = devvp; 8177c478bd9Sstevel@tonic-gate 8187c478bd9Sstevel@tonic-gate udf_vfsp->udf_fsmnt = kmem_zalloc(strlen(name) + 1, KM_SLEEP); 8197c478bd9Sstevel@tonic-gate (void) strcpy(udf_vfsp->udf_fsmnt, name); 8207c478bd9Sstevel@tonic-gate 8217c478bd9Sstevel@tonic-gate udf_vfsp->udf_vfs = vfsp; 8227c478bd9Sstevel@tonic-gate udf_vfsp->udf_rdclustsz = udf_vfsp->udf_wrclustsz = maxphys; 8237c478bd9Sstevel@tonic-gate 8247c478bd9Sstevel@tonic-gate udf_vfsp->udf_mod = 0; 8257c478bd9Sstevel@tonic-gate 8267c478bd9Sstevel@tonic-gate 8277c478bd9Sstevel@tonic-gate lvid = udf_vfsp->udf_lvid; 8287c478bd9Sstevel@tonic-gate if (vfsp->vfs_flag & VFS_RDONLY) { 8297c478bd9Sstevel@tonic-gate /* 8307c478bd9Sstevel@tonic-gate * We could read only UDF1.50 8317c478bd9Sstevel@tonic-gate * disallow mount of any highier version 8327c478bd9Sstevel@tonic-gate */ 8337c478bd9Sstevel@tonic-gate if (udf_vfsp->udf_miread > UDF_150) { 8347c478bd9Sstevel@tonic-gate error = EINVAL; 8357c478bd9Sstevel@tonic-gate goto out; 8367c478bd9Sstevel@tonic-gate } 8377c478bd9Sstevel@tonic-gate udf_vfsp->udf_flags = UDF_FL_RDONLY; 8387c478bd9Sstevel@tonic-gate if (SWAP_32(lvid->lvid_int_type) == LOG_VOL_CLOSE_INT) { 8397c478bd9Sstevel@tonic-gate udf_vfsp->udf_clean = UDF_CLEAN; 8407c478bd9Sstevel@tonic-gate } else { 8417c478bd9Sstevel@tonic-gate /* Do we have a VAT at the end of the recorded media */ 8427c478bd9Sstevel@tonic-gate map = udf_vfsp->udf_maps; 8437c478bd9Sstevel@tonic-gate for (i = 0; i < udf_vfsp->udf_nmaps; i++) { 8447c478bd9Sstevel@tonic-gate if (map->udm_flags & UDM_MAP_VPM) { 8457c478bd9Sstevel@tonic-gate break; 8467c478bd9Sstevel@tonic-gate } 8477c478bd9Sstevel@tonic-gate map++; 8487c478bd9Sstevel@tonic-gate } 8497c478bd9Sstevel@tonic-gate if (i == udf_vfsp->udf_nmaps) { 8507c478bd9Sstevel@tonic-gate error = ENOSPC; 8517c478bd9Sstevel@tonic-gate goto out; 8527c478bd9Sstevel@tonic-gate } 8537c478bd9Sstevel@tonic-gate udf_vfsp->udf_clean = UDF_CLEAN; 8547c478bd9Sstevel@tonic-gate } 8557c478bd9Sstevel@tonic-gate } else { 8567c478bd9Sstevel@tonic-gate /* 8577c478bd9Sstevel@tonic-gate * We could read UDF1.50 and write UDF1.50 only 8587c478bd9Sstevel@tonic-gate * disallow mount of any highier version 8597c478bd9Sstevel@tonic-gate */ 8607c478bd9Sstevel@tonic-gate if ((udf_vfsp->udf_miread > UDF_150) || 8617c478bd9Sstevel@tonic-gate (udf_vfsp->udf_miwrite > UDF_150)) { 8627c478bd9Sstevel@tonic-gate error = EINVAL; 8637c478bd9Sstevel@tonic-gate goto out; 8647c478bd9Sstevel@tonic-gate } 8657c478bd9Sstevel@tonic-gate /* 8667c478bd9Sstevel@tonic-gate * Check if the media allows 8677c478bd9Sstevel@tonic-gate * us to mount read/write 8687c478bd9Sstevel@tonic-gate */ 8697c478bd9Sstevel@tonic-gate if (udf_vfsp->udf_mtype != UDF_MT_OW) { 8707c478bd9Sstevel@tonic-gate error = EACCES; 8717c478bd9Sstevel@tonic-gate goto out; 8727c478bd9Sstevel@tonic-gate } 8737c478bd9Sstevel@tonic-gate 8747c478bd9Sstevel@tonic-gate /* 8757c478bd9Sstevel@tonic-gate * Check if we have VAT on a writable media 8767c478bd9Sstevel@tonic-gate * we cannot use the media in presence of VAT 8777c478bd9Sstevel@tonic-gate * Dent RW mount. 8787c478bd9Sstevel@tonic-gate */ 8797c478bd9Sstevel@tonic-gate map = udf_vfsp->udf_maps; 8807c478bd9Sstevel@tonic-gate ASSERT(map != NULL); 8817c478bd9Sstevel@tonic-gate for (i = 0; i < udf_vfsp->udf_nmaps; i++) { 8827c478bd9Sstevel@tonic-gate if (map->udm_flags & UDM_MAP_VPM) { 8837c478bd9Sstevel@tonic-gate error = EACCES; 8847c478bd9Sstevel@tonic-gate goto out; 8857c478bd9Sstevel@tonic-gate } 8867c478bd9Sstevel@tonic-gate map++; 8877c478bd9Sstevel@tonic-gate } 8887c478bd9Sstevel@tonic-gate 8897c478bd9Sstevel@tonic-gate /* 8907c478bd9Sstevel@tonic-gate * Check if the domain Id allows 8917c478bd9Sstevel@tonic-gate * us to write 8927c478bd9Sstevel@tonic-gate */ 8937c478bd9Sstevel@tonic-gate if (udf_vfsp->udf_lvd->lvd_dom_id.reg_ids[2] & 0x3) { 8947c478bd9Sstevel@tonic-gate error = EACCES; 8957c478bd9Sstevel@tonic-gate goto out; 8967c478bd9Sstevel@tonic-gate } 8977c478bd9Sstevel@tonic-gate udf_vfsp->udf_flags = UDF_FL_RW; 8987c478bd9Sstevel@tonic-gate 8997c478bd9Sstevel@tonic-gate if (SWAP_32(lvid->lvid_int_type) == LOG_VOL_CLOSE_INT) { 9007c478bd9Sstevel@tonic-gate udf_vfsp->udf_clean = UDF_CLEAN; 9017c478bd9Sstevel@tonic-gate } else { 9027c478bd9Sstevel@tonic-gate if (isroot) { 9037c478bd9Sstevel@tonic-gate udf_vfsp->udf_clean = UDF_DIRTY; 9047c478bd9Sstevel@tonic-gate } else { 9057c478bd9Sstevel@tonic-gate error = ENOSPC; 9067c478bd9Sstevel@tonic-gate goto out; 9077c478bd9Sstevel@tonic-gate } 9087c478bd9Sstevel@tonic-gate } 9097c478bd9Sstevel@tonic-gate } 9107c478bd9Sstevel@tonic-gate 9117c478bd9Sstevel@tonic-gate mutex_init(&udf_vfsp->udf_lock, NULL, MUTEX_DEFAULT, NULL); 9127c478bd9Sstevel@tonic-gate 9137c478bd9Sstevel@tonic-gate mutex_init(&udf_vfsp->udf_rename_lck, NULL, MUTEX_DEFAULT, NULL); 9147c478bd9Sstevel@tonic-gate 9157c478bd9Sstevel@tonic-gate #ifndef __lint 9167c478bd9Sstevel@tonic-gate _NOTE(COMPETING_THREADS_NOW); 9177c478bd9Sstevel@tonic-gate #endif 9187c478bd9Sstevel@tonic-gate if (error = ud_iget(vfsp, udf_vfsp->udf_ricb_prn, 9197c478bd9Sstevel@tonic-gate udf_vfsp->udf_ricb_loc, &rip, NULL, cr)) { 9207c478bd9Sstevel@tonic-gate mutex_destroy(&udf_vfsp->udf_lock); 9217c478bd9Sstevel@tonic-gate goto out; 9227c478bd9Sstevel@tonic-gate } 9237c478bd9Sstevel@tonic-gate 9247c478bd9Sstevel@tonic-gate 9257c478bd9Sstevel@tonic-gate /* 9267c478bd9Sstevel@tonic-gate * Get the root inode and 9277c478bd9Sstevel@tonic-gate * initialize the root vnode 9287c478bd9Sstevel@tonic-gate */ 9297c478bd9Sstevel@tonic-gate rvp = ITOV(rip); 9307c478bd9Sstevel@tonic-gate mutex_enter(&rvp->v_lock); 9317c478bd9Sstevel@tonic-gate rvp->v_flag |= VROOT; 9327c478bd9Sstevel@tonic-gate mutex_exit(&rvp->v_lock); 9337c478bd9Sstevel@tonic-gate udf_vfsp->udf_root = rvp; 9347c478bd9Sstevel@tonic-gate 9357c478bd9Sstevel@tonic-gate 9367c478bd9Sstevel@tonic-gate if (why == ROOT_INIT && isroot) 9377c478bd9Sstevel@tonic-gate rootvp = devvp; 9387c478bd9Sstevel@tonic-gate 9397c478bd9Sstevel@tonic-gate ud_vfs_add(udf_vfsp); 9407c478bd9Sstevel@tonic-gate 9417c478bd9Sstevel@tonic-gate if (udf_vfsp->udf_flags == UDF_FL_RW) { 9427c478bd9Sstevel@tonic-gate udf_vfsp->udf_clean = UDF_DIRTY; 9437c478bd9Sstevel@tonic-gate ud_update_superblock(vfsp); 9447c478bd9Sstevel@tonic-gate } 9457c478bd9Sstevel@tonic-gate 9467c478bd9Sstevel@tonic-gate return (0); 9477c478bd9Sstevel@tonic-gate 9487c478bd9Sstevel@tonic-gate out: 9497c478bd9Sstevel@tonic-gate ud_destroy_fsp(udf_vfsp); 9507c478bd9Sstevel@tonic-gate if (needclose) { 9517c478bd9Sstevel@tonic-gate (void) VOP_CLOSE(devvp, (vfsp->vfs_flag & VFS_RDONLY) ? 952da6c28aaSamw FREAD : FREAD|FWRITE, 1, (offset_t)0, cr, NULL); 9537c478bd9Sstevel@tonic-gate bflush(dev); 9547c478bd9Sstevel@tonic-gate binval(dev); 9557c478bd9Sstevel@tonic-gate } 9567c478bd9Sstevel@tonic-gate VN_RELE(devvp); 9577c478bd9Sstevel@tonic-gate 9587c478bd9Sstevel@tonic-gate return (error); 9597c478bd9Sstevel@tonic-gate } 9607c478bd9Sstevel@tonic-gate 9617c478bd9Sstevel@tonic-gate 9627c478bd9Sstevel@tonic-gate static struct udf_vfs * 9637c478bd9Sstevel@tonic-gate ud_validate_and_fill_superblock(dev_t dev, int32_t bsize, uint32_t avd_loc) 9647c478bd9Sstevel@tonic-gate { 9657c478bd9Sstevel@tonic-gate int32_t error, count, index, shift; 9667c478bd9Sstevel@tonic-gate uint32_t dummy, vds_loc; 9677c478bd9Sstevel@tonic-gate caddr_t addr; 9687c478bd9Sstevel@tonic-gate daddr_t blkno, lblkno; 9697c478bd9Sstevel@tonic-gate struct buf *secbp, *bp; 9707c478bd9Sstevel@tonic-gate struct tag *ttag; 9717c478bd9Sstevel@tonic-gate struct anch_vol_desc_ptr *avdp; 9727c478bd9Sstevel@tonic-gate struct file_set_desc *fsd; 9737c478bd9Sstevel@tonic-gate struct udf_vfs *udf_vfsp = NULL; 9747c478bd9Sstevel@tonic-gate struct pmap_hdr *hdr; 9757c478bd9Sstevel@tonic-gate struct pmap_typ1 *typ1; 9767c478bd9Sstevel@tonic-gate struct pmap_typ2 *typ2; 9777c478bd9Sstevel@tonic-gate struct ud_map *map; 9787c478bd9Sstevel@tonic-gate int32_t desc_len; 9797c478bd9Sstevel@tonic-gate 9807c478bd9Sstevel@tonic-gate ud_printf("ud_validate_and_fill_superblock\n"); 9817c478bd9Sstevel@tonic-gate 9827c478bd9Sstevel@tonic-gate if (bsize < DEV_BSIZE) { 9837c478bd9Sstevel@tonic-gate return (NULL); 9847c478bd9Sstevel@tonic-gate } 9857c478bd9Sstevel@tonic-gate shift = 0; 9867c478bd9Sstevel@tonic-gate while ((bsize >> shift) > DEV_BSIZE) { 9877c478bd9Sstevel@tonic-gate shift++; 9887c478bd9Sstevel@tonic-gate } 9897c478bd9Sstevel@tonic-gate 9907c478bd9Sstevel@tonic-gate /* 9917c478bd9Sstevel@tonic-gate * Read Anchor Volume Descriptor 9927c478bd9Sstevel@tonic-gate * Verify it and get the location of 9937c478bd9Sstevel@tonic-gate * Main Volume Descriptor Sequence 9947c478bd9Sstevel@tonic-gate */ 9957c478bd9Sstevel@tonic-gate secbp = ud_bread(dev, avd_loc << shift, ANCHOR_VOL_DESC_LEN); 9967c478bd9Sstevel@tonic-gate if ((error = geterror(secbp)) != 0) { 99793239addSjohnlev cmn_err(CE_NOTE, "udfs : Could not read Anchor Volume Desc %x", 99893239addSjohnlev error); 9997c478bd9Sstevel@tonic-gate brelse(secbp); 10007c478bd9Sstevel@tonic-gate return (NULL); 10017c478bd9Sstevel@tonic-gate } 10027c478bd9Sstevel@tonic-gate avdp = (struct anch_vol_desc_ptr *)secbp->b_un.b_addr; 10037c478bd9Sstevel@tonic-gate if (ud_verify_tag_and_desc(&avdp->avd_tag, UD_ANCH_VOL_DESC, 10047c478bd9Sstevel@tonic-gate avd_loc, 1, ANCHOR_VOL_DESC_LEN) != 0) { 10057c478bd9Sstevel@tonic-gate brelse(secbp); 10067c478bd9Sstevel@tonic-gate return (NULL); 10077c478bd9Sstevel@tonic-gate } 10087c478bd9Sstevel@tonic-gate udf_vfsp = (struct udf_vfs *) 10097c478bd9Sstevel@tonic-gate kmem_zalloc(sizeof (struct udf_vfs), KM_SLEEP); 10107c478bd9Sstevel@tonic-gate udf_vfsp->udf_mvds_loc = SWAP_32(avdp->avd_main_vdse.ext_loc); 10117c478bd9Sstevel@tonic-gate udf_vfsp->udf_mvds_len = SWAP_32(avdp->avd_main_vdse.ext_len); 10127c478bd9Sstevel@tonic-gate udf_vfsp->udf_rvds_loc = SWAP_32(avdp->avd_res_vdse.ext_loc); 10137c478bd9Sstevel@tonic-gate udf_vfsp->udf_rvds_len = SWAP_32(avdp->avd_res_vdse.ext_len); 10147c478bd9Sstevel@tonic-gate secbp->b_flags = B_AGE | B_STALE; 10157c478bd9Sstevel@tonic-gate brelse(secbp); 10167c478bd9Sstevel@tonic-gate 10177c478bd9Sstevel@tonic-gate /* 10187c478bd9Sstevel@tonic-gate * Read Main Volume Descriptor Sequence 10197c478bd9Sstevel@tonic-gate * and process it 10207c478bd9Sstevel@tonic-gate */ 10217c478bd9Sstevel@tonic-gate vds_loc = udf_vfsp->udf_mvds_loc; 10227c478bd9Sstevel@tonic-gate secbp = ud_bread(dev, vds_loc << shift, 10237c478bd9Sstevel@tonic-gate udf_vfsp->udf_mvds_len); 10247c478bd9Sstevel@tonic-gate if ((error = geterror(secbp)) != 0) { 10257c478bd9Sstevel@tonic-gate brelse(secbp); 102693239addSjohnlev cmn_err(CE_NOTE, "udfs : Could not read Main Volume Desc %x", 102793239addSjohnlev error); 10287c478bd9Sstevel@tonic-gate 10297c478bd9Sstevel@tonic-gate vds_loc = udf_vfsp->udf_rvds_loc; 10307c478bd9Sstevel@tonic-gate secbp = ud_bread(dev, vds_loc << shift, 10317c478bd9Sstevel@tonic-gate udf_vfsp->udf_rvds_len); 10327c478bd9Sstevel@tonic-gate if ((error = geterror(secbp)) != 0) { 10337c478bd9Sstevel@tonic-gate brelse(secbp); 10347c478bd9Sstevel@tonic-gate cmn_err(CE_NOTE, 10357c478bd9Sstevel@tonic-gate "udfs : Could not read Res Volume Desc %x", error); 10367c478bd9Sstevel@tonic-gate return (NULL); 10377c478bd9Sstevel@tonic-gate } 10387c478bd9Sstevel@tonic-gate } 10397c478bd9Sstevel@tonic-gate 10407c478bd9Sstevel@tonic-gate udf_vfsp->udf_vds = ngeteblk(udf_vfsp->udf_mvds_len); 10417c478bd9Sstevel@tonic-gate bp = udf_vfsp->udf_vds; 10427c478bd9Sstevel@tonic-gate bp->b_edev = dev; 10437c478bd9Sstevel@tonic-gate bp->b_dev = cmpdev(dev); 10447c478bd9Sstevel@tonic-gate bp->b_blkno = vds_loc << shift; 10457c478bd9Sstevel@tonic-gate bp->b_bcount = udf_vfsp->udf_mvds_len; 10467c478bd9Sstevel@tonic-gate bcopy(secbp->b_un.b_addr, bp->b_un.b_addr, udf_vfsp->udf_mvds_len); 10477c478bd9Sstevel@tonic-gate secbp->b_flags |= B_STALE | B_AGE; 10487c478bd9Sstevel@tonic-gate brelse(secbp); 10497c478bd9Sstevel@tonic-gate 10507c478bd9Sstevel@tonic-gate 10517c478bd9Sstevel@tonic-gate count = udf_vfsp->udf_mvds_len / DEV_BSIZE; 10527c478bd9Sstevel@tonic-gate addr = bp->b_un.b_addr; 10537c478bd9Sstevel@tonic-gate for (index = 0; index < count; index ++) { 10547c478bd9Sstevel@tonic-gate ttag = (struct tag *)(addr + index * DEV_BSIZE); 10557c478bd9Sstevel@tonic-gate desc_len = udf_vfsp->udf_mvds_len - (index * DEV_BSIZE); 10567c478bd9Sstevel@tonic-gate if (ud_verify_tag_and_desc(ttag, UD_PRI_VOL_DESC, 10577c478bd9Sstevel@tonic-gate vds_loc + (index >> shift), 10587c478bd9Sstevel@tonic-gate 1, desc_len) == 0) { 10597c478bd9Sstevel@tonic-gate if (udf_vfsp->udf_pvd == NULL) { 10607c478bd9Sstevel@tonic-gate udf_vfsp->udf_pvd = 10617c478bd9Sstevel@tonic-gate (struct pri_vol_desc *)ttag; 10627c478bd9Sstevel@tonic-gate } else { 10637c478bd9Sstevel@tonic-gate struct pri_vol_desc *opvd, *npvd; 10647c478bd9Sstevel@tonic-gate 10657c478bd9Sstevel@tonic-gate opvd = udf_vfsp->udf_pvd; 10667c478bd9Sstevel@tonic-gate npvd = (struct pri_vol_desc *)ttag; 10677c478bd9Sstevel@tonic-gate 10687c478bd9Sstevel@tonic-gate if ((strncmp(opvd->pvd_vsi, 10697c478bd9Sstevel@tonic-gate npvd->pvd_vsi, 128) == 0) && 10707c478bd9Sstevel@tonic-gate (strncmp(opvd->pvd_vol_id, 10717c478bd9Sstevel@tonic-gate npvd->pvd_vol_id, 32) == 0) && 10727c478bd9Sstevel@tonic-gate (strncmp((caddr_t)&opvd->pvd_desc_cs, 10737c478bd9Sstevel@tonic-gate (caddr_t)&npvd->pvd_desc_cs, 10747c478bd9Sstevel@tonic-gate sizeof (charspec_t)) == 0)) { 10757c478bd9Sstevel@tonic-gate 10767c478bd9Sstevel@tonic-gate if (SWAP_32(opvd->pvd_vdsn) < 10777c478bd9Sstevel@tonic-gate SWAP_32(npvd->pvd_vdsn)) { 10787c478bd9Sstevel@tonic-gate udf_vfsp->udf_pvd = npvd; 10797c478bd9Sstevel@tonic-gate } 10807c478bd9Sstevel@tonic-gate } else { 10817c478bd9Sstevel@tonic-gate goto out; 10827c478bd9Sstevel@tonic-gate } 10837c478bd9Sstevel@tonic-gate } 10847c478bd9Sstevel@tonic-gate } else if (ud_verify_tag_and_desc(ttag, UD_LOG_VOL_DESC, 10857c478bd9Sstevel@tonic-gate vds_loc + (index >> shift), 10867c478bd9Sstevel@tonic-gate 1, desc_len) == 0) { 10877c478bd9Sstevel@tonic-gate struct log_vol_desc *lvd; 10887c478bd9Sstevel@tonic-gate 10897c478bd9Sstevel@tonic-gate lvd = (struct log_vol_desc *)ttag; 10907c478bd9Sstevel@tonic-gate if (strncmp(lvd->lvd_dom_id.reg_id, 10917c478bd9Sstevel@tonic-gate UDF_DOMAIN_NAME, 23) != 0) { 10927c478bd9Sstevel@tonic-gate printf("Domain ID in lvd is not valid\n"); 10937c478bd9Sstevel@tonic-gate goto out; 10947c478bd9Sstevel@tonic-gate } 10957c478bd9Sstevel@tonic-gate 10967c478bd9Sstevel@tonic-gate if (udf_vfsp->udf_lvd == NULL) { 10977c478bd9Sstevel@tonic-gate udf_vfsp->udf_lvd = lvd; 10987c478bd9Sstevel@tonic-gate } else { 10997c478bd9Sstevel@tonic-gate struct log_vol_desc *olvd; 11007c478bd9Sstevel@tonic-gate 11017c478bd9Sstevel@tonic-gate olvd = udf_vfsp->udf_lvd; 11027c478bd9Sstevel@tonic-gate if ((strncmp((caddr_t)&olvd->lvd_desc_cs, 11037c478bd9Sstevel@tonic-gate (caddr_t)&lvd->lvd_desc_cs, 11047c478bd9Sstevel@tonic-gate sizeof (charspec_t)) == 0) && 11057c478bd9Sstevel@tonic-gate (strncmp(olvd->lvd_lvid, 11067c478bd9Sstevel@tonic-gate lvd->lvd_lvid, 128) == 0)) { 11077c478bd9Sstevel@tonic-gate if (SWAP_32(olvd->lvd_vdsn) < 11087c478bd9Sstevel@tonic-gate SWAP_32(lvd->lvd_vdsn)) { 11097c478bd9Sstevel@tonic-gate udf_vfsp->udf_lvd = lvd; 11107c478bd9Sstevel@tonic-gate } 11117c478bd9Sstevel@tonic-gate } else { 11127c478bd9Sstevel@tonic-gate goto out; 11137c478bd9Sstevel@tonic-gate } 11147c478bd9Sstevel@tonic-gate } 11157c478bd9Sstevel@tonic-gate } else if (ud_verify_tag_and_desc(ttag, UD_PART_DESC, 11167c478bd9Sstevel@tonic-gate vds_loc + (index >> shift), 11177c478bd9Sstevel@tonic-gate 1, desc_len) == 0) { 11187c478bd9Sstevel@tonic-gate int32_t i; 11197c478bd9Sstevel@tonic-gate struct phdr_desc *hdr; 11207c478bd9Sstevel@tonic-gate struct part_desc *pdesc; 11217c478bd9Sstevel@tonic-gate struct ud_part *pnew, *pold, *part; 11227c478bd9Sstevel@tonic-gate 11237c478bd9Sstevel@tonic-gate pdesc = (struct part_desc *)ttag; 11247c478bd9Sstevel@tonic-gate pold = udf_vfsp->udf_parts; 11257c478bd9Sstevel@tonic-gate for (i = 0; i < udf_vfsp->udf_npart; i++) { 112693239addSjohnlev if (pold->udp_number != 11277c478bd9Sstevel@tonic-gate SWAP_16(pdesc->pd_pnum)) { 112893239addSjohnlev pold++; 112993239addSjohnlev continue; 113093239addSjohnlev } 113193239addSjohnlev 11327c478bd9Sstevel@tonic-gate if (SWAP_32(pdesc->pd_vdsn) > 11337c478bd9Sstevel@tonic-gate pold->udp_seqno) { 11347c478bd9Sstevel@tonic-gate pold->udp_seqno = 11357c478bd9Sstevel@tonic-gate SWAP_32(pdesc->pd_vdsn); 11367c478bd9Sstevel@tonic-gate pold->udp_access = 11377c478bd9Sstevel@tonic-gate SWAP_32(pdesc->pd_acc_type); 11387c478bd9Sstevel@tonic-gate pold->udp_start = 11397c478bd9Sstevel@tonic-gate SWAP_32(pdesc->pd_part_start); 11407c478bd9Sstevel@tonic-gate pold->udp_length = 11417c478bd9Sstevel@tonic-gate SWAP_32(pdesc->pd_part_length); 11427c478bd9Sstevel@tonic-gate } 11437c478bd9Sstevel@tonic-gate goto loop_end; 11447c478bd9Sstevel@tonic-gate } 11457c478bd9Sstevel@tonic-gate pold = udf_vfsp->udf_parts; 11467c478bd9Sstevel@tonic-gate udf_vfsp->udf_npart++; 11477c478bd9Sstevel@tonic-gate pnew = kmem_zalloc(udf_vfsp->udf_npart * 11487c478bd9Sstevel@tonic-gate sizeof (struct ud_part), KM_SLEEP); 11497c478bd9Sstevel@tonic-gate udf_vfsp->udf_parts = pnew; 11507c478bd9Sstevel@tonic-gate if (pold) { 11517c478bd9Sstevel@tonic-gate bcopy(pold, pnew, 11527c478bd9Sstevel@tonic-gate sizeof (struct ud_part) * 11537c478bd9Sstevel@tonic-gate (udf_vfsp->udf_npart - 1)); 11547c478bd9Sstevel@tonic-gate kmem_free(pold, 11557c478bd9Sstevel@tonic-gate sizeof (struct ud_part) * 11567c478bd9Sstevel@tonic-gate (udf_vfsp->udf_npart - 1)); 11577c478bd9Sstevel@tonic-gate } 11587c478bd9Sstevel@tonic-gate part = pnew + (udf_vfsp->udf_npart - 1); 11597c478bd9Sstevel@tonic-gate part->udp_number = SWAP_16(pdesc->pd_pnum); 11607c478bd9Sstevel@tonic-gate part->udp_seqno = SWAP_32(pdesc->pd_vdsn); 11617c478bd9Sstevel@tonic-gate part->udp_access = SWAP_32(pdesc->pd_acc_type); 11627c478bd9Sstevel@tonic-gate part->udp_start = SWAP_32(pdesc->pd_part_start); 11637c478bd9Sstevel@tonic-gate part->udp_length = SWAP_32(pdesc->pd_part_length); 11647c478bd9Sstevel@tonic-gate part->udp_last_alloc = 0; 11657c478bd9Sstevel@tonic-gate 11667c478bd9Sstevel@tonic-gate /* 11677c478bd9Sstevel@tonic-gate * Figure out space bitmaps 11687c478bd9Sstevel@tonic-gate * or space tables 11697c478bd9Sstevel@tonic-gate */ 11707c478bd9Sstevel@tonic-gate hdr = (struct phdr_desc *)pdesc->pd_pc_use; 11717c478bd9Sstevel@tonic-gate if (hdr->phdr_ust.sad_ext_len) { 11727c478bd9Sstevel@tonic-gate part->udp_flags = UDP_SPACETBLS; 11737c478bd9Sstevel@tonic-gate part->udp_unall_loc = 11747c478bd9Sstevel@tonic-gate SWAP_32(hdr->phdr_ust.sad_ext_loc); 11757c478bd9Sstevel@tonic-gate part->udp_unall_len = 11767c478bd9Sstevel@tonic-gate SWAP_32(hdr->phdr_ust.sad_ext_len); 11777c478bd9Sstevel@tonic-gate part->udp_freed_loc = 11787c478bd9Sstevel@tonic-gate SWAP_32(hdr->phdr_fst.sad_ext_loc); 11797c478bd9Sstevel@tonic-gate part->udp_freed_len = 11807c478bd9Sstevel@tonic-gate SWAP_32(hdr->phdr_fst.sad_ext_len); 11817c478bd9Sstevel@tonic-gate } else { 11827c478bd9Sstevel@tonic-gate part->udp_flags = UDP_BITMAPS; 11837c478bd9Sstevel@tonic-gate part->udp_unall_loc = 11847c478bd9Sstevel@tonic-gate SWAP_32(hdr->phdr_usb.sad_ext_loc); 11857c478bd9Sstevel@tonic-gate part->udp_unall_len = 11867c478bd9Sstevel@tonic-gate SWAP_32(hdr->phdr_usb.sad_ext_len); 11877c478bd9Sstevel@tonic-gate part->udp_freed_loc = 11887c478bd9Sstevel@tonic-gate SWAP_32(hdr->phdr_fsb.sad_ext_loc); 11897c478bd9Sstevel@tonic-gate part->udp_freed_len = 11907c478bd9Sstevel@tonic-gate SWAP_32(hdr->phdr_fsb.sad_ext_len); 11917c478bd9Sstevel@tonic-gate } 11927c478bd9Sstevel@tonic-gate } else if (ud_verify_tag_and_desc(ttag, UD_TERM_DESC, 11937c478bd9Sstevel@tonic-gate vds_loc + (index >> shift), 11947c478bd9Sstevel@tonic-gate 1, desc_len) == 0) { 11957c478bd9Sstevel@tonic-gate 11967c478bd9Sstevel@tonic-gate break; 11977c478bd9Sstevel@tonic-gate } 11987c478bd9Sstevel@tonic-gate loop_end: 11997c478bd9Sstevel@tonic-gate ; 12007c478bd9Sstevel@tonic-gate } 12017c478bd9Sstevel@tonic-gate if ((udf_vfsp->udf_pvd == NULL) || 12027c478bd9Sstevel@tonic-gate (udf_vfsp->udf_lvd == NULL) || 12037c478bd9Sstevel@tonic-gate (udf_vfsp->udf_parts == NULL)) { 12047c478bd9Sstevel@tonic-gate goto out; 12057c478bd9Sstevel@tonic-gate } 12067c478bd9Sstevel@tonic-gate 12077c478bd9Sstevel@tonic-gate /* 12087c478bd9Sstevel@tonic-gate * Process Primary Volume Descriptor 12097c478bd9Sstevel@tonic-gate */ 12107c478bd9Sstevel@tonic-gate (void) strncpy(udf_vfsp->udf_volid, udf_vfsp->udf_pvd->pvd_vol_id, 32); 12117c478bd9Sstevel@tonic-gate udf_vfsp->udf_volid[31] = '\0'; 12127c478bd9Sstevel@tonic-gate udf_vfsp->udf_tsno = SWAP_16(udf_vfsp->udf_pvd->pvd_tag.tag_sno); 12137c478bd9Sstevel@tonic-gate 12147c478bd9Sstevel@tonic-gate /* 12157c478bd9Sstevel@tonic-gate * Process Logical Volume Descriptor 12167c478bd9Sstevel@tonic-gate */ 12177c478bd9Sstevel@tonic-gate udf_vfsp->udf_lbsize = 12187c478bd9Sstevel@tonic-gate SWAP_32(udf_vfsp->udf_lvd->lvd_log_bsize); 12197c478bd9Sstevel@tonic-gate udf_vfsp->udf_lbmask = udf_vfsp->udf_lbsize - 1; 12207c478bd9Sstevel@tonic-gate udf_vfsp->udf_l2d_shift = shift; 12217c478bd9Sstevel@tonic-gate udf_vfsp->udf_l2b_shift = shift + DEV_BSHIFT; 12227c478bd9Sstevel@tonic-gate 12237c478bd9Sstevel@tonic-gate /* 12247c478bd9Sstevel@tonic-gate * Check if the media is in 12257c478bd9Sstevel@tonic-gate * proper domain. 12267c478bd9Sstevel@tonic-gate */ 12277c478bd9Sstevel@tonic-gate if (strcmp(udf_vfsp->udf_lvd->lvd_dom_id.reg_id, 12287c478bd9Sstevel@tonic-gate UDF_DOMAIN_NAME) != 0) { 12297c478bd9Sstevel@tonic-gate goto out; 12307c478bd9Sstevel@tonic-gate } 12317c478bd9Sstevel@tonic-gate 12327c478bd9Sstevel@tonic-gate /* 12337c478bd9Sstevel@tonic-gate * AVDS offset does not match with the lbsize 12347c478bd9Sstevel@tonic-gate * in the lvd 12357c478bd9Sstevel@tonic-gate */ 12367c478bd9Sstevel@tonic-gate if (udf_vfsp->udf_lbsize != bsize) { 12377c478bd9Sstevel@tonic-gate goto out; 12387c478bd9Sstevel@tonic-gate } 12397c478bd9Sstevel@tonic-gate 12407c478bd9Sstevel@tonic-gate udf_vfsp->udf_iseq_loc = 12417c478bd9Sstevel@tonic-gate SWAP_32(udf_vfsp->udf_lvd->lvd_int_seq_ext.ext_loc); 12427c478bd9Sstevel@tonic-gate udf_vfsp->udf_iseq_len = 12437c478bd9Sstevel@tonic-gate SWAP_32(udf_vfsp->udf_lvd->lvd_int_seq_ext.ext_len); 12447c478bd9Sstevel@tonic-gate 12457c478bd9Sstevel@tonic-gate udf_vfsp->udf_fsd_prn = 12467c478bd9Sstevel@tonic-gate SWAP_16(udf_vfsp->udf_lvd->lvd_lvcu.lad_ext_prn); 12477c478bd9Sstevel@tonic-gate udf_vfsp->udf_fsd_loc = 12487c478bd9Sstevel@tonic-gate SWAP_32(udf_vfsp->udf_lvd->lvd_lvcu.lad_ext_loc); 12497c478bd9Sstevel@tonic-gate udf_vfsp->udf_fsd_len = 12507c478bd9Sstevel@tonic-gate SWAP_32(udf_vfsp->udf_lvd->lvd_lvcu.lad_ext_len); 12517c478bd9Sstevel@tonic-gate 12527c478bd9Sstevel@tonic-gate 12537c478bd9Sstevel@tonic-gate /* 12547c478bd9Sstevel@tonic-gate * process paritions 12557c478bd9Sstevel@tonic-gate */ 12567c478bd9Sstevel@tonic-gate udf_vfsp->udf_mtype = udf_vfsp->udf_parts[0].udp_access; 12577c478bd9Sstevel@tonic-gate for (index = 0; index < udf_vfsp->udf_npart; index ++) { 12587c478bd9Sstevel@tonic-gate if (udf_vfsp->udf_parts[index].udp_access < 12597c478bd9Sstevel@tonic-gate udf_vfsp->udf_mtype) { 12607c478bd9Sstevel@tonic-gate udf_vfsp->udf_mtype = 12617c478bd9Sstevel@tonic-gate udf_vfsp->udf_parts[index].udp_access; 12627c478bd9Sstevel@tonic-gate } 12637c478bd9Sstevel@tonic-gate } 12647c478bd9Sstevel@tonic-gate if ((udf_vfsp->udf_mtype < UDF_MT_RO) || 12657c478bd9Sstevel@tonic-gate (udf_vfsp->udf_mtype > UDF_MT_OW)) { 12667c478bd9Sstevel@tonic-gate udf_vfsp->udf_mtype = UDF_MT_RO; 12677c478bd9Sstevel@tonic-gate } 12687c478bd9Sstevel@tonic-gate 12697c478bd9Sstevel@tonic-gate udf_vfsp->udf_nmaps = 0; 12707c478bd9Sstevel@tonic-gate hdr = (struct pmap_hdr *)udf_vfsp->udf_lvd->lvd_pmaps; 12717c478bd9Sstevel@tonic-gate count = SWAP_32(udf_vfsp->udf_lvd->lvd_num_pmaps); 12727c478bd9Sstevel@tonic-gate for (index = 0; index < count; index++) { 12737c478bd9Sstevel@tonic-gate 12747c478bd9Sstevel@tonic-gate if ((hdr->maph_type == MAP_TYPE1) && 12757c478bd9Sstevel@tonic-gate (hdr->maph_length == MAP_TYPE1_LEN)) { 12767c478bd9Sstevel@tonic-gate typ1 = (struct pmap_typ1 *)hdr; 12777c478bd9Sstevel@tonic-gate 12787c478bd9Sstevel@tonic-gate map = udf_vfsp->udf_maps; 12797c478bd9Sstevel@tonic-gate udf_vfsp->udf_maps = 12807c478bd9Sstevel@tonic-gate kmem_zalloc(sizeof (struct ud_map) * 128193239addSjohnlev (udf_vfsp->udf_nmaps + 1), KM_SLEEP); 12827c478bd9Sstevel@tonic-gate if (map != NULL) { 12837c478bd9Sstevel@tonic-gate bcopy(map, udf_vfsp->udf_maps, 128493239addSjohnlev sizeof (struct ud_map) * 128593239addSjohnlev udf_vfsp->udf_nmaps); 128693239addSjohnlev kmem_free(map, sizeof (struct ud_map) * 128793239addSjohnlev udf_vfsp->udf_nmaps); 12887c478bd9Sstevel@tonic-gate } 12897c478bd9Sstevel@tonic-gate map = udf_vfsp->udf_maps + udf_vfsp->udf_nmaps; 12907c478bd9Sstevel@tonic-gate map->udm_flags = UDM_MAP_NORM; 12917c478bd9Sstevel@tonic-gate map->udm_vsn = SWAP_16(typ1->map1_vsn); 12927c478bd9Sstevel@tonic-gate map->udm_pn = SWAP_16(typ1->map1_pn); 12937c478bd9Sstevel@tonic-gate udf_vfsp->udf_nmaps ++; 12947c478bd9Sstevel@tonic-gate } else if ((hdr->maph_type == MAP_TYPE2) && 12957c478bd9Sstevel@tonic-gate (hdr->maph_length == MAP_TYPE2_LEN)) { 12967c478bd9Sstevel@tonic-gate typ2 = (struct pmap_typ2 *)hdr; 12977c478bd9Sstevel@tonic-gate 12987c478bd9Sstevel@tonic-gate if (strncmp(typ2->map2_pti.reg_id, 12997c478bd9Sstevel@tonic-gate UDF_VIRT_PART, 23) == 0) { 13007c478bd9Sstevel@tonic-gate /* 13017c478bd9Sstevel@tonic-gate * Add this to the normal 13027c478bd9Sstevel@tonic-gate * partition table so that 13037c478bd9Sstevel@tonic-gate * we donot 13047c478bd9Sstevel@tonic-gate */ 13057c478bd9Sstevel@tonic-gate map = udf_vfsp->udf_maps; 13067c478bd9Sstevel@tonic-gate udf_vfsp->udf_maps = 13077c478bd9Sstevel@tonic-gate kmem_zalloc(sizeof (struct ud_map) * 130893239addSjohnlev (udf_vfsp->udf_nmaps + 1), KM_SLEEP); 13097c478bd9Sstevel@tonic-gate if (map != NULL) { 13107c478bd9Sstevel@tonic-gate bcopy(map, udf_vfsp->udf_maps, 13117c478bd9Sstevel@tonic-gate sizeof (struct ud_map) * 13127c478bd9Sstevel@tonic-gate udf_vfsp->udf_nmaps); 13137c478bd9Sstevel@tonic-gate kmem_free(map, 13147c478bd9Sstevel@tonic-gate sizeof (struct ud_map) * 13157c478bd9Sstevel@tonic-gate udf_vfsp->udf_nmaps); 13167c478bd9Sstevel@tonic-gate } 13177c478bd9Sstevel@tonic-gate map = udf_vfsp->udf_maps + udf_vfsp->udf_nmaps; 13187c478bd9Sstevel@tonic-gate map->udm_flags = UDM_MAP_VPM; 13197c478bd9Sstevel@tonic-gate map->udm_vsn = SWAP_16(typ2->map2_vsn); 13207c478bd9Sstevel@tonic-gate map->udm_pn = SWAP_16(typ2->map2_pn); 13217c478bd9Sstevel@tonic-gate udf_vfsp->udf_nmaps ++; 13227c478bd9Sstevel@tonic-gate if (error = ud_get_last_block(dev, &lblkno)) { 13237c478bd9Sstevel@tonic-gate goto out; 13247c478bd9Sstevel@tonic-gate } 13257c478bd9Sstevel@tonic-gate if (error = ud_val_get_vat(udf_vfsp, dev, 13267c478bd9Sstevel@tonic-gate lblkno, map)) { 13277c478bd9Sstevel@tonic-gate goto out; 13287c478bd9Sstevel@tonic-gate } 13297c478bd9Sstevel@tonic-gate } else if (strncmp(typ2->map2_pti.reg_id, 13307c478bd9Sstevel@tonic-gate UDF_SPAR_PART, 23) == 0) { 13317c478bd9Sstevel@tonic-gate 13327c478bd9Sstevel@tonic-gate if (SWAP_16(typ2->map2_pl) != 32) { 13337c478bd9Sstevel@tonic-gate printf( 13347c478bd9Sstevel@tonic-gate "Packet Length is not valid %x\n", 13357c478bd9Sstevel@tonic-gate SWAP_16(typ2->map2_pl)); 13367c478bd9Sstevel@tonic-gate goto out; 13377c478bd9Sstevel@tonic-gate } 13387c478bd9Sstevel@tonic-gate if ((typ2->map2_nst < 1) || 13397c478bd9Sstevel@tonic-gate (typ2->map2_nst > 4)) { 13407c478bd9Sstevel@tonic-gate goto out; 13417c478bd9Sstevel@tonic-gate } 13427c478bd9Sstevel@tonic-gate map = udf_vfsp->udf_maps; 13437c478bd9Sstevel@tonic-gate udf_vfsp->udf_maps = 13447c478bd9Sstevel@tonic-gate kmem_zalloc(sizeof (struct ud_map) * 13457c478bd9Sstevel@tonic-gate (udf_vfsp->udf_nmaps + 1), 13467c478bd9Sstevel@tonic-gate KM_SLEEP); 13477c478bd9Sstevel@tonic-gate if (map != NULL) { 13487c478bd9Sstevel@tonic-gate bcopy(map, udf_vfsp->udf_maps, 13497c478bd9Sstevel@tonic-gate sizeof (struct ud_map) * 13507c478bd9Sstevel@tonic-gate udf_vfsp->udf_nmaps); 13517c478bd9Sstevel@tonic-gate kmem_free(map, 13527c478bd9Sstevel@tonic-gate sizeof (struct ud_map) * 13537c478bd9Sstevel@tonic-gate udf_vfsp->udf_nmaps); 13547c478bd9Sstevel@tonic-gate } 13557c478bd9Sstevel@tonic-gate map = udf_vfsp->udf_maps + udf_vfsp->udf_nmaps; 13567c478bd9Sstevel@tonic-gate map->udm_flags = UDM_MAP_SPM; 13577c478bd9Sstevel@tonic-gate map->udm_vsn = SWAP_16(typ2->map2_vsn); 13587c478bd9Sstevel@tonic-gate map->udm_pn = SWAP_16(typ2->map2_pn); 13597c478bd9Sstevel@tonic-gate 13607c478bd9Sstevel@tonic-gate udf_vfsp->udf_nmaps ++; 13617c478bd9Sstevel@tonic-gate 13627c478bd9Sstevel@tonic-gate if (error = ud_read_sparing_tbls(udf_vfsp, 13637c478bd9Sstevel@tonic-gate dev, map, typ2)) { 13647c478bd9Sstevel@tonic-gate goto out; 13657c478bd9Sstevel@tonic-gate } 13667c478bd9Sstevel@tonic-gate } else { 13677c478bd9Sstevel@tonic-gate /* 13687c478bd9Sstevel@tonic-gate * Unknown type of partition 13697c478bd9Sstevel@tonic-gate * Bail out 13707c478bd9Sstevel@tonic-gate */ 13717c478bd9Sstevel@tonic-gate goto out; 13727c478bd9Sstevel@tonic-gate } 13737c478bd9Sstevel@tonic-gate } else { 13747c478bd9Sstevel@tonic-gate /* 13757c478bd9Sstevel@tonic-gate * Unknown type of partition 13767c478bd9Sstevel@tonic-gate * Bail out 13777c478bd9Sstevel@tonic-gate */ 13787c478bd9Sstevel@tonic-gate goto out; 13797c478bd9Sstevel@tonic-gate } 13807c478bd9Sstevel@tonic-gate hdr = (struct pmap_hdr *)(((uint8_t *)hdr) + hdr->maph_length); 13817c478bd9Sstevel@tonic-gate } 13827c478bd9Sstevel@tonic-gate 13837c478bd9Sstevel@tonic-gate 13847c478bd9Sstevel@tonic-gate /* 13857c478bd9Sstevel@tonic-gate * Read Logical Volume Integrity Sequence 13867c478bd9Sstevel@tonic-gate * and process it 13877c478bd9Sstevel@tonic-gate */ 13887c478bd9Sstevel@tonic-gate secbp = ud_bread(dev, udf_vfsp->udf_iseq_loc << shift, 13897c478bd9Sstevel@tonic-gate udf_vfsp->udf_iseq_len); 13907c478bd9Sstevel@tonic-gate if ((error = geterror(secbp)) != 0) { 13917c478bd9Sstevel@tonic-gate cmn_err(CE_NOTE, 13927c478bd9Sstevel@tonic-gate "udfs : Could not read Logical Volume Integrity Sequence %x", 13937c478bd9Sstevel@tonic-gate error); 13947c478bd9Sstevel@tonic-gate brelse(secbp); 13957c478bd9Sstevel@tonic-gate goto out; 13967c478bd9Sstevel@tonic-gate } 13977c478bd9Sstevel@tonic-gate udf_vfsp->udf_iseq = ngeteblk(udf_vfsp->udf_iseq_len); 13987c478bd9Sstevel@tonic-gate bp = udf_vfsp->udf_iseq; 13997c478bd9Sstevel@tonic-gate bp->b_edev = dev; 14007c478bd9Sstevel@tonic-gate bp->b_dev = cmpdev(dev); 14017c478bd9Sstevel@tonic-gate bp->b_blkno = udf_vfsp->udf_iseq_loc << shift; 14027c478bd9Sstevel@tonic-gate bp->b_bcount = udf_vfsp->udf_iseq_len; 14037c478bd9Sstevel@tonic-gate bcopy(secbp->b_un.b_addr, bp->b_un.b_addr, udf_vfsp->udf_iseq_len); 14047c478bd9Sstevel@tonic-gate secbp->b_flags |= B_STALE | B_AGE; 14057c478bd9Sstevel@tonic-gate brelse(secbp); 14067c478bd9Sstevel@tonic-gate 14077c478bd9Sstevel@tonic-gate count = udf_vfsp->udf_iseq_len / DEV_BSIZE; 14087c478bd9Sstevel@tonic-gate addr = bp->b_un.b_addr; 14097c478bd9Sstevel@tonic-gate for (index = 0; index < count; index ++) { 14107c478bd9Sstevel@tonic-gate ttag = (struct tag *)(addr + index * DEV_BSIZE); 14117c478bd9Sstevel@tonic-gate desc_len = udf_vfsp->udf_iseq_len - (index * DEV_BSIZE); 14127c478bd9Sstevel@tonic-gate if (ud_verify_tag_and_desc(ttag, UD_LOG_VOL_INT, 14137c478bd9Sstevel@tonic-gate udf_vfsp->udf_iseq_loc + (index >> shift), 14147c478bd9Sstevel@tonic-gate 1, desc_len) == 0) { 14157c478bd9Sstevel@tonic-gate 14167c478bd9Sstevel@tonic-gate struct log_vol_int_desc *lvid; 14177c478bd9Sstevel@tonic-gate 14187c478bd9Sstevel@tonic-gate lvid = (struct log_vol_int_desc *)ttag; 14197c478bd9Sstevel@tonic-gate udf_vfsp->udf_lvid = lvid; 14207c478bd9Sstevel@tonic-gate 14217c478bd9Sstevel@tonic-gate if (SWAP_32(lvid->lvid_int_type) == LOG_VOL_CLOSE_INT) { 14227c478bd9Sstevel@tonic-gate udf_vfsp->udf_clean = UDF_CLEAN; 14237c478bd9Sstevel@tonic-gate } else { 14247c478bd9Sstevel@tonic-gate udf_vfsp->udf_clean = UDF_DIRTY; 14257c478bd9Sstevel@tonic-gate } 14267c478bd9Sstevel@tonic-gate 14277c478bd9Sstevel@tonic-gate /* 14287c478bd9Sstevel@tonic-gate * update superblock with the metadata 14297c478bd9Sstevel@tonic-gate */ 14307c478bd9Sstevel@tonic-gate ud_convert_to_superblock(udf_vfsp, lvid); 14317c478bd9Sstevel@tonic-gate break; 14327c478bd9Sstevel@tonic-gate } 14337c478bd9Sstevel@tonic-gate } 14347c478bd9Sstevel@tonic-gate 14357c478bd9Sstevel@tonic-gate if (udf_vfsp->udf_lvid == NULL) { 14367c478bd9Sstevel@tonic-gate goto out; 14377c478bd9Sstevel@tonic-gate } 14387c478bd9Sstevel@tonic-gate 14397c478bd9Sstevel@tonic-gate if ((blkno = ud_xlate_to_daddr(udf_vfsp, 14407c478bd9Sstevel@tonic-gate udf_vfsp->udf_fsd_prn, udf_vfsp->udf_fsd_loc, 14417c478bd9Sstevel@tonic-gate 1, &dummy)) == 0) { 14427c478bd9Sstevel@tonic-gate goto out; 14437c478bd9Sstevel@tonic-gate } 14447c478bd9Sstevel@tonic-gate secbp = ud_bread(dev, blkno << shift, udf_vfsp->udf_fsd_len); 14457c478bd9Sstevel@tonic-gate if ((error = geterror(secbp)) != 0) { 14467c478bd9Sstevel@tonic-gate cmn_err(CE_NOTE, 14477c478bd9Sstevel@tonic-gate "udfs : Could not read File Set Descriptor %x", error); 14487c478bd9Sstevel@tonic-gate brelse(secbp); 14497c478bd9Sstevel@tonic-gate goto out; 14507c478bd9Sstevel@tonic-gate } 14517c478bd9Sstevel@tonic-gate fsd = (struct file_set_desc *)secbp->b_un.b_addr; 14527c478bd9Sstevel@tonic-gate if (ud_verify_tag_and_desc(&fsd->fsd_tag, UD_FILE_SET_DESC, 14537c478bd9Sstevel@tonic-gate udf_vfsp->udf_fsd_loc, 14547c478bd9Sstevel@tonic-gate 1, udf_vfsp->udf_fsd_len) != 0) { 14557c478bd9Sstevel@tonic-gate secbp->b_flags = B_AGE | B_STALE; 14567c478bd9Sstevel@tonic-gate brelse(secbp); 14577c478bd9Sstevel@tonic-gate goto out; 14587c478bd9Sstevel@tonic-gate } 14597c478bd9Sstevel@tonic-gate udf_vfsp->udf_ricb_prn = SWAP_16(fsd->fsd_root_icb.lad_ext_prn); 14607c478bd9Sstevel@tonic-gate udf_vfsp->udf_ricb_loc = SWAP_32(fsd->fsd_root_icb.lad_ext_loc); 14617c478bd9Sstevel@tonic-gate udf_vfsp->udf_ricb_len = SWAP_32(fsd->fsd_root_icb.lad_ext_len); 14627c478bd9Sstevel@tonic-gate secbp->b_flags = B_AGE | B_STALE; 14637c478bd9Sstevel@tonic-gate brelse(secbp); 14647c478bd9Sstevel@tonic-gate udf_vfsp->udf_root_blkno = ud_xlate_to_daddr(udf_vfsp, 14657c478bd9Sstevel@tonic-gate udf_vfsp->udf_ricb_prn, udf_vfsp->udf_ricb_loc, 14667c478bd9Sstevel@tonic-gate 1, &dummy); 14677c478bd9Sstevel@tonic-gate 14687c478bd9Sstevel@tonic-gate return (udf_vfsp); 14697c478bd9Sstevel@tonic-gate out: 14707c478bd9Sstevel@tonic-gate ud_destroy_fsp(udf_vfsp); 14717c478bd9Sstevel@tonic-gate 14727c478bd9Sstevel@tonic-gate return (NULL); 14737c478bd9Sstevel@tonic-gate } 14747c478bd9Sstevel@tonic-gate 14757c478bd9Sstevel@tonic-gate /* 14767c478bd9Sstevel@tonic-gate * release/free resources from one ud_map; map data was zalloc'd in 14777c478bd9Sstevel@tonic-gate * ud_validate_and_fill_superblock() and fields may later point to 14787c478bd9Sstevel@tonic-gate * valid data 14797c478bd9Sstevel@tonic-gate */ 14807c478bd9Sstevel@tonic-gate static void 14817c478bd9Sstevel@tonic-gate ud_free_map(struct ud_map *map) 14827c478bd9Sstevel@tonic-gate { 14837c478bd9Sstevel@tonic-gate uint32_t n; 14847c478bd9Sstevel@tonic-gate 14857c478bd9Sstevel@tonic-gate if (map->udm_flags & UDM_MAP_VPM) { 14867c478bd9Sstevel@tonic-gate if (map->udm_count) { 14877c478bd9Sstevel@tonic-gate kmem_free(map->udm_count, 14887c478bd9Sstevel@tonic-gate map->udm_nent * sizeof (*map->udm_count)); 14897c478bd9Sstevel@tonic-gate map->udm_count = NULL; 14907c478bd9Sstevel@tonic-gate } 14917c478bd9Sstevel@tonic-gate if (map->udm_bp) { 14927c478bd9Sstevel@tonic-gate for (n = 0; n < map->udm_nent; n++) { 14937c478bd9Sstevel@tonic-gate if (map->udm_bp[n]) 14947c478bd9Sstevel@tonic-gate brelse(map->udm_bp[n]); 14957c478bd9Sstevel@tonic-gate } 14967c478bd9Sstevel@tonic-gate kmem_free(map->udm_bp, 14977c478bd9Sstevel@tonic-gate map->udm_nent * sizeof (*map->udm_bp)); 14987c478bd9Sstevel@tonic-gate map->udm_bp = NULL; 14997c478bd9Sstevel@tonic-gate } 15007c478bd9Sstevel@tonic-gate if (map->udm_addr) { 15017c478bd9Sstevel@tonic-gate kmem_free(map->udm_addr, 15027c478bd9Sstevel@tonic-gate map->udm_nent * sizeof (*map->udm_addr)); 15037c478bd9Sstevel@tonic-gate map->udm_addr = NULL; 15047c478bd9Sstevel@tonic-gate } 15057c478bd9Sstevel@tonic-gate } 15067c478bd9Sstevel@tonic-gate if (map->udm_flags & UDM_MAP_SPM) { 15077c478bd9Sstevel@tonic-gate for (n = 0; n < MAX_SPM; n++) { 15087c478bd9Sstevel@tonic-gate if (map->udm_sbp[n]) { 15097c478bd9Sstevel@tonic-gate brelse(map->udm_sbp[n]); 15107c478bd9Sstevel@tonic-gate map->udm_sbp[n] = NULL; 15117c478bd9Sstevel@tonic-gate map->udm_spaddr[n] = NULL; 15127c478bd9Sstevel@tonic-gate } 15137c478bd9Sstevel@tonic-gate } 15147c478bd9Sstevel@tonic-gate } 15157c478bd9Sstevel@tonic-gate } 15167c478bd9Sstevel@tonic-gate 15177c478bd9Sstevel@tonic-gate void 15187c478bd9Sstevel@tonic-gate ud_destroy_fsp(struct udf_vfs *udf_vfsp) 15197c478bd9Sstevel@tonic-gate { 15207c478bd9Sstevel@tonic-gate int32_t i; 15217c478bd9Sstevel@tonic-gate 15227c478bd9Sstevel@tonic-gate ud_printf("ud_destroy_fsp\n"); 15237c478bd9Sstevel@tonic-gate if (udf_vfsp == NULL) 15247c478bd9Sstevel@tonic-gate return; 15257c478bd9Sstevel@tonic-gate 15267c478bd9Sstevel@tonic-gate if (udf_vfsp->udf_maps) { 15277c478bd9Sstevel@tonic-gate for (i = 0; i < udf_vfsp->udf_nmaps; i++) 15287c478bd9Sstevel@tonic-gate ud_free_map(&udf_vfsp->udf_maps[i]); 15297c478bd9Sstevel@tonic-gate 15307c478bd9Sstevel@tonic-gate kmem_free(udf_vfsp->udf_maps, 15317c478bd9Sstevel@tonic-gate udf_vfsp->udf_nmaps * sizeof (*udf_vfsp->udf_maps)); 15327c478bd9Sstevel@tonic-gate } 15337c478bd9Sstevel@tonic-gate 15347c478bd9Sstevel@tonic-gate if (udf_vfsp->udf_parts) { 15357c478bd9Sstevel@tonic-gate kmem_free(udf_vfsp->udf_parts, 15367c478bd9Sstevel@tonic-gate udf_vfsp->udf_npart * sizeof (*udf_vfsp->udf_parts)); 15377c478bd9Sstevel@tonic-gate } 15387c478bd9Sstevel@tonic-gate if (udf_vfsp->udf_iseq) { 15397c478bd9Sstevel@tonic-gate udf_vfsp->udf_iseq->b_flags |= (B_STALE|B_AGE); 15407c478bd9Sstevel@tonic-gate brelse(udf_vfsp->udf_iseq); 15417c478bd9Sstevel@tonic-gate } 15427c478bd9Sstevel@tonic-gate if (udf_vfsp->udf_vds) { 15437c478bd9Sstevel@tonic-gate udf_vfsp->udf_vds->b_flags |= (B_STALE|B_AGE); 15447c478bd9Sstevel@tonic-gate brelse(udf_vfsp->udf_vds); 15457c478bd9Sstevel@tonic-gate } 15467c478bd9Sstevel@tonic-gate if (udf_vfsp->udf_vfs) 15477c478bd9Sstevel@tonic-gate ud_vfs_remove(udf_vfsp); 15487c478bd9Sstevel@tonic-gate if (udf_vfsp->udf_fsmnt) { 15497c478bd9Sstevel@tonic-gate kmem_free(udf_vfsp->udf_fsmnt, 15507c478bd9Sstevel@tonic-gate strlen(udf_vfsp->udf_fsmnt) + 1); 15517c478bd9Sstevel@tonic-gate } 15527c478bd9Sstevel@tonic-gate kmem_free(udf_vfsp, sizeof (*udf_vfsp)); 15537c478bd9Sstevel@tonic-gate } 15547c478bd9Sstevel@tonic-gate 15557c478bd9Sstevel@tonic-gate void 15567c478bd9Sstevel@tonic-gate ud_convert_to_superblock(struct udf_vfs *udf_vfsp, 15577c478bd9Sstevel@tonic-gate struct log_vol_int_desc *lvid) 15587c478bd9Sstevel@tonic-gate { 15597c478bd9Sstevel@tonic-gate int32_t i, c; 15607c478bd9Sstevel@tonic-gate uint32_t *temp; 15617c478bd9Sstevel@tonic-gate struct ud_part *ud_part; 15627c478bd9Sstevel@tonic-gate struct lvid_iu *iu; 15637c478bd9Sstevel@tonic-gate 15647c478bd9Sstevel@tonic-gate udf_vfsp->udf_maxuniq = SWAP_64(lvid->lvid_uniqid); 15657c478bd9Sstevel@tonic-gate temp = lvid->lvid_fst; 15667c478bd9Sstevel@tonic-gate c = SWAP_32(lvid->lvid_npart); 15677c478bd9Sstevel@tonic-gate ud_part = udf_vfsp->udf_parts; 15687c478bd9Sstevel@tonic-gate for (i = 0; i < c; i++) { 15697c478bd9Sstevel@tonic-gate if (i >= udf_vfsp->udf_npart) { 15707c478bd9Sstevel@tonic-gate continue; 15717c478bd9Sstevel@tonic-gate } 15727c478bd9Sstevel@tonic-gate ud_part->udp_nfree = SWAP_32(temp[i]); 15737c478bd9Sstevel@tonic-gate ud_part->udp_nblocks = SWAP_32(temp[c + i]); 15747c478bd9Sstevel@tonic-gate udf_vfsp->udf_freeblks += SWAP_32(temp[i]); 15757c478bd9Sstevel@tonic-gate udf_vfsp->udf_totalblks += SWAP_32(temp[c + i]); 15767c478bd9Sstevel@tonic-gate ud_part++; 15777c478bd9Sstevel@tonic-gate } 15787c478bd9Sstevel@tonic-gate 15797c478bd9Sstevel@tonic-gate iu = (struct lvid_iu *)(temp + c * 2); 15807c478bd9Sstevel@tonic-gate udf_vfsp->udf_nfiles = SWAP_32(iu->lvidiu_nfiles); 15817c478bd9Sstevel@tonic-gate udf_vfsp->udf_ndirs = SWAP_32(iu->lvidiu_ndirs); 15827c478bd9Sstevel@tonic-gate udf_vfsp->udf_miread = BCD2HEX_16(SWAP_16(iu->lvidiu_mread)); 15837c478bd9Sstevel@tonic-gate udf_vfsp->udf_miwrite = BCD2HEX_16(SWAP_16(iu->lvidiu_mwrite)); 15847c478bd9Sstevel@tonic-gate udf_vfsp->udf_mawrite = BCD2HEX_16(SWAP_16(iu->lvidiu_maxwr)); 15857c478bd9Sstevel@tonic-gate } 15867c478bd9Sstevel@tonic-gate 15877c478bd9Sstevel@tonic-gate void 15887c478bd9Sstevel@tonic-gate ud_update_superblock(struct vfs *vfsp) 15897c478bd9Sstevel@tonic-gate { 15907c478bd9Sstevel@tonic-gate struct udf_vfs *udf_vfsp; 15917c478bd9Sstevel@tonic-gate 15927c478bd9Sstevel@tonic-gate ud_printf("ud_update_superblock\n"); 15937c478bd9Sstevel@tonic-gate 15947c478bd9Sstevel@tonic-gate udf_vfsp = (struct udf_vfs *)vfsp->vfs_data; 15957c478bd9Sstevel@tonic-gate 15967c478bd9Sstevel@tonic-gate mutex_enter(&udf_vfsp->udf_lock); 15977c478bd9Sstevel@tonic-gate ud_sbwrite(udf_vfsp); 15987c478bd9Sstevel@tonic-gate mutex_exit(&udf_vfsp->udf_lock); 15997c478bd9Sstevel@tonic-gate } 16007c478bd9Sstevel@tonic-gate 16017c478bd9Sstevel@tonic-gate 16027c478bd9Sstevel@tonic-gate #include <sys/dkio.h> 16037c478bd9Sstevel@tonic-gate #include <sys/cdio.h> 16047c478bd9Sstevel@tonic-gate #include <sys/vtoc.h> 16057c478bd9Sstevel@tonic-gate 16067c478bd9Sstevel@tonic-gate /* 16077c478bd9Sstevel@tonic-gate * This part of the code is known 16087c478bd9Sstevel@tonic-gate * to work with only sparc. It needs 16097c478bd9Sstevel@tonic-gate * to be evluated before using it with x86 16107c478bd9Sstevel@tonic-gate */ 16117c478bd9Sstevel@tonic-gate int32_t 16127c478bd9Sstevel@tonic-gate ud_get_last_block(dev_t dev, daddr_t *blkno) 16137c478bd9Sstevel@tonic-gate { 16147c478bd9Sstevel@tonic-gate struct vtoc vtoc; 16157c478bd9Sstevel@tonic-gate struct dk_cinfo dki_info; 16167c478bd9Sstevel@tonic-gate int32_t rval, error; 16177c478bd9Sstevel@tonic-gate 16187c478bd9Sstevel@tonic-gate if ((error = cdev_ioctl(dev, DKIOCGVTOC, (intptr_t)&vtoc, 16197c478bd9Sstevel@tonic-gate FKIOCTL|FREAD|FNATIVE, CRED(), &rval)) != 0) { 16207c478bd9Sstevel@tonic-gate cmn_err(CE_NOTE, "Could not get the vtoc information"); 16217c478bd9Sstevel@tonic-gate return (error); 16227c478bd9Sstevel@tonic-gate } 16237c478bd9Sstevel@tonic-gate 16247c478bd9Sstevel@tonic-gate if (vtoc.v_sanity != VTOC_SANE) { 16257c478bd9Sstevel@tonic-gate return (EINVAL); 16267c478bd9Sstevel@tonic-gate } 16277c478bd9Sstevel@tonic-gate if ((error = cdev_ioctl(dev, DKIOCINFO, (intptr_t)&dki_info, 16287c478bd9Sstevel@tonic-gate FKIOCTL|FREAD|FNATIVE, CRED(), &rval)) != 0) { 16297c478bd9Sstevel@tonic-gate cmn_err(CE_NOTE, "Could not get the slice information"); 16307c478bd9Sstevel@tonic-gate return (error); 16317c478bd9Sstevel@tonic-gate } 16327c478bd9Sstevel@tonic-gate 16337c478bd9Sstevel@tonic-gate if (dki_info.dki_partition > V_NUMPAR) { 16347c478bd9Sstevel@tonic-gate return (EINVAL); 16357c478bd9Sstevel@tonic-gate } 16367c478bd9Sstevel@tonic-gate 16377c478bd9Sstevel@tonic-gate 16387c478bd9Sstevel@tonic-gate *blkno = vtoc.v_part[dki_info.dki_partition].p_size; 16397c478bd9Sstevel@tonic-gate 16407c478bd9Sstevel@tonic-gate return (0); 16417c478bd9Sstevel@tonic-gate } 16427c478bd9Sstevel@tonic-gate 16437c478bd9Sstevel@tonic-gate /* Search sequentially N - 2, N, N - 152, N - 150 for vat icb */ 16447c478bd9Sstevel@tonic-gate /* 16457c478bd9Sstevel@tonic-gate * int32_t ud_sub_blks[] = {2, 0, 152, 150}; 16467c478bd9Sstevel@tonic-gate */ 16477c478bd9Sstevel@tonic-gate int32_t ud_sub_blks[] = {152, 150, 2, 0}; 16487c478bd9Sstevel@tonic-gate int32_t ud_sub_count = 4; 16497c478bd9Sstevel@tonic-gate 16507c478bd9Sstevel@tonic-gate /* 16517c478bd9Sstevel@tonic-gate * Validate the VAT ICB 16527c478bd9Sstevel@tonic-gate */ 16537c478bd9Sstevel@tonic-gate static int32_t 16547c478bd9Sstevel@tonic-gate ud_val_get_vat(struct udf_vfs *udf_vfsp, dev_t dev, 16557c478bd9Sstevel@tonic-gate daddr_t blkno, struct ud_map *udm) 16567c478bd9Sstevel@tonic-gate { 16577c478bd9Sstevel@tonic-gate struct buf *secbp; 16587c478bd9Sstevel@tonic-gate struct file_entry *fe; 16597c478bd9Sstevel@tonic-gate int32_t end_loc, i, j, ad_type; 16607c478bd9Sstevel@tonic-gate struct short_ad *sad; 16617c478bd9Sstevel@tonic-gate struct long_ad *lad; 16627c478bd9Sstevel@tonic-gate uint32_t count, blk; 16637c478bd9Sstevel@tonic-gate struct ud_part *ud_part; 16647c478bd9Sstevel@tonic-gate int err = 0; 16657c478bd9Sstevel@tonic-gate 16667c478bd9Sstevel@tonic-gate end_loc = (blkno >> udf_vfsp->udf_l2d_shift) - 1; 16677c478bd9Sstevel@tonic-gate 16687c478bd9Sstevel@tonic-gate for (i = 0; i < ud_sub_count; i++) { 16697c478bd9Sstevel@tonic-gate udm->udm_vat_icb = end_loc - ud_sub_blks[i]; 16707c478bd9Sstevel@tonic-gate 16717c478bd9Sstevel@tonic-gate secbp = ud_bread(dev, 16727c478bd9Sstevel@tonic-gate udm->udm_vat_icb << udf_vfsp->udf_l2d_shift, 16737c478bd9Sstevel@tonic-gate udf_vfsp->udf_lbsize); 16747c478bd9Sstevel@tonic-gate ASSERT(secbp->b_un.b_addr); 16757c478bd9Sstevel@tonic-gate 16767c478bd9Sstevel@tonic-gate fe = (struct file_entry *)secbp->b_un.b_addr; 16777c478bd9Sstevel@tonic-gate if (ud_verify_tag_and_desc(&fe->fe_tag, UD_FILE_ENTRY, 0, 16787c478bd9Sstevel@tonic-gate 0, 0) == 0) { 16797c478bd9Sstevel@tonic-gate if (ud_verify_tag_and_desc(&fe->fe_tag, UD_FILE_ENTRY, 16807c478bd9Sstevel@tonic-gate SWAP_32(fe->fe_tag.tag_loc), 16817c478bd9Sstevel@tonic-gate 1, udf_vfsp->udf_lbsize) == 0) { 16827c478bd9Sstevel@tonic-gate if (fe->fe_icb_tag.itag_ftype == 0) { 16837c478bd9Sstevel@tonic-gate break; 16847c478bd9Sstevel@tonic-gate } 16857c478bd9Sstevel@tonic-gate } 16867c478bd9Sstevel@tonic-gate } 16877c478bd9Sstevel@tonic-gate secbp->b_flags |= B_AGE | B_STALE; 16887c478bd9Sstevel@tonic-gate brelse(secbp); 16897c478bd9Sstevel@tonic-gate } 16907c478bd9Sstevel@tonic-gate if (i == ud_sub_count) { 16917c478bd9Sstevel@tonic-gate return (EINVAL); 16927c478bd9Sstevel@tonic-gate } 16937c478bd9Sstevel@tonic-gate 16947c478bd9Sstevel@tonic-gate ad_type = SWAP_16(fe->fe_icb_tag.itag_flags) & 0x3; 16957c478bd9Sstevel@tonic-gate if (ad_type == ICB_FLAG_ONE_AD) { 16967c478bd9Sstevel@tonic-gate udm->udm_nent = 1; 16977c478bd9Sstevel@tonic-gate } else if (ad_type == ICB_FLAG_SHORT_AD) { 16987c478bd9Sstevel@tonic-gate udm->udm_nent = 16997c478bd9Sstevel@tonic-gate SWAP_32(fe->fe_len_adesc) / sizeof (struct short_ad); 17007c478bd9Sstevel@tonic-gate } else if (ad_type == ICB_FLAG_LONG_AD) { 17017c478bd9Sstevel@tonic-gate udm->udm_nent = 17027c478bd9Sstevel@tonic-gate SWAP_32(fe->fe_len_adesc) / sizeof (struct long_ad); 17037c478bd9Sstevel@tonic-gate } else { 17047c478bd9Sstevel@tonic-gate err = EINVAL; 17057c478bd9Sstevel@tonic-gate goto end; 17067c478bd9Sstevel@tonic-gate } 17077c478bd9Sstevel@tonic-gate 17087c478bd9Sstevel@tonic-gate udm->udm_count = kmem_zalloc(udm->udm_nent * sizeof (*udm->udm_count), 17097c478bd9Sstevel@tonic-gate KM_SLEEP); 17107c478bd9Sstevel@tonic-gate udm->udm_bp = kmem_zalloc(udm->udm_nent * sizeof (*udm->udm_bp), 17117c478bd9Sstevel@tonic-gate KM_SLEEP); 17127c478bd9Sstevel@tonic-gate udm->udm_addr = kmem_zalloc(udm->udm_nent * sizeof (*udm->udm_addr), 17137c478bd9Sstevel@tonic-gate KM_SLEEP); 17147c478bd9Sstevel@tonic-gate 17157c478bd9Sstevel@tonic-gate if (ad_type == ICB_FLAG_ONE_AD) { 17167c478bd9Sstevel@tonic-gate udm->udm_count[0] = (SWAP_64(fe->fe_info_len) - 36) / 17177c478bd9Sstevel@tonic-gate sizeof (uint32_t); 17187c478bd9Sstevel@tonic-gate udm->udm_bp[0] = secbp; 17197c478bd9Sstevel@tonic-gate udm->udm_addr[0] = (uint32_t *) 17207c478bd9Sstevel@tonic-gate &fe->fe_spec[SWAP_32(fe->fe_len_ear)]; 17217c478bd9Sstevel@tonic-gate return (0); 17227c478bd9Sstevel@tonic-gate } 17237c478bd9Sstevel@tonic-gate for (i = 0; i < udm->udm_nent; i++) { 17247c478bd9Sstevel@tonic-gate if (ad_type == ICB_FLAG_SHORT_AD) { 17257c478bd9Sstevel@tonic-gate sad = (struct short_ad *) 17267c478bd9Sstevel@tonic-gate (fe->fe_spec + SWAP_32(fe->fe_len_ear)); 17277c478bd9Sstevel@tonic-gate sad += i; 17287c478bd9Sstevel@tonic-gate count = SWAP_32(sad->sad_ext_len); 17297c478bd9Sstevel@tonic-gate blk = SWAP_32(sad->sad_ext_loc); 17307c478bd9Sstevel@tonic-gate } else { 17317c478bd9Sstevel@tonic-gate lad = (struct long_ad *) 17327c478bd9Sstevel@tonic-gate (fe->fe_spec + SWAP_32(fe->fe_len_ear)); 17337c478bd9Sstevel@tonic-gate lad += i; 17347c478bd9Sstevel@tonic-gate count = SWAP_32(lad->lad_ext_len); 17357c478bd9Sstevel@tonic-gate blk = SWAP_32(lad->lad_ext_loc); 17367c478bd9Sstevel@tonic-gate ASSERT(SWAP_16(lad->lad_ext_prn) == udm->udm_pn); 17377c478bd9Sstevel@tonic-gate } 17387c478bd9Sstevel@tonic-gate if ((count & 0x3FFFFFFF) == 0) { 17397c478bd9Sstevel@tonic-gate break; 17407c478bd9Sstevel@tonic-gate } 17417c478bd9Sstevel@tonic-gate if (i < udm->udm_nent - 1) { 17427c478bd9Sstevel@tonic-gate udm->udm_count[i] = count / 4; 17437c478bd9Sstevel@tonic-gate } else { 17447c478bd9Sstevel@tonic-gate udm->udm_count[i] = (count - 36) / 4; 17457c478bd9Sstevel@tonic-gate } 17467c478bd9Sstevel@tonic-gate ud_part = udf_vfsp->udf_parts; 17477c478bd9Sstevel@tonic-gate for (j = 0; j < udf_vfsp->udf_npart; j++) { 17487c478bd9Sstevel@tonic-gate if (udm->udm_pn == ud_part->udp_number) { 17497c478bd9Sstevel@tonic-gate blk = ud_part->udp_start + blk; 17507c478bd9Sstevel@tonic-gate break; 17517c478bd9Sstevel@tonic-gate } 17527c478bd9Sstevel@tonic-gate } 17537c478bd9Sstevel@tonic-gate if (j == udf_vfsp->udf_npart) { 17547c478bd9Sstevel@tonic-gate err = EINVAL; 17557c478bd9Sstevel@tonic-gate break; 17567c478bd9Sstevel@tonic-gate } 17577c478bd9Sstevel@tonic-gate 17587c478bd9Sstevel@tonic-gate count = (count + DEV_BSIZE - 1) & ~(DEV_BSIZE - 1); 17597c478bd9Sstevel@tonic-gate udm->udm_bp[i] = ud_bread(dev, 17607c478bd9Sstevel@tonic-gate blk << udf_vfsp->udf_l2d_shift, count); 17617c478bd9Sstevel@tonic-gate if ((udm->udm_bp[i]->b_error != 0) || 17627c478bd9Sstevel@tonic-gate (udm->udm_bp[i]->b_resid)) { 17637c478bd9Sstevel@tonic-gate err = EINVAL; 17647c478bd9Sstevel@tonic-gate break; 17657c478bd9Sstevel@tonic-gate } 17667c478bd9Sstevel@tonic-gate udm->udm_addr[i] = (uint32_t *)udm->udm_bp[i]->b_un.b_addr; 17677c478bd9Sstevel@tonic-gate } 17687c478bd9Sstevel@tonic-gate 17697c478bd9Sstevel@tonic-gate end: 17707c478bd9Sstevel@tonic-gate if (err) 17717c478bd9Sstevel@tonic-gate ud_free_map(udm); 17727c478bd9Sstevel@tonic-gate secbp->b_flags |= B_AGE | B_STALE; 17737c478bd9Sstevel@tonic-gate brelse(secbp); 17747c478bd9Sstevel@tonic-gate return (err); 17757c478bd9Sstevel@tonic-gate } 17767c478bd9Sstevel@tonic-gate 17777c478bd9Sstevel@tonic-gate int32_t 17787c478bd9Sstevel@tonic-gate ud_read_sparing_tbls(struct udf_vfs *udf_vfsp, 17797c478bd9Sstevel@tonic-gate dev_t dev, struct ud_map *map, struct pmap_typ2 *typ2) 17807c478bd9Sstevel@tonic-gate { 17817c478bd9Sstevel@tonic-gate int32_t index, valid = 0; 17827c478bd9Sstevel@tonic-gate uint32_t sz; 17837c478bd9Sstevel@tonic-gate struct buf *bp; 17847c478bd9Sstevel@tonic-gate struct stbl *stbl; 17857c478bd9Sstevel@tonic-gate 17867c478bd9Sstevel@tonic-gate map->udm_plen = SWAP_16(typ2->map2_pl); 17877c478bd9Sstevel@tonic-gate map->udm_nspm = typ2->map2_nst; 17887c478bd9Sstevel@tonic-gate map->udm_spsz = SWAP_32(typ2->map2_sest); 17897c478bd9Sstevel@tonic-gate sz = (map->udm_spsz + udf_vfsp->udf_lbmask) & ~udf_vfsp->udf_lbmask; 17907c478bd9Sstevel@tonic-gate if (sz == 0) { 17917c478bd9Sstevel@tonic-gate return (0); 17927c478bd9Sstevel@tonic-gate } 17937c478bd9Sstevel@tonic-gate 17947c478bd9Sstevel@tonic-gate for (index = 0; index < map->udm_nspm; index++) { 17957c478bd9Sstevel@tonic-gate map->udm_loc[index] = SWAP_32(typ2->map2_st[index]); 17967c478bd9Sstevel@tonic-gate 17977c478bd9Sstevel@tonic-gate bp = ud_bread(dev, 17987c478bd9Sstevel@tonic-gate map->udm_loc[index] << udf_vfsp->udf_l2d_shift, sz); 17997c478bd9Sstevel@tonic-gate if ((bp->b_error != 0) || (bp->b_resid)) { 18007c478bd9Sstevel@tonic-gate brelse(bp); 18017c478bd9Sstevel@tonic-gate continue; 18027c478bd9Sstevel@tonic-gate } 18037c478bd9Sstevel@tonic-gate stbl = (struct stbl *)bp->b_un.b_addr; 18047c478bd9Sstevel@tonic-gate if (strncmp(stbl->stbl_si.reg_id, UDF_SPAR_TBL, 23) != 0) { 18057c478bd9Sstevel@tonic-gate printf("Sparing Identifier does not match\n"); 18067c478bd9Sstevel@tonic-gate bp->b_flags |= B_AGE | B_STALE; 18077c478bd9Sstevel@tonic-gate brelse(bp); 18087c478bd9Sstevel@tonic-gate continue; 18097c478bd9Sstevel@tonic-gate } 18107c478bd9Sstevel@tonic-gate map->udm_sbp[index] = bp; 18117c478bd9Sstevel@tonic-gate map->udm_spaddr[index] = bp->b_un.b_addr; 18127c478bd9Sstevel@tonic-gate #ifdef UNDEF 18137c478bd9Sstevel@tonic-gate { 18147c478bd9Sstevel@tonic-gate struct stbl_entry *te; 18157c478bd9Sstevel@tonic-gate int32_t i, tbl_len; 18167c478bd9Sstevel@tonic-gate 18177c478bd9Sstevel@tonic-gate te = (struct stbl_entry *)&stbl->stbl_entry; 18187c478bd9Sstevel@tonic-gate tbl_len = SWAP_16(stbl->stbl_len); 18197c478bd9Sstevel@tonic-gate 18207c478bd9Sstevel@tonic-gate printf("%x %x\n", tbl_len, SWAP_32(stbl->stbl_seqno)); 18217c478bd9Sstevel@tonic-gate printf("%x %x\n", bp->b_un.b_addr, te); 18227c478bd9Sstevel@tonic-gate 18237c478bd9Sstevel@tonic-gate for (i = 0; i < tbl_len; i++) { 18247c478bd9Sstevel@tonic-gate printf("%x %x\n", SWAP_32(te->sent_ol), SWAP_32(te->sent_ml)); 18257c478bd9Sstevel@tonic-gate te ++; 18267c478bd9Sstevel@tonic-gate } 18277c478bd9Sstevel@tonic-gate } 18287c478bd9Sstevel@tonic-gate #endif 18297c478bd9Sstevel@tonic-gate valid ++; 18307c478bd9Sstevel@tonic-gate } 18317c478bd9Sstevel@tonic-gate 18327c478bd9Sstevel@tonic-gate if (valid) { 18337c478bd9Sstevel@tonic-gate return (0); 18347c478bd9Sstevel@tonic-gate } 18357c478bd9Sstevel@tonic-gate return (EINVAL); 18367c478bd9Sstevel@tonic-gate } 18377c478bd9Sstevel@tonic-gate 18387c478bd9Sstevel@tonic-gate uint32_t 18397c478bd9Sstevel@tonic-gate ud_get_lbsize(dev_t dev, uint32_t *loc) 18407c478bd9Sstevel@tonic-gate { 18417c478bd9Sstevel@tonic-gate int32_t bsize, shift, index, end_index; 18427c478bd9Sstevel@tonic-gate daddr_t last_block; 18437c478bd9Sstevel@tonic-gate uint32_t avd_loc; 18447c478bd9Sstevel@tonic-gate struct buf *bp; 18457c478bd9Sstevel@tonic-gate struct anch_vol_desc_ptr *avdp; 18467c478bd9Sstevel@tonic-gate uint32_t session_offset = 0; 18477c478bd9Sstevel@tonic-gate int32_t rval; 18487c478bd9Sstevel@tonic-gate 18497c478bd9Sstevel@tonic-gate if (ud_get_last_block(dev, &last_block) != 0) { 18507c478bd9Sstevel@tonic-gate end_index = 1; 18517c478bd9Sstevel@tonic-gate } else { 18527c478bd9Sstevel@tonic-gate end_index = 3; 18537c478bd9Sstevel@tonic-gate } 18547c478bd9Sstevel@tonic-gate 18557c478bd9Sstevel@tonic-gate if (cdev_ioctl(dev, CDROMREADOFFSET, (intptr_t)&session_offset, 18567c478bd9Sstevel@tonic-gate FKIOCTL|FREAD|FNATIVE, CRED(), &rval) != 0) { 18577c478bd9Sstevel@tonic-gate session_offset = 0; 18587c478bd9Sstevel@tonic-gate } 18597c478bd9Sstevel@tonic-gate 18607c478bd9Sstevel@tonic-gate for (index = 0; index < end_index; index++) { 18617c478bd9Sstevel@tonic-gate 18627c478bd9Sstevel@tonic-gate for (bsize = DEV_BSIZE, shift = 0; 18637c478bd9Sstevel@tonic-gate bsize <= MAXBSIZE; bsize <<= 1, shift++) { 18647c478bd9Sstevel@tonic-gate 18657c478bd9Sstevel@tonic-gate if (index == 0) { 18667c478bd9Sstevel@tonic-gate avd_loc = 256; 18677c478bd9Sstevel@tonic-gate if (bsize <= 2048) { 18687c478bd9Sstevel@tonic-gate avd_loc += 18697c478bd9Sstevel@tonic-gate session_offset * 2048 / bsize; 18707c478bd9Sstevel@tonic-gate } else { 18717c478bd9Sstevel@tonic-gate avd_loc += 18727c478bd9Sstevel@tonic-gate session_offset / (bsize / 2048); 18737c478bd9Sstevel@tonic-gate } 18747c478bd9Sstevel@tonic-gate } else if (index == 1) { 18757c478bd9Sstevel@tonic-gate avd_loc = last_block - (1 << shift); 18767c478bd9Sstevel@tonic-gate } else { 18777c478bd9Sstevel@tonic-gate avd_loc = last_block - (256 << shift); 18787c478bd9Sstevel@tonic-gate } 18797c478bd9Sstevel@tonic-gate 18807c478bd9Sstevel@tonic-gate bp = ud_bread(dev, avd_loc << shift, 18817c478bd9Sstevel@tonic-gate ANCHOR_VOL_DESC_LEN); 18827c478bd9Sstevel@tonic-gate if (geterror(bp) != 0) { 18837c478bd9Sstevel@tonic-gate brelse(bp); 18847c478bd9Sstevel@tonic-gate continue; 18857c478bd9Sstevel@tonic-gate } 18867c478bd9Sstevel@tonic-gate 18877c478bd9Sstevel@tonic-gate /* 18887c478bd9Sstevel@tonic-gate * Verify if we have avdp here 18897c478bd9Sstevel@tonic-gate */ 18907c478bd9Sstevel@tonic-gate avdp = (struct anch_vol_desc_ptr *)bp->b_un.b_addr; 18917c478bd9Sstevel@tonic-gate if (ud_verify_tag_and_desc(&avdp->avd_tag, 18927c478bd9Sstevel@tonic-gate UD_ANCH_VOL_DESC, avd_loc, 18937c478bd9Sstevel@tonic-gate 1, ANCHOR_VOL_DESC_LEN) != 0) { 18947c478bd9Sstevel@tonic-gate bp->b_flags |= B_AGE | B_STALE; 18957c478bd9Sstevel@tonic-gate brelse(bp); 18967c478bd9Sstevel@tonic-gate continue; 18977c478bd9Sstevel@tonic-gate } 18987c478bd9Sstevel@tonic-gate bp->b_flags |= B_AGE | B_STALE; 18997c478bd9Sstevel@tonic-gate brelse(bp); 19007c478bd9Sstevel@tonic-gate *loc = avd_loc; 19017c478bd9Sstevel@tonic-gate return (bsize); 19027c478bd9Sstevel@tonic-gate } 19037c478bd9Sstevel@tonic-gate } 19047c478bd9Sstevel@tonic-gate 19057c478bd9Sstevel@tonic-gate /* 19067c478bd9Sstevel@tonic-gate * Did not find AVD at all the locations 19077c478bd9Sstevel@tonic-gate */ 19087c478bd9Sstevel@tonic-gate return (0); 19097c478bd9Sstevel@tonic-gate } 19107c478bd9Sstevel@tonic-gate 19117c478bd9Sstevel@tonic-gate static int 19127c478bd9Sstevel@tonic-gate udfinit(int fstype, char *name) 19137c478bd9Sstevel@tonic-gate { 19147c478bd9Sstevel@tonic-gate static const fs_operation_def_t udf_vfsops_template[] = { 1915aa59c4cbSrsb VFSNAME_MOUNT, { .vfs_mount = udf_mount }, 1916aa59c4cbSrsb VFSNAME_UNMOUNT, { .vfs_unmount = udf_unmount }, 1917aa59c4cbSrsb VFSNAME_ROOT, { .vfs_root = udf_root }, 1918aa59c4cbSrsb VFSNAME_STATVFS, { .vfs_statvfs = udf_statvfs }, 1919aa59c4cbSrsb VFSNAME_SYNC, { .vfs_sync = udf_sync }, 1920aa59c4cbSrsb VFSNAME_VGET, { .vfs_vget = udf_vget }, 1921aa59c4cbSrsb VFSNAME_MOUNTROOT, { .vfs_mountroot = udf_mountroot }, 19227c478bd9Sstevel@tonic-gate NULL, NULL 19237c478bd9Sstevel@tonic-gate }; 19247c478bd9Sstevel@tonic-gate extern struct vnodeops *udf_vnodeops; 19257c478bd9Sstevel@tonic-gate extern const fs_operation_def_t udf_vnodeops_template[]; 19267c478bd9Sstevel@tonic-gate int error; 19277c478bd9Sstevel@tonic-gate 19287c478bd9Sstevel@tonic-gate ud_printf("udfinit\n"); 19297c478bd9Sstevel@tonic-gate 19307c478bd9Sstevel@tonic-gate error = vfs_setfsops(fstype, udf_vfsops_template, NULL); 19317c478bd9Sstevel@tonic-gate if (error != 0) { 19327c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "udfinit: bad vfs ops template"); 19337c478bd9Sstevel@tonic-gate return (error); 19347c478bd9Sstevel@tonic-gate } 19357c478bd9Sstevel@tonic-gate 19367c478bd9Sstevel@tonic-gate error = vn_make_ops(name, udf_vnodeops_template, &udf_vnodeops); 19377c478bd9Sstevel@tonic-gate if (error != 0) { 19387c478bd9Sstevel@tonic-gate (void) vfs_freevfsops_by_type(fstype); 19397c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "udfinit: bad vnode ops template"); 19407c478bd9Sstevel@tonic-gate return (error); 19417c478bd9Sstevel@tonic-gate } 19427c478bd9Sstevel@tonic-gate 19437c478bd9Sstevel@tonic-gate udf_fstype = fstype; 19447c478bd9Sstevel@tonic-gate 19457c478bd9Sstevel@tonic-gate ud_init_inodes(); 19467c478bd9Sstevel@tonic-gate 19477c478bd9Sstevel@tonic-gate return (0); 19487c478bd9Sstevel@tonic-gate } 1949