diff options
Diffstat (limited to 'usr/src/uts/common/fs/zfs/zfs_vfsops.c')
-rw-r--r-- | usr/src/uts/common/fs/zfs/zfs_vfsops.c | 75 |
1 files changed, 38 insertions, 37 deletions
diff --git a/usr/src/uts/common/fs/zfs/zfs_vfsops.c b/usr/src/uts/common/fs/zfs/zfs_vfsops.c index 07676602bd..c524cb5eaa 100644 --- a/usr/src/uts/common/fs/zfs/zfs_vfsops.c +++ b/usr/src/uts/common/fs/zfs/zfs_vfsops.c @@ -61,6 +61,7 @@ #include <sys/sunddi.h> #include <sys/dnlc.h> #include <sys/dmu_objset.h> +#include <sys/spa_boot.h> int zfsfstype; vfsops_t *zfs_vfsops = NULL; @@ -830,7 +831,7 @@ str_to_uint64(char *str, uint64_t *objnum) * string to a dataset name: "rootpool-name/root-filesystem-name". */ static int -parse_bootpath(char *bpath, char *outpath) +zfs_parse_bootfs(char *bpath, char *outpath) { char *slashp; uint64_t objnum; @@ -861,60 +862,66 @@ static int zfs_mountroot(vfs_t *vfsp, enum whymountroot why) { int error = 0; - int ret = 0; static int zfsrootdone = 0; zfsvfs_t *zfsvfs = NULL; znode_t *zp = NULL; vnode_t *vp = NULL; - char *zfs_bootpath; -#if defined(_OBP) - int proplen; -#endif + char *zfs_bootfs; ASSERT(vfsp); /* * The filesystem that we mount as root is defined in the - * "zfs-bootfs" property. + * boot property "zfs-bootfs" with a format of + * "poolname/root-dataset-objnum". */ if (why == ROOT_INIT) { if (zfsrootdone++) return (EBUSY); + /* + * the process of doing a spa_load will require the + * clock to be set before we could (for example) do + * something better by looking at the timestamp on + * an uberblock, so just set it to -1. + */ + clkset(-1); + + if ((zfs_bootfs = spa_get_bootfs()) == NULL) { + cmn_err(CE_NOTE, "\nspa_get_bootfs: can not get " + "bootfs name \n"); + return (EINVAL); + } -#if defined(_OBP) - proplen = BOP_GETPROPLEN(bootops, "zfs-bootfs"); - if (proplen == 0) - return (EIO); - zfs_bootpath = kmem_zalloc(proplen, KM_SLEEP); - if (BOP_GETPROP(bootops, "zfs-bootfs", zfs_bootpath) == -1) { - kmem_free(zfs_bootpath, proplen); - return (EIO); + if (error = spa_import_rootpool(rootfs.bo_name)) { + spa_free_bootfs(zfs_bootfs); + cmn_err(CE_NOTE, "\nspa_import_rootpool: error %d\n", + error); + return (error); } - error = parse_bootpath(zfs_bootpath, rootfs.bo_name); - kmem_free(zfs_bootpath, proplen); -#else - if (ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_root_node(), - DDI_PROP_DONTPASS, "zfs-bootfs", &zfs_bootpath) != - DDI_SUCCESS) - return (EIO); - - error = parse_bootpath(zfs_bootpath, rootfs.bo_name); - ddi_prop_free(zfs_bootpath); -#endif - - if (error) + + if (error = zfs_parse_bootfs(zfs_bootfs, rootfs.bo_name)) { + spa_free_bootfs(zfs_bootfs); + cmn_err(CE_NOTE, "\nzfs_parse_bootfs: error %d\n", + error); return (error); + } + + spa_free_bootfs(zfs_bootfs); if (error = vfs_lock(vfsp)) return (error); - if (error = zfs_domount(vfsp, rootfs.bo_name, CRED())) + if (error = zfs_domount(vfsp, rootfs.bo_name, CRED())) { + cmn_err(CE_NOTE, "\nzfs_domount: error %d\n", error); goto out; + } zfsvfs = (zfsvfs_t *)vfsp->vfs_data; ASSERT(zfsvfs); - if (error = zfs_zget(zfsvfs, zfsvfs->z_root, &zp)) + if (error = zfs_zget(zfsvfs, zfsvfs->z_root, &zp)) { + cmn_err(CE_NOTE, "\nzfs_zget: error %d\n", error); goto out; + } vp = ZTOV(zp); mutex_enter(&vp->v_lock); @@ -928,17 +935,11 @@ zfs_mountroot(vfs_t *vfsp, enum whymountroot why) */ VN_RELE(vp); - /* - * Mount root as readonly initially, it will be remouted - * read/write by /lib/svc/method/fs-usr. - */ - readonly_changed_cb(vfsp->vfs_data, B_TRUE); vfs_add((struct vnode *)0, vfsp, (vfsp->vfs_flag & VFS_RDONLY) ? MS_RDONLY : 0); out: vfs_unlock(vfsp); - ret = (error) ? error : 0; - return (ret); + return (error); } else if (why == ROOT_REMOUNT) { readonly_changed_cb(vfsp->vfs_data, B_FALSE); vfsp->vfs_flag |= VFS_REMOUNT; |