usr/src/uts/common/fs/zfs/zfs_ioctl.c
changeset 5331 3047ad28a67b
parent 5329 33cb98223b2d
child 5367 c40abbe796be
equal deleted inserted replaced
5330:71aba7712438 5331:3047ad28a67b
    36 #include <sys/kmem.h>
    36 #include <sys/kmem.h>
    37 #include <sys/conf.h>
    37 #include <sys/conf.h>
    38 #include <sys/cmn_err.h>
    38 #include <sys/cmn_err.h>
    39 #include <sys/stat.h>
    39 #include <sys/stat.h>
    40 #include <sys/zfs_ioctl.h>
    40 #include <sys/zfs_ioctl.h>
       
    41 #include <sys/zfs_i18n.h>
       
    42 #include <sys/zfs_znode.h>
    41 #include <sys/zap.h>
    43 #include <sys/zap.h>
    42 #include <sys/spa.h>
    44 #include <sys/spa.h>
    43 #include <sys/spa_impl.h>
    45 #include <sys/spa_impl.h>
    44 #include <sys/vdev.h>
    46 #include <sys/vdev.h>
    45 #include <sys/vdev_impl.h>
    47 #include <sys/vdev_impl.h>
    58 #include <sys/pathname.h>
    60 #include <sys/pathname.h>
    59 #include <sys/mount.h>
    61 #include <sys/mount.h>
    60 #include <sys/sdt.h>
    62 #include <sys/sdt.h>
    61 #include <sys/fs/zfs.h>
    63 #include <sys/fs/zfs.h>
    62 #include <sys/zfs_ctldir.h>
    64 #include <sys/zfs_ctldir.h>
       
    65 #include <sys/zfs_dir.h>
    63 #include <sys/zvol.h>
    66 #include <sys/zvol.h>
    64 #include <sharefs/share.h>
    67 #include <sharefs/share.h>
    65 #include <sys/zfs_znode.h>
    68 #include <sys/zfs_znode.h>
    66 #include <sys/zfs_vfsops.h>
    69 #include <sys/zfs_vfsops.h>
    67 #include <sys/dmu_objset.h>
    70 #include <sys/dmu_objset.h>
   150 	}
   153 	}
   151 
   154 
   152 	buf[HIS_MAX_RECORD_LEN -1] = '\0';
   155 	buf[HIS_MAX_RECORD_LEN -1] = '\0';
   153 
   156 
   154 	return (buf);
   157 	return (buf);
       
   158 }
       
   159 
       
   160 static int
       
   161 zfs_check_version(const char *name, int version)
       
   162 {
       
   163 
       
   164 	spa_t *spa;
       
   165 
       
   166 	if (spa_open(name, &spa, FTAG) == 0) {
       
   167 		if (spa_version(spa) < version) {
       
   168 			spa_close(spa, FTAG);
       
   169 			return (1);
       
   170 		}
       
   171 		spa_close(spa, FTAG);
       
   172 	}
       
   173 	return (0);
   155 }
   174 }
   156 
   175 
   157 static void
   176 static void
   158 zfs_log_history(zfs_cmd_t *zc)
   177 zfs_log_history(zfs_cmd_t *zc)
   159 {
   178 {
  1278 			 */
  1297 			 */
  1279 			if (!zfs_prop_user(propname) ||
  1298 			if (!zfs_prop_user(propname) ||
  1280 			    nvpair_type(elem) != DATA_TYPE_STRING)
  1299 			    nvpair_type(elem) != DATA_TYPE_STRING)
  1281 				return (EINVAL);
  1300 				return (EINVAL);
  1282 
  1301 
  1283 			error = zfs_secpolicy_write_perms(name,
  1302 			if (error = zfs_secpolicy_write_perms(name,
  1284 			    ZFS_DELEG_PERM_USERPROP, CRED());
  1303 			    ZFS_DELEG_PERM_USERPROP, CRED()))
  1285 			if (error)
       
  1286 				return (error);
  1304 				return (error);
  1287 			continue;
  1305 			continue;
  1288 		}
  1306 		}
  1289 
  1307 
  1290 		if ((error = zfs_secpolicy_setprop(name, prop, CRED())) != 0)
  1308 		if ((error = zfs_secpolicy_setprop(name, prop, CRED())) != 0)
  1302 			 */
  1320 			 */
  1303 			if (nvpair_type(elem) == DATA_TYPE_UINT64 &&
  1321 			if (nvpair_type(elem) == DATA_TYPE_UINT64 &&
  1304 			    nvpair_value_uint64(elem, &intval) == 0 &&
  1322 			    nvpair_value_uint64(elem, &intval) == 0 &&
  1305 			    intval >= ZIO_COMPRESS_GZIP_1 &&
  1323 			    intval >= ZIO_COMPRESS_GZIP_1 &&
  1306 			    intval <= ZIO_COMPRESS_GZIP_9) {
  1324 			    intval <= ZIO_COMPRESS_GZIP_9) {
  1307 				spa_t *spa;
  1325 				if (zfs_check_version(name,
  1308 
  1326 				    SPA_VERSION_GZIP_COMPRESSION))
  1309 				if (spa_open(name, &spa, FTAG) == 0) {
  1327 					return (ENOTSUP);
  1310 					if (spa_version(spa) <
       
  1311 					    SPA_VERSION_GZIP_COMPRESSION) {
       
  1312 						spa_close(spa, FTAG);
       
  1313 						return (ENOTSUP);
       
  1314 					}
       
  1315 
       
  1316 					spa_close(spa, FTAG);
       
  1317 				}
       
  1318 			}
  1328 			}
  1319 			break;
  1329 			break;
  1320 
  1330 
  1321 		case ZFS_PROP_COPIES:
  1331 		case ZFS_PROP_COPIES:
  1322 		{
  1332 			if (zfs_check_version(name, SPA_VERSION_DITTO_BLOCKS))
  1323 			spa_t *spa;
  1333 				return (ENOTSUP);
  1324 
       
  1325 			if (spa_open(name, &spa, FTAG) == 0) {
       
  1326 				if (spa_version(spa) <
       
  1327 				    SPA_VERSION_DITTO_BLOCKS) {
       
  1328 					spa_close(spa, FTAG);
       
  1329 					return (ENOTSUP);
       
  1330 				}
       
  1331 				spa_close(spa, FTAG);
       
  1332 			}
       
  1333 			break;
  1334 			break;
  1334 		}
  1335 		case ZFS_PROP_NORMALIZE:
  1335 		}
  1336 		case ZFS_PROP_UTF8ONLY:
       
  1337 		case ZFS_PROP_CASE:
       
  1338 			if (zfs_check_version(name, SPA_VERSION_NORMALIZATION))
       
  1339 				return (ENOTSUP);
       
  1340 
       
  1341 		}
       
  1342 		if ((error = zfs_secpolicy_setprop(name, prop, CRED())) != 0)
       
  1343 			return (error);
  1336 	}
  1344 	}
  1337 
  1345 
  1338 	elem = NULL;
  1346 	elem = NULL;
  1339 	while ((elem = nvlist_next_nvpair(nvl, elem)) != NULL) {
  1347 	while ((elem = nvlist_next_nvpair(nvl, elem)) != NULL) {
  1340 		const char *propname = nvpair_name(elem);
  1348 		const char *propname = nvpair_name(elem);
  1640 
  1648 
  1641 /* ARGSUSED */
  1649 /* ARGSUSED */
  1642 static void
  1650 static void
  1643 zfs_create_cb(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx)
  1651 zfs_create_cb(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx)
  1644 {
  1652 {
  1645 	nvlist_t *nvprops = arg;
  1653 	zfs_creat_t *zct = arg;
  1646 	uint64_t version = ZPL_VERSION;
  1654 	uint64_t version;
  1647 
  1655 
  1648 	(void) nvlist_lookup_uint64(nvprops,
  1656 	if (spa_version(dmu_objset_spa(os)) >= SPA_VERSION_FUID)
       
  1657 		version = ZPL_VERSION;
       
  1658 	else
       
  1659 		version = ZPL_VERSION_FUID - 1;
       
  1660 
       
  1661 	(void) nvlist_lookup_uint64(zct->zct_props,
  1649 	    zfs_prop_to_name(ZFS_PROP_VERSION), &version);
  1662 	    zfs_prop_to_name(ZFS_PROP_VERSION), &version);
  1650 
  1663 
  1651 	zfs_create_fs(os, cr, version, tx);
  1664 	zfs_create_fs(os, cr, version, zct->zct_norm, tx);
       
  1665 }
       
  1666 
       
  1667 /*
       
  1668  * zfs_prop_lookup()
       
  1669  *
       
  1670  * Look for the property first in the existing property nvlist.  If
       
  1671  * it's already present, you're done.  If it's not there, attempt to
       
  1672  * find the property value from a parent dataset.  If that fails, fall
       
  1673  * back to the property's default value.  In either of these two
       
  1674  * cases, if update is TRUE, add a value for the property to the
       
  1675  * property nvlist.
       
  1676  *
       
  1677  * If the rval pointer is non-NULL, copy the discovered value to rval.
       
  1678  *
       
  1679  * If we get any unexpected errors, bail and return the error number
       
  1680  * to the caller.
       
  1681  *
       
  1682  * If we succeed, return 0.
       
  1683  */
       
  1684 static int
       
  1685 zfs_prop_lookup(const char *parentname, zfs_prop_t propnum,
       
  1686     nvlist_t *proplist, uint64_t *rval, boolean_t update)
       
  1687 {
       
  1688 	const char *propname;
       
  1689 	uint64_t value;
       
  1690 	int error = ENOENT;
       
  1691 
       
  1692 	propname = zfs_prop_to_name(propnum);
       
  1693 	if (proplist != NULL)
       
  1694 		error = nvlist_lookup_uint64(proplist, propname, &value);
       
  1695 	if (error == ENOENT) {
       
  1696 		error = dsl_prop_get_integer(parentname, propname,
       
  1697 		    &value, NULL);
       
  1698 		if (error == ENOENT)
       
  1699 			value = zfs_prop_default_numeric(propnum);
       
  1700 		else if (error != 0)
       
  1701 			return (error);
       
  1702 		if (update) {
       
  1703 			ASSERT(proplist != NULL);
       
  1704 			error = nvlist_add_uint64(proplist, propname, value);
       
  1705 		}
       
  1706 	}
       
  1707 	if (error == 0 && rval)
       
  1708 		*rval = value;
       
  1709 	return (error);
       
  1710 }
       
  1711 
       
  1712 /*
       
  1713  * zfs_normalization_get
       
  1714  *
       
  1715  * Get the normalization flag value.  If the properties have
       
  1716  * non-default values, make sure the pool version is recent enough to
       
  1717  * support these choices.
       
  1718  */
       
  1719 static int
       
  1720 zfs_normalization_get(const char *dataset, nvlist_t *proplist, int *norm,
       
  1721     boolean_t update)
       
  1722 {
       
  1723 	char parentname[MAXNAMELEN];
       
  1724 	char poolname[MAXNAMELEN];
       
  1725 	char *cp;
       
  1726 	uint64_t value;
       
  1727 	int check = 0;
       
  1728 	int error;
       
  1729 
       
  1730 	ASSERT(norm != NULL);
       
  1731 	*norm = 0;
       
  1732 
       
  1733 	(void) strncpy(parentname, dataset, sizeof (parentname));
       
  1734 	cp = strrchr(parentname, '@');
       
  1735 	if (cp != NULL) {
       
  1736 		cp[0] = '\0';
       
  1737 	} else {
       
  1738 		cp = strrchr(parentname, '/');
       
  1739 		if (cp == NULL)
       
  1740 			return (ENOENT);
       
  1741 		cp[0] = '\0';
       
  1742 	}
       
  1743 
       
  1744 	(void) strncpy(poolname, dataset, sizeof (poolname));
       
  1745 	cp = strchr(poolname, '/');
       
  1746 	if (cp != NULL)
       
  1747 		cp[0] = '\0';
       
  1748 
       
  1749 	error = zfs_prop_lookup(parentname, ZFS_PROP_UTF8ONLY,
       
  1750 	    proplist, &value, update);
       
  1751 	if (error != 0)
       
  1752 		return (error);
       
  1753 	if (value != zfs_prop_default_numeric(ZFS_PROP_UTF8ONLY))
       
  1754 		check = 1;
       
  1755 
       
  1756 	error = zfs_prop_lookup(parentname, ZFS_PROP_NORMALIZE,
       
  1757 	    proplist, &value, update);
       
  1758 	if (error != 0)
       
  1759 		return (error);
       
  1760 	if (value != zfs_prop_default_numeric(ZFS_PROP_NORMALIZE)) {
       
  1761 		check = 1;
       
  1762 		switch ((int)value) {
       
  1763 		case ZFS_NORMALIZE_NONE:
       
  1764 			break;
       
  1765 		case ZFS_NORMALIZE_C:
       
  1766 			*norm |= U8_TEXTPREP_NFC;
       
  1767 			break;
       
  1768 		case ZFS_NORMALIZE_D:
       
  1769 			*norm |= U8_TEXTPREP_NFD;
       
  1770 			break;
       
  1771 		case ZFS_NORMALIZE_KC:
       
  1772 			*norm |= U8_TEXTPREP_NFKC;
       
  1773 			break;
       
  1774 		case ZFS_NORMALIZE_KD:
       
  1775 			*norm |= U8_TEXTPREP_NFKD;
       
  1776 			break;
       
  1777 		default:
       
  1778 			ASSERT((int)value >= ZFS_NORMALIZE_NONE);
       
  1779 			ASSERT((int)value <= ZFS_NORMALIZE_KD);
       
  1780 			break;
       
  1781 		}
       
  1782 	}
       
  1783 
       
  1784 	error = zfs_prop_lookup(parentname, ZFS_PROP_CASE,
       
  1785 	    proplist, &value, update);
       
  1786 	if (error != 0)
       
  1787 		return (error);
       
  1788 	if (value != zfs_prop_default_numeric(ZFS_PROP_CASE)) {
       
  1789 		check = 1;
       
  1790 		switch ((int)value) {
       
  1791 		case ZFS_CASE_SENSITIVE:
       
  1792 			break;
       
  1793 		case ZFS_CASE_INSENSITIVE:
       
  1794 			*norm |= U8_TEXTPREP_TOUPPER;
       
  1795 			break;
       
  1796 		case ZFS_CASE_MIXED:
       
  1797 			*norm |= U8_TEXTPREP_TOUPPER;
       
  1798 			break;
       
  1799 		default:
       
  1800 			ASSERT((int)value >= ZFS_CASE_SENSITIVE);
       
  1801 			ASSERT((int)value <= ZFS_CASE_MIXED);
       
  1802 			break;
       
  1803 		}
       
  1804 	}
       
  1805 
       
  1806 	if (check == 1)
       
  1807 		if (zfs_check_version(poolname, SPA_VERSION_NORMALIZATION))
       
  1808 			return (ENOTSUP);
       
  1809 	return (0);
  1652 }
  1810 }
  1653 
  1811 
  1654 static int
  1812 static int
  1655 zfs_ioc_create(zfs_cmd_t *zc)
  1813 zfs_ioc_create(zfs_cmd_t *zc)
  1656 {
  1814 {
  1657 	objset_t *clone;
  1815 	objset_t *clone;
  1658 	int error = 0;
  1816 	int error = 0;
       
  1817 	zfs_creat_t zct;
  1659 	nvlist_t *nvprops = NULL;
  1818 	nvlist_t *nvprops = NULL;
  1660 	void (*cbfunc)(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx);
  1819 	void (*cbfunc)(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx);
  1661 	dmu_objset_type_t type = zc->zc_objset_type;
  1820 	dmu_objset_type_t type = zc->zc_objset_type;
  1662 
  1821 
  1663 	switch (type) {
  1822 	switch (type) {
  1679 
  1838 
  1680 	if (zc->zc_nvlist_src != NULL &&
  1839 	if (zc->zc_nvlist_src != NULL &&
  1681 	    (error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
  1840 	    (error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
  1682 	    &nvprops)) != 0)
  1841 	    &nvprops)) != 0)
  1683 		return (error);
  1842 		return (error);
       
  1843 
       
  1844 	zct.zct_norm = 0;
       
  1845 	zct.zct_props = nvprops;
  1684 
  1846 
  1685 	if (zc->zc_value[0] != '\0') {
  1847 	if (zc->zc_value[0] != '\0') {
  1686 		/*
  1848 		/*
  1687 		 * We're creating a clone of an existing snapshot.
  1849 		 * We're creating a clone of an existing snapshot.
  1688 		 */
  1850 		 */
  1697 		if (error) {
  1859 		if (error) {
  1698 			nvlist_free(nvprops);
  1860 			nvlist_free(nvprops);
  1699 			return (error);
  1861 			return (error);
  1700 		}
  1862 		}
  1701 		error = dmu_objset_create(zc->zc_name, type, clone, NULL, NULL);
  1863 		error = dmu_objset_create(zc->zc_name, type, clone, NULL, NULL);
       
  1864 		if (error) {
       
  1865 			dmu_objset_close(clone);
       
  1866 			nvlist_free(nvprops);
       
  1867 			return (error);
       
  1868 		}
       
  1869 		/*
       
  1870 		 * If caller did not provide any properties, allocate
       
  1871 		 * an nvlist for properties, as we will be adding our set-once
       
  1872 		 * properties to it.  This carries the choices made on the
       
  1873 		 * original file system into the clone.
       
  1874 		 */
       
  1875 		if (nvprops == NULL)
       
  1876 			VERIFY(nvlist_alloc(&nvprops,
       
  1877 			    NV_UNIQUE_NAME, KM_SLEEP) == 0);
       
  1878 
       
  1879 		/*
       
  1880 		 * We have to have normalization and case-folding
       
  1881 		 * flags correct when we do the file system creation,
       
  1882 		 * so go figure them out now.  All we really care about
       
  1883 		 * here is getting these values into the property list.
       
  1884 		 */
       
  1885 		error = zfs_normalization_get(zc->zc_value, nvprops,
       
  1886 		    &zct.zct_norm, B_TRUE);
       
  1887 		if (error != 0) {
       
  1888 			dmu_objset_close(clone);
       
  1889 			nvlist_free(nvprops);
       
  1890 			return (error);
       
  1891 		}
  1702 		dmu_objset_close(clone);
  1892 		dmu_objset_close(clone);
  1703 	} else {
  1893 	} else {
  1704 		if (cbfunc == NULL) {
  1894 		if (cbfunc == NULL) {
  1705 			nvlist_free(nvprops);
  1895 			nvlist_free(nvprops);
  1706 			return (EINVAL);
  1896 			return (EINVAL);
  1735 				nvlist_free(nvprops);
  1925 				nvlist_free(nvprops);
  1736 				return (error);
  1926 				return (error);
  1737 			}
  1927 			}
  1738 		} else if (type == DMU_OST_ZFS) {
  1928 		} else if (type == DMU_OST_ZFS) {
  1739 			uint64_t version;
  1929 			uint64_t version;
  1740 
  1930 			int error;
  1741 			if (0 == nvlist_lookup_uint64(nvprops,
  1931 
  1742 			    zfs_prop_to_name(ZFS_PROP_VERSION), &version) &&
  1932 			error = nvlist_lookup_uint64(nvprops,
  1743 			    (version < ZPL_VERSION_INITIAL ||
  1933 			    zfs_prop_to_name(ZFS_PROP_VERSION), &version);
       
  1934 
       
  1935 			if (error == 0 && (version < ZPL_VERSION_INITIAL ||
  1744 			    version > ZPL_VERSION)) {
  1936 			    version > ZPL_VERSION)) {
  1745 				nvlist_free(nvprops);
  1937 				nvlist_free(nvprops);
  1746 				return (EINVAL);
  1938 				return (ENOTSUP);
       
  1939 			} else if (error == 0 && version >= ZPL_VERSION_FUID &&
       
  1940 			    zfs_check_version(zc->zc_name, SPA_VERSION_FUID)) {
       
  1941 				nvlist_free(nvprops);
       
  1942 				return (ENOTSUP);
  1747 			}
  1943 			}
  1748 		}
  1944 
  1749 
  1945 			/*
       
  1946 			 * We have to have normalization and
       
  1947 			 * case-folding flags correct when we do the
       
  1948 			 * file system creation, so go figure them out
       
  1949 			 * now.  The final argument to zfs_normalization_get()
       
  1950 			 * tells that routine not to update the nvprops
       
  1951 			 * list.
       
  1952 			 */
       
  1953 			error = zfs_normalization_get(zc->zc_name, nvprops,
       
  1954 			    &zct.zct_norm, B_FALSE);
       
  1955 			if (error != 0) {
       
  1956 				nvlist_free(nvprops);
       
  1957 				return (error);
       
  1958 			}
       
  1959 		}
  1750 		error = dmu_objset_create(zc->zc_name, type, NULL, cbfunc,
  1960 		error = dmu_objset_create(zc->zc_name, type, NULL, cbfunc,
  1751 		    nvprops);
  1961 		    &zct);
  1752 	}
  1962 	}
  1753 
  1963 
  1754 	/*
  1964 	/*
  1755 	 * It would be nice to do this atomically.
  1965 	 * It would be nice to do this atomically.
  1756 	 */
  1966 	 */
  1950 		(void) dmu_objset_destroy(cosname);
  2160 		(void) dmu_objset_destroy(cosname);
  1951 	}
  2161 	}
  1952 	if (zfsvfs != NULL)
  2162 	if (zfsvfs != NULL)
  1953 		VFS_RELE(zfsvfs->z_vfs);
  2163 		VFS_RELE(zfsvfs->z_vfs);
  1954 	new_off = fp->f_offset + zc->zc_cookie;
  2164 	new_off = fp->f_offset + zc->zc_cookie;
  1955 	if (VOP_SEEK(fp->f_vnode, fp->f_offset, &new_off) == 0)
  2165 	if (VOP_SEEK(fp->f_vnode, fp->f_offset, &new_off, NULL) == 0)
  1956 		fp->f_offset = new_off;
  2166 		fp->f_offset = new_off;
  1957 
  2167 
  1958 	releasef(fd);
  2168 	releasef(fd);
  1959 	return (error);
  2169 	return (error);
  1960 }
  2170 }
  2121 }
  2331 }
  2122 
  2332 
  2123 /*
  2333 /*
  2124  * We don't want to have a hard dependency
  2334  * We don't want to have a hard dependency
  2125  * against some special symbols in sharefs
  2335  * against some special symbols in sharefs
  2126  * and nfs.  Determine them if needed when
  2336  * nfs, and smbsrv.  Determine them if needed when
  2127  * the first file system is shared.
  2337  * the first file system is shared.
  2128  * Neither sharefs or nfs are unloadable modules.
  2338  * Neither sharefs, nfs or smbsrv are unloadable modules.
  2129  */
  2339  */
  2130 int (*zexport_fs)(void *arg);
  2340 int (*znfsexport_fs)(void *arg);
  2131 int (*zshare_fs)(enum sharefs_sys_op, share_t *, uint32_t);
  2341 int (*zshare_fs)(enum sharefs_sys_op, share_t *, uint32_t);
  2132 
  2342 int (*zsmbexport_fs)(void *arg, boolean_t add_share);
  2133 int zfs_share_inited;
  2343 
       
  2344 int zfs_nfsshare_inited;
       
  2345 int zfs_smbshare_inited;
       
  2346 
  2134 ddi_modhandle_t nfs_mod;
  2347 ddi_modhandle_t nfs_mod;
  2135 ddi_modhandle_t sharefs_mod;
  2348 ddi_modhandle_t sharefs_mod;
       
  2349 ddi_modhandle_t smbsrv_mod;
  2136 kmutex_t zfs_share_lock;
  2350 kmutex_t zfs_share_lock;
  2137 
  2351 
  2138 static int
  2352 static int
       
  2353 zfs_init_sharefs()
       
  2354 {
       
  2355 	int error;
       
  2356 
       
  2357 	ASSERT(MUTEX_HELD(&zfs_share_lock));
       
  2358 	/* Both NFS and SMB shares also require sharetab support. */
       
  2359 	if (sharefs_mod == NULL && ((sharefs_mod =
       
  2360 	    ddi_modopen("fs/sharefs",
       
  2361 	    KRTLD_MODE_FIRST, &error)) == NULL)) {
       
  2362 		return (ENOSYS);
       
  2363 	}
       
  2364 	if (zshare_fs == NULL && ((zshare_fs =
       
  2365 	    (int (*)(enum sharefs_sys_op, share_t *, uint32_t))
       
  2366 	    ddi_modsym(sharefs_mod, "sharefs_impl", &error)) == NULL)) {
       
  2367 		return (ENOSYS);
       
  2368 	}
       
  2369 	return (0);
       
  2370 }
       
  2371 
       
  2372 static int
  2139 zfs_ioc_share(zfs_cmd_t *zc)
  2373 zfs_ioc_share(zfs_cmd_t *zc)
  2140 {
  2374 {
  2141 	int error;
  2375 	int error;
  2142 	int opcode;
  2376 	int opcode;
  2143 
  2377 
  2144 	if (zfs_share_inited == 0) {
  2378 	switch (zc->zc_share.z_sharetype) {
  2145 		mutex_enter(&zfs_share_lock);
  2379 	case ZFS_SHARE_NFS:
  2146 		nfs_mod = ddi_modopen("fs/nfs", KRTLD_MODE_FIRST, &error);
  2380 	case ZFS_UNSHARE_NFS:
  2147 		sharefs_mod = ddi_modopen("fs/sharefs",
  2381 		if (zfs_nfsshare_inited == 0) {
  2148 		    KRTLD_MODE_FIRST, &error);
  2382 			mutex_enter(&zfs_share_lock);
  2149 		if (nfs_mod == NULL || sharefs_mod == NULL) {
  2383 			if (nfs_mod == NULL && ((nfs_mod = ddi_modopen("fs/nfs",
       
  2384 			    KRTLD_MODE_FIRST, &error)) == NULL)) {
       
  2385 				mutex_exit(&zfs_share_lock);
       
  2386 				return (ENOSYS);
       
  2387 			}
       
  2388 			if (znfsexport_fs == NULL &&
       
  2389 			    ((znfsexport_fs = (int (*)(void *))
       
  2390 			    ddi_modsym(nfs_mod,
       
  2391 			    "nfs_export", &error)) == NULL)) {
       
  2392 				mutex_exit(&zfs_share_lock);
       
  2393 				return (ENOSYS);
       
  2394 			}
       
  2395 			error = zfs_init_sharefs();
       
  2396 			if (error) {
       
  2397 				mutex_exit(&zfs_share_lock);
       
  2398 				return (ENOSYS);
       
  2399 			}
       
  2400 			zfs_nfsshare_inited = 1;
  2150 			mutex_exit(&zfs_share_lock);
  2401 			mutex_exit(&zfs_share_lock);
  2151 			return (ENOSYS);
  2402 		}
  2152 		}
  2403 		break;
  2153 		if (zexport_fs == NULL && ((zexport_fs = (int (*)(void *))
  2404 	case ZFS_SHARE_SMB:
  2154 		    ddi_modsym(nfs_mod, "nfs_export", &error)) == NULL)) {
  2405 	case ZFS_UNSHARE_SMB:
       
  2406 		if (zfs_smbshare_inited == 0) {
       
  2407 			mutex_enter(&zfs_share_lock);
       
  2408 			if (smbsrv_mod == NULL && ((smbsrv_mod =
       
  2409 			    ddi_modopen("drv/smbsrv",
       
  2410 			    KRTLD_MODE_FIRST, &error)) == NULL)) {
       
  2411 				mutex_exit(&zfs_share_lock);
       
  2412 				return (ENOSYS);
       
  2413 			}
       
  2414 			if (zsmbexport_fs == NULL && ((zsmbexport_fs =
       
  2415 			    (int (*)(void *, boolean_t))ddi_modsym(smbsrv_mod,
       
  2416 			    "lmshrd_share_upcall", &error)) == NULL)) {
       
  2417 				mutex_exit(&zfs_share_lock);
       
  2418 				return (ENOSYS);
       
  2419 			}
       
  2420 			error = zfs_init_sharefs();
       
  2421 			if (error) {
       
  2422 				mutex_exit(&zfs_share_lock);
       
  2423 				return (ENOSYS);
       
  2424 			}
       
  2425 			zfs_smbshare_inited = 1;
  2155 			mutex_exit(&zfs_share_lock);
  2426 			mutex_exit(&zfs_share_lock);
  2156 			return (ENOSYS);
  2427 		}
  2157 		}
  2428 		break;
  2158 
  2429 	default:
  2159 		if (zshare_fs == NULL && ((zshare_fs =
  2430 		return (EINVAL);
  2160 		    (int (*)(enum sharefs_sys_op, share_t *, uint32_t))
  2431 	}
  2161 		    ddi_modsym(sharefs_mod, "sharefs_impl", &error)) == NULL)) {
  2432 
  2162 			mutex_exit(&zfs_share_lock);
  2433 	switch (zc->zc_share.z_sharetype) {
  2163 			return (ENOSYS);
  2434 	case ZFS_SHARE_NFS:
  2164 		}
  2435 	case ZFS_UNSHARE_NFS:
  2165 		zfs_share_inited = 1;
  2436 		if (error =
  2166 		mutex_exit(&zfs_share_lock);
  2437 		    znfsexport_fs((void *)
  2167 	}
  2438 		    (uintptr_t)zc->zc_share.z_exportdata))
  2168 
  2439 			return (error);
  2169 	if (error = zexport_fs((void *)(uintptr_t)zc->zc_share.z_exportdata))
  2440 		break;
  2170 		return (error);
  2441 	case ZFS_SHARE_SMB:
  2171 
  2442 	case ZFS_UNSHARE_SMB:
  2172 	opcode = (zc->zc_share.z_sharetype == B_TRUE) ?
  2443 		if (error = zsmbexport_fs((void *)
       
  2444 		    (uintptr_t)zc->zc_share.z_exportdata,
       
  2445 		    zc->zc_share.z_sharetype == ZFS_SHARE_SMB ?
       
  2446 		    B_TRUE : B_FALSE)) {
       
  2447 			return (error);
       
  2448 		}
       
  2449 		break;
       
  2450 	}
       
  2451 
       
  2452 	opcode = (zc->zc_share.z_sharetype == ZFS_SHARE_NFS ||
       
  2453 	    zc->zc_share.z_sharetype == ZFS_SHARE_SMB) ?
  2173 	    SHAREFS_ADD : SHAREFS_REMOVE;
  2454 	    SHAREFS_ADD : SHAREFS_REMOVE;
  2174 
  2455 
       
  2456 	/*
       
  2457 	 * Add or remove share from sharetab
       
  2458 	 */
  2175 	error = zshare_fs(opcode,
  2459 	error = zshare_fs(opcode,
  2176 	    (void *)(uintptr_t)zc->zc_share.z_sharedata,
  2460 	    (void *)(uintptr_t)zc->zc_share.z_sharedata,
  2177 	    zc->zc_share.z_sharemax);
  2461 	    zc->zc_share.z_sharemax);
  2178 
  2462 
  2179 	return (error);
  2463 	return (error);
  2445 		return (error);
  2729 		return (error);
  2446 
  2730 
  2447 	zvol_fini();
  2731 	zvol_fini();
  2448 	zfs_fini();
  2732 	zfs_fini();
  2449 	spa_fini();
  2733 	spa_fini();
  2450 	if (zfs_share_inited) {
  2734 	if (zfs_nfsshare_inited)
  2451 		(void) ddi_modclose(nfs_mod);
  2735 		(void) ddi_modclose(nfs_mod);
       
  2736 	if (zfs_smbshare_inited)
       
  2737 		(void) ddi_modclose(smbsrv_mod);
       
  2738 	if (zfs_nfsshare_inited || zfs_smbshare_inited)
  2452 		(void) ddi_modclose(sharefs_mod);
  2739 		(void) ddi_modclose(sharefs_mod);
  2453 	}
       
  2454 
  2740 
  2455 	tsd_destroy(&zfs_fsyncer_key);
  2741 	tsd_destroy(&zfs_fsyncer_key);
  2456 	ldi_ident_release(zfs_li);
  2742 	ldi_ident_release(zfs_li);
  2457 	zfs_li = NULL;
  2743 	zfs_li = NULL;
  2458 	mutex_destroy(&zfs_share_lock);
  2744 	mutex_destroy(&zfs_share_lock);