usr/src/uts/common/fs/zfs/zfs_vfsops.c
changeset 6423 437422a29d3a
parent 6404 6377536e1718
child 6570 bbfcb773718e
equal deleted inserted replaced
6422:d51a10d738ba 6423:437422a29d3a
    59 #include <sys/zfs_fuid.h>
    59 #include <sys/zfs_fuid.h>
    60 #include <sys/bootconf.h>
    60 #include <sys/bootconf.h>
    61 #include <sys/sunddi.h>
    61 #include <sys/sunddi.h>
    62 #include <sys/dnlc.h>
    62 #include <sys/dnlc.h>
    63 #include <sys/dmu_objset.h>
    63 #include <sys/dmu_objset.h>
       
    64 #include <sys/spa_boot.h>
    64 
    65 
    65 int zfsfstype;
    66 int zfsfstype;
    66 vfsops_t *zfs_vfsops = NULL;
    67 vfsops_t *zfs_vfsops = NULL;
    67 static major_t zfs_major;
    68 static major_t zfs_major;
    68 static minor_t zfs_minor;
    69 static minor_t zfs_minor;
   828  * The boot path passed from the boot loader is in the form of
   829  * The boot path passed from the boot loader is in the form of
   829  * "rootpool-name/root-filesystem-object-number'. Convert this
   830  * "rootpool-name/root-filesystem-object-number'. Convert this
   830  * string to a dataset name: "rootpool-name/root-filesystem-name".
   831  * string to a dataset name: "rootpool-name/root-filesystem-name".
   831  */
   832  */
   832 static int
   833 static int
   833 parse_bootpath(char *bpath, char *outpath)
   834 zfs_parse_bootfs(char *bpath, char *outpath)
   834 {
   835 {
   835 	char *slashp;
   836 	char *slashp;
   836 	uint64_t objnum;
   837 	uint64_t objnum;
   837 	int error;
   838 	int error;
   838 
   839 
   859 
   860 
   860 static int
   861 static int
   861 zfs_mountroot(vfs_t *vfsp, enum whymountroot why)
   862 zfs_mountroot(vfs_t *vfsp, enum whymountroot why)
   862 {
   863 {
   863 	int error = 0;
   864 	int error = 0;
   864 	int ret = 0;
       
   865 	static int zfsrootdone = 0;
   865 	static int zfsrootdone = 0;
   866 	zfsvfs_t *zfsvfs = NULL;
   866 	zfsvfs_t *zfsvfs = NULL;
   867 	znode_t *zp = NULL;
   867 	znode_t *zp = NULL;
   868 	vnode_t *vp = NULL;
   868 	vnode_t *vp = NULL;
   869 	char *zfs_bootpath;
   869 	char *zfs_bootfs;
   870 #if defined(_OBP)
       
   871 	int proplen;
       
   872 #endif
       
   873 
   870 
   874 	ASSERT(vfsp);
   871 	ASSERT(vfsp);
   875 
   872 
   876 	/*
   873 	/*
   877 	 * The filesystem that we mount as root is defined in the
   874 	 * The filesystem that we mount as root is defined in the
   878 	 * "zfs-bootfs" property.
   875 	 * boot property "zfs-bootfs" with a format of
       
   876 	 * "poolname/root-dataset-objnum".
   879 	 */
   877 	 */
   880 	if (why == ROOT_INIT) {
   878 	if (why == ROOT_INIT) {
   881 		if (zfsrootdone++)
   879 		if (zfsrootdone++)
   882 			return (EBUSY);
   880 			return (EBUSY);
   883 
   881 		/*
   884 #if defined(_OBP)
   882 		 * the process of doing a spa_load will require the
   885 		proplen = BOP_GETPROPLEN(bootops, "zfs-bootfs");
   883 		 * clock to be set before we could (for example) do
   886 		if (proplen == 0)
   884 		 * something better by looking at the timestamp on
   887 			return (EIO);
   885 		 * an uberblock, so just set it to -1.
   888 		zfs_bootpath = kmem_zalloc(proplen, KM_SLEEP);
   886 		 */
   889 		if (BOP_GETPROP(bootops, "zfs-bootfs", zfs_bootpath) == -1) {
   887 		clkset(-1);
   890 			kmem_free(zfs_bootpath, proplen);
   888 
   891 			return (EIO);
   889 		if ((zfs_bootfs = spa_get_bootfs()) == NULL) {
       
   890 			cmn_err(CE_NOTE, "\nspa_get_bootfs: can not get "
       
   891 			    "bootfs name \n");
       
   892 			return (EINVAL);
   892 		}
   893 		}
   893 		error = parse_bootpath(zfs_bootpath, rootfs.bo_name);
   894 
   894 		kmem_free(zfs_bootpath, proplen);
   895 		if (error = spa_import_rootpool(rootfs.bo_name)) {
   895 #else
   896 			spa_free_bootfs(zfs_bootfs);
   896 		if (ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_root_node(),
   897 			cmn_err(CE_NOTE, "\nspa_import_rootpool: error %d\n",
   897 		    DDI_PROP_DONTPASS, "zfs-bootfs", &zfs_bootpath) !=
   898 			    error);
   898 		    DDI_SUCCESS)
       
   899 			return (EIO);
       
   900 
       
   901 		error = parse_bootpath(zfs_bootpath, rootfs.bo_name);
       
   902 		ddi_prop_free(zfs_bootpath);
       
   903 #endif
       
   904 
       
   905 		if (error)
       
   906 			return (error);
   899 			return (error);
       
   900 		}
       
   901 
       
   902 		if (error = zfs_parse_bootfs(zfs_bootfs, rootfs.bo_name)) {
       
   903 			spa_free_bootfs(zfs_bootfs);
       
   904 			cmn_err(CE_NOTE, "\nzfs_parse_bootfs: error %d\n",
       
   905 			    error);
       
   906 			return (error);
       
   907 		}
       
   908 
       
   909 		spa_free_bootfs(zfs_bootfs);
   907 
   910 
   908 		if (error = vfs_lock(vfsp))
   911 		if (error = vfs_lock(vfsp))
   909 			return (error);
   912 			return (error);
   910 
   913 
   911 		if (error = zfs_domount(vfsp, rootfs.bo_name, CRED()))
   914 		if (error = zfs_domount(vfsp, rootfs.bo_name, CRED())) {
       
   915 			cmn_err(CE_NOTE, "\nzfs_domount: error %d\n", error);
   912 			goto out;
   916 			goto out;
       
   917 		}
   913 
   918 
   914 		zfsvfs = (zfsvfs_t *)vfsp->vfs_data;
   919 		zfsvfs = (zfsvfs_t *)vfsp->vfs_data;
   915 		ASSERT(zfsvfs);
   920 		ASSERT(zfsvfs);
   916 		if (error = zfs_zget(zfsvfs, zfsvfs->z_root, &zp))
   921 		if (error = zfs_zget(zfsvfs, zfsvfs->z_root, &zp)) {
       
   922 			cmn_err(CE_NOTE, "\nzfs_zget: error %d\n", error);
   917 			goto out;
   923 			goto out;
       
   924 		}
   918 
   925 
   919 		vp = ZTOV(zp);
   926 		vp = ZTOV(zp);
   920 		mutex_enter(&vp->v_lock);
   927 		mutex_enter(&vp->v_lock);
   921 		vp->v_flag |= VROOT;
   928 		vp->v_flag |= VROOT;
   922 		mutex_exit(&vp->v_lock);
   929 		mutex_exit(&vp->v_lock);
   926 		 * The zfs_zget call above returns with a hold on vp, we release
   933 		 * The zfs_zget call above returns with a hold on vp, we release
   927 		 * it here.
   934 		 * it here.
   928 		 */
   935 		 */
   929 		VN_RELE(vp);
   936 		VN_RELE(vp);
   930 
   937 
   931 		/*
       
   932 		 * Mount root as readonly initially, it will be remouted
       
   933 		 * read/write by /lib/svc/method/fs-usr.
       
   934 		 */
       
   935 		readonly_changed_cb(vfsp->vfs_data, B_TRUE);
       
   936 		vfs_add((struct vnode *)0, vfsp,
   938 		vfs_add((struct vnode *)0, vfsp,
   937 		    (vfsp->vfs_flag & VFS_RDONLY) ? MS_RDONLY : 0);
   939 		    (vfsp->vfs_flag & VFS_RDONLY) ? MS_RDONLY : 0);
   938 out:
   940 out:
   939 		vfs_unlock(vfsp);
   941 		vfs_unlock(vfsp);
   940 		ret = (error) ? error : 0;
   942 		return (error);
   941 		return (ret);
       
   942 	} else if (why == ROOT_REMOUNT) {
   943 	} else if (why == ROOT_REMOUNT) {
   943 		readonly_changed_cb(vfsp->vfs_data, B_FALSE);
   944 		readonly_changed_cb(vfsp->vfs_data, B_FALSE);
   944 		vfsp->vfs_flag |= VFS_REMOUNT;
   945 		vfsp->vfs_flag |= VFS_REMOUNT;
   945 
   946 
   946 		/* refresh mount options */
   947 		/* refresh mount options */