summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/fs/zfs/zfs_vfsops.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/fs/zfs/zfs_vfsops.c')
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_vfsops.c75
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;