summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/fs/zfs/zfs_ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/fs/zfs/zfs_ioctl.c')
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_ioctl.c167
1 files changed, 96 insertions, 71 deletions
diff --git a/usr/src/uts/common/fs/zfs/zfs_ioctl.c b/usr/src/uts/common/fs/zfs/zfs_ioctl.c
index 560a943cd7..dcd9853ed8 100644
--- a/usr/src/uts/common/fs/zfs/zfs_ioctl.c
+++ b/usr/src/uts/common/fs/zfs/zfs_ioctl.c
@@ -62,6 +62,7 @@
#include <sys/zfs_ctldir.h>
#include <sys/zvol.h>
#include <sharefs/share.h>
+#include <sys/zfs_znode.h>
#include "zfs_namecheck.h"
#include "zfs_prop.h"
@@ -82,9 +83,9 @@ typedef struct zfs_ioc_vec {
zfs_ioc_func_t *zvec_func;
zfs_secpolicy_func_t *zvec_secpolicy;
enum {
- no_name,
- pool_name,
- dataset_name
+ NO_NAME,
+ POOL_NAME,
+ DATASET_NAME
} zvec_namecheck;
boolean_t zvec_his_log;
} zfs_ioc_vec_t;
@@ -135,6 +136,10 @@ zfs_log_history(zfs_cmd_t *zc)
if (zc->zc_history == NULL)
return;
+ if (zc->zc_history_offset != LOG_CMD_POOL_CREATE &&
+ zc->zc_history_offset != LOG_CMD_NORMAL)
+ return;
+
buf = kmem_alloc(HIS_MAX_RECORD_LEN, KM_SLEEP);
if (copyinstr((void *)(uintptr_t)zc->zc_history,
buf, HIS_MAX_RECORD_LEN, NULL) != 0) {
@@ -154,7 +159,7 @@ zfs_log_history(zfs_cmd_t *zc)
return;
}
- if (spa_version(spa) >= ZFS_VERSION_ZPOOL_HISTORY)
+ if (spa_version(spa) >= SPA_VERSION_ZPOOL_HISTORY)
(void) spa_history_log(spa, buf, zc->zc_history_offset);
spa_close(spa, FTAG);
@@ -521,8 +526,6 @@ zfs_secpolicy_snapshot(zfs_cmd_t *zc, cred_t *cr)
return (zfs_secpolicy_snapshot_perms(zc->zc_name, cr));
}
-
-
static int
zfs_secpolicy_create(zfs_cmd_t *zc, cred_t *cr)
{
@@ -847,7 +850,7 @@ zfs_ioc_pool_get_history(zfs_cmd_t *zc)
if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
return (error);
- if (spa_version(spa) < ZFS_VERSION_ZPOOL_HISTORY) {
+ if (spa_version(spa) < SPA_VERSION_ZPOOL_HISTORY) {
spa_close(spa, FTAG);
return (ENOTSUP);
}
@@ -1052,14 +1055,17 @@ retry:
(error = dsl_prop_get_all(os, &nv)) == 0) {
dmu_objset_stats(os, nv);
/*
- * NB: zvol_get_stats() will read the objset contents,
+ * NB: {zpl,zvol}_get_stats() will read the objset contents,
* which we aren't supposed to do with a
* DS_MODE_STANDARD open, because it could be
* inconsistent. So this is a bit of a workaround...
*/
- if (!zc->zc_objset_stats.dds_inconsistent &&
- dmu_objset_type(os) == DMU_OST_ZVOL)
- VERIFY(zvol_get_stats(os, nv) == 0);
+ if (!zc->zc_objset_stats.dds_inconsistent) {
+ if (dmu_objset_type(os) == DMU_OST_ZVOL)
+ VERIFY(zvol_get_stats(os, nv) == 0);
+ else if (dmu_objset_type(os) == DMU_OST_ZFS)
+ (void) zfs_get_stats(os, nv);
+ }
error = put_nvlist(zc, nv);
nvlist_free(nv);
}
@@ -1266,7 +1272,7 @@ zfs_set_prop_nvlist(const char *name, dev_t dev, cred_t *cr, nvlist_t *nvl)
if (spa_open(p, &spa, FTAG) == 0) {
if (spa_version(spa) <
- ZFS_VERSION_GZIP_COMPRESSION) {
+ SPA_VERSION_GZIP_COMPRESSION) {
spa_close(spa, FTAG);
return (ENOTSUP);
}
@@ -1299,8 +1305,7 @@ zfs_set_prop_nvlist(const char *name, dev_t dev, cred_t *cr, nvlist_t *nvl)
switch (prop) {
case ZFS_PROP_QUOTA:
if ((error = nvpair_value_uint64(elem, &intval)) != 0 ||
- (error = dsl_dir_set_quota(name,
- intval)) != 0)
+ (error = dsl_dir_set_quota(name, intval)) != 0)
return (error);
break;
@@ -1313,15 +1318,19 @@ zfs_set_prop_nvlist(const char *name, dev_t dev, cred_t *cr, nvlist_t *nvl)
case ZFS_PROP_VOLSIZE:
if ((error = nvpair_value_uint64(elem, &intval)) != 0 ||
- (error = zvol_set_volsize(name, dev,
- intval)) != 0)
+ (error = zvol_set_volsize(name, dev, intval)) != 0)
return (error);
break;
case ZFS_PROP_VOLBLOCKSIZE:
if ((error = nvpair_value_uint64(elem, &intval)) != 0 ||
- (error = zvol_set_volblocksize(name,
- intval)) != 0)
+ (error = zvol_set_volblocksize(name, intval)) != 0)
+ return (error);
+ break;
+
+ case ZFS_PROP_VERSION:
+ if ((error = nvpair_value_uint64(elem, &intval)) != 0 ||
+ (error = zfs_set_version(name, intval)) != 0)
return (error);
break;
@@ -1355,8 +1364,8 @@ zfs_set_prop_nvlist(const char *name, dev_t dev, cred_t *cr, nvlist_t *nvl)
return (EINVAL);
break;
default:
- cmn_err(CE_PANIC, "unknown property "
- "type");
+ cmn_err(CE_PANIC,
+ "unknown property type");
break;
}
@@ -1427,7 +1436,7 @@ zfs_ioc_pool_set_props(zfs_cmd_t *zc)
return (error);
}
- if (spa_version(spa) < ZFS_VERSION_BOOTFS) {
+ if (spa_version(spa) < SPA_VERSION_BOOTFS) {
nvlist_free(nvl);
spa_close(spa, FTAG);
return (ENOTSUP);
@@ -1669,7 +1678,13 @@ zfs_get_vfs(const char *resource)
static void
zfs_create_cb(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx)
{
- zfs_create_fs(os, cr, tx);
+ nvlist_t *nvprops = arg;
+ uint64_t version = ZPL_VERSION;
+
+ (void) nvlist_lookup_uint64(nvprops,
+ zfs_prop_to_name(ZFS_PROP_VERSION), &version);
+
+ zfs_create_fs(os, cr, version, tx);
}
static int
@@ -1754,6 +1769,16 @@ zfs_ioc_create(zfs_cmd_t *zc)
nvlist_free(nvprops);
return (error);
}
+ } else if (type == DMU_OST_ZFS) {
+ uint64_t version;
+
+ if (0 == nvlist_lookup_uint64(nvprops,
+ zfs_prop_to_name(ZFS_PROP_VERSION), &version) &&
+ (version < ZPL_VERSION_INITIAL ||
+ version > ZPL_VERSION)) {
+ nvlist_free(nvprops);
+ return (EINVAL);
+ }
}
error = dmu_objset_create(zc->zc_name, type, NULL, cbfunc,
@@ -2122,54 +2147,54 @@ zfs_ioc_share(zfs_cmd_t *zc)
* of those commands.
*/
static zfs_ioc_vec_t zfs_ioc_vec[] = {
- { zfs_ioc_pool_create, zfs_secpolicy_config, pool_name, B_TRUE },
- { zfs_ioc_pool_destroy, zfs_secpolicy_config, pool_name, B_FALSE },
- { zfs_ioc_pool_import, zfs_secpolicy_config, pool_name, B_TRUE },
- { zfs_ioc_pool_export, zfs_secpolicy_config, pool_name, B_FALSE },
- { zfs_ioc_pool_configs, zfs_secpolicy_none, no_name, B_FALSE },
- { zfs_ioc_pool_stats, zfs_secpolicy_read, pool_name, B_FALSE },
- { zfs_ioc_pool_tryimport, zfs_secpolicy_config, no_name, B_FALSE },
- { zfs_ioc_pool_scrub, zfs_secpolicy_config, pool_name, B_TRUE },
- { zfs_ioc_pool_freeze, zfs_secpolicy_config, no_name, B_FALSE },
- { zfs_ioc_pool_upgrade, zfs_secpolicy_config, pool_name, B_TRUE },
- { zfs_ioc_pool_get_history, zfs_secpolicy_config, pool_name, B_FALSE },
- { zfs_ioc_vdev_add, zfs_secpolicy_config, pool_name, B_TRUE },
- { zfs_ioc_vdev_remove, zfs_secpolicy_config, pool_name, B_TRUE },
- { zfs_ioc_vdev_set_state, zfs_secpolicy_config, pool_name, B_TRUE },
- { zfs_ioc_vdev_attach, zfs_secpolicy_config, pool_name, B_TRUE },
- { zfs_ioc_vdev_detach, zfs_secpolicy_config, pool_name, B_TRUE },
- { zfs_ioc_vdev_setpath, zfs_secpolicy_config, pool_name, B_FALSE },
- { zfs_ioc_objset_stats, zfs_secpolicy_read, dataset_name, B_FALSE },
+ { zfs_ioc_pool_create, zfs_secpolicy_config, POOL_NAME, B_TRUE },
+ { zfs_ioc_pool_destroy, zfs_secpolicy_config, POOL_NAME, B_FALSE },
+ { zfs_ioc_pool_import, zfs_secpolicy_config, POOL_NAME, B_TRUE },
+ { zfs_ioc_pool_export, zfs_secpolicy_config, POOL_NAME, B_FALSE },
+ { zfs_ioc_pool_configs, zfs_secpolicy_none, NO_NAME, B_FALSE },
+ { zfs_ioc_pool_stats, zfs_secpolicy_read, POOL_NAME, B_FALSE },
+ { zfs_ioc_pool_tryimport, zfs_secpolicy_config, NO_NAME, B_FALSE },
+ { zfs_ioc_pool_scrub, zfs_secpolicy_config, POOL_NAME, B_TRUE },
+ { zfs_ioc_pool_freeze, zfs_secpolicy_config, NO_NAME, B_FALSE },
+ { zfs_ioc_pool_upgrade, zfs_secpolicy_config, POOL_NAME, B_TRUE },
+ { zfs_ioc_pool_get_history, zfs_secpolicy_config, POOL_NAME, B_FALSE },
+ { zfs_ioc_vdev_add, zfs_secpolicy_config, POOL_NAME, B_TRUE },
+ { zfs_ioc_vdev_remove, zfs_secpolicy_config, POOL_NAME, B_TRUE },
+ { zfs_ioc_vdev_set_state, zfs_secpolicy_config, POOL_NAME, B_TRUE },
+ { zfs_ioc_vdev_attach, zfs_secpolicy_config, POOL_NAME, B_TRUE },
+ { zfs_ioc_vdev_detach, zfs_secpolicy_config, POOL_NAME, B_TRUE },
+ { zfs_ioc_vdev_setpath, zfs_secpolicy_config, POOL_NAME, B_FALSE },
+ { zfs_ioc_objset_stats, zfs_secpolicy_read, DATASET_NAME, B_FALSE },
{ zfs_ioc_dataset_list_next, zfs_secpolicy_read,
- dataset_name, B_FALSE },
+ DATASET_NAME, B_FALSE },
{ zfs_ioc_snapshot_list_next, zfs_secpolicy_read,
- dataset_name, B_FALSE },
- { zfs_ioc_set_prop, zfs_secpolicy_none, dataset_name, B_TRUE },
- { zfs_ioc_create_minor, zfs_secpolicy_minor, dataset_name, B_FALSE },
- { zfs_ioc_remove_minor, zfs_secpolicy_minor, dataset_name, B_FALSE },
- { zfs_ioc_create, zfs_secpolicy_create, dataset_name, B_TRUE },
- { zfs_ioc_destroy, zfs_secpolicy_destroy, dataset_name, B_TRUE },
- { zfs_ioc_rollback, zfs_secpolicy_rollback, dataset_name, B_TRUE },
- { zfs_ioc_rename, zfs_secpolicy_rename, dataset_name, B_TRUE },
- { zfs_ioc_recvbackup, zfs_secpolicy_receive, dataset_name, B_TRUE },
- { zfs_ioc_sendbackup, zfs_secpolicy_send, dataset_name, B_TRUE },
- { zfs_ioc_inject_fault, zfs_secpolicy_inject, no_name, B_FALSE },
- { zfs_ioc_clear_fault, zfs_secpolicy_inject, no_name, B_FALSE },
- { zfs_ioc_inject_list_next, zfs_secpolicy_inject, no_name, B_FALSE },
- { zfs_ioc_error_log, zfs_secpolicy_inject, pool_name, B_FALSE },
- { zfs_ioc_clear, zfs_secpolicy_config, pool_name, B_TRUE },
- { zfs_ioc_promote, zfs_secpolicy_promote, dataset_name, B_TRUE },
- { zfs_ioc_destroy_snaps, zfs_secpolicy_destroy, dataset_name, B_TRUE },
- { zfs_ioc_snapshot, zfs_secpolicy_snapshot, dataset_name, B_TRUE },
- { zfs_ioc_dsobj_to_dsname, zfs_secpolicy_config, pool_name, B_FALSE },
- { zfs_ioc_obj_to_path, zfs_secpolicy_config, no_name, B_FALSE },
- { zfs_ioc_pool_set_props, zfs_secpolicy_config, pool_name, B_TRUE },
- { zfs_ioc_pool_get_props, zfs_secpolicy_read, pool_name, B_FALSE },
- { zfs_ioc_set_fsacl, zfs_secpolicy_fsacl, dataset_name, B_TRUE },
- { zfs_ioc_get_fsacl, zfs_secpolicy_read, dataset_name, B_FALSE },
+ DATASET_NAME, B_FALSE },
+ { zfs_ioc_set_prop, zfs_secpolicy_none, DATASET_NAME, B_TRUE },
+ { zfs_ioc_create_minor, zfs_secpolicy_minor, DATASET_NAME, B_FALSE },
+ { zfs_ioc_remove_minor, zfs_secpolicy_minor, DATASET_NAME, B_FALSE },
+ { zfs_ioc_create, zfs_secpolicy_create, DATASET_NAME, B_TRUE },
+ { zfs_ioc_destroy, zfs_secpolicy_destroy, DATASET_NAME, B_TRUE },
+ { zfs_ioc_rollback, zfs_secpolicy_rollback, DATASET_NAME, B_TRUE },
+ { zfs_ioc_rename, zfs_secpolicy_rename, DATASET_NAME, B_TRUE },
+ { zfs_ioc_recvbackup, zfs_secpolicy_receive, DATASET_NAME, B_TRUE },
+ { zfs_ioc_sendbackup, zfs_secpolicy_send, DATASET_NAME, B_TRUE },
+ { zfs_ioc_inject_fault, zfs_secpolicy_inject, NO_NAME, B_FALSE },
+ { zfs_ioc_clear_fault, zfs_secpolicy_inject, NO_NAME, B_FALSE },
+ { zfs_ioc_inject_list_next, zfs_secpolicy_inject, NO_NAME, B_FALSE },
+ { zfs_ioc_error_log, zfs_secpolicy_inject, POOL_NAME, B_FALSE },
+ { zfs_ioc_clear, zfs_secpolicy_config, POOL_NAME, B_TRUE },
+ { zfs_ioc_promote, zfs_secpolicy_promote, DATASET_NAME, B_TRUE },
+ { zfs_ioc_destroy_snaps, zfs_secpolicy_destroy, DATASET_NAME, B_TRUE },
+ { zfs_ioc_snapshot, zfs_secpolicy_snapshot, DATASET_NAME, B_TRUE },
+ { zfs_ioc_dsobj_to_dsname, zfs_secpolicy_config, POOL_NAME, B_FALSE },
+ { zfs_ioc_obj_to_path, zfs_secpolicy_config, NO_NAME, B_FALSE },
+ { zfs_ioc_pool_set_props, zfs_secpolicy_config, POOL_NAME, B_TRUE },
+ { zfs_ioc_pool_get_props, zfs_secpolicy_read, POOL_NAME, B_FALSE },
+ { zfs_ioc_set_fsacl, zfs_secpolicy_fsacl, DATASET_NAME, B_TRUE },
+ { zfs_ioc_get_fsacl, zfs_secpolicy_read, DATASET_NAME, B_FALSE },
{ zfs_ioc_iscsi_perm_check, zfs_secpolicy_iscsi,
- dataset_name, B_FALSE },
- { zfs_ioc_share, zfs_secpolicy_share, dataset_name, B_FALSE }
+ DATASET_NAME, B_FALSE },
+ { zfs_ioc_share, zfs_secpolicy_share, DATASET_NAME, B_FALSE }
};
static int
@@ -2204,17 +2229,17 @@ zfsdev_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp)
if (error == 0) {
zc->zc_name[sizeof (zc->zc_name) - 1] = '\0';
switch (zfs_ioc_vec[vec].zvec_namecheck) {
- case pool_name:
+ case POOL_NAME:
if (pool_namecheck(zc->zc_name, NULL, NULL) != 0)
error = EINVAL;
break;
- case dataset_name:
+ case DATASET_NAME:
if (dataset_namecheck(zc->zc_name, NULL, NULL) != 0)
error = EINVAL;
break;
- case no_name:
+ case NO_NAME:
break;
}
}
@@ -2328,7 +2353,7 @@ static struct dev_ops zfs_dev_ops = {
};
static struct modldrv zfs_modldrv = {
- &mod_driverops, "ZFS storage pool version " ZFS_VERSION_STRING,
+ &mod_driverops, "ZFS storage pool version " SPA_VERSION_STRING,
&zfs_dev_ops
};