aboutsummaryrefslogtreecommitdiff
path: root/sys/contrib/openzfs/module/zfs/zfs_ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/openzfs/module/zfs/zfs_ioctl.c')
-rw-r--r--sys/contrib/openzfs/module/zfs/zfs_ioctl.c224
1 files changed, 151 insertions, 73 deletions
diff --git a/sys/contrib/openzfs/module/zfs/zfs_ioctl.c b/sys/contrib/openzfs/module/zfs/zfs_ioctl.c
index 3b71dcb0e788..dca15f4b826d 100644
--- a/sys/contrib/openzfs/module/zfs/zfs_ioctl.c
+++ b/sys/contrib/openzfs/module/zfs/zfs_ioctl.c
@@ -6,7 +6,7 @@
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
@@ -23,11 +23,11 @@
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Portions Copyright 2011 Martin Matuska
* Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved.
- * Portions Copyright 2012 Pawel Jakub Dawidek <pawel@dawidek.net>
+ * Copyright (c) 2012 Pawel Jakub Dawidek
* Copyright (c) 2014, 2016 Joyent, Inc. All rights reserved.
* Copyright 2016 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2014, Joyent, Inc. All rights reserved.
- * Copyright (c) 2011, 2020 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2024 by Delphix. All rights reserved.
* Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
* Copyright (c) 2013 Steven Hartland. All rights reserved.
* Copyright (c) 2014 Integros [integros.com]
@@ -222,23 +222,22 @@
#include <sys/zfs_ioctl_impl.h>
kmutex_t zfsdev_state_lock;
-static zfsdev_state_t *zfsdev_state_list;
+static zfsdev_state_t zfsdev_state_listhead;
/*
* Limit maximum nvlist size. We don't want users passing in insane values
* for zc->zc_nvlist_src_size, since we will need to allocate that much memory.
* Defaults to 0=auto which is handled by platform code.
*/
-unsigned long zfs_max_nvlist_src_size = 0;
+uint64_t zfs_max_nvlist_src_size = 0;
/*
* When logging the output nvlist of an ioctl in the on-disk history, limit
* the logged size to this many bytes. This must be less than DMU_MAX_ACCESS.
* This applies primarily to zfs_ioc_channel_program().
*/
-static unsigned long zfs_history_output_max = 1024 * 1024;
+static uint64_t zfs_history_output_max = 1024 * 1024;
-uint_t zfs_fsyncer_key;
uint_t zfs_allow_log_key;
/* DATA_TYPE_ANY is used when zkey_type can vary. */
@@ -604,7 +603,7 @@ static int
zfs_secpolicy_setprop(const char *dsname, zfs_prop_t prop, nvpair_t *propval,
cred_t *cr)
{
- char *strval;
+ const char *strval;
/*
* Check permissions for special properties.
@@ -741,7 +740,7 @@ zfs_get_parent(const char *datasetname, char *parent, int parentsize)
/*
* Remove the @bla or /bla from the end of the name to get the parent.
*/
- (void) strncpy(parent, datasetname, parentsize);
+ (void) strlcpy(parent, datasetname, parentsize);
cp = strrchr(parent, '@');
if (cp != NULL) {
cp[0] = '\0';
@@ -935,7 +934,7 @@ zfs_secpolicy_snapshot(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL;
pair = nvlist_next_nvpair(snaps, pair)) {
- char *name = nvpair_name(pair);
+ char *name = (char *)nvpair_name(pair);
char *atp = strchr(name, '@');
if (atp == NULL) {
@@ -962,7 +961,7 @@ zfs_secpolicy_bookmark(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
for (nvpair_t *pair = nvlist_next_nvpair(innvl, NULL);
pair != NULL; pair = nvlist_next_nvpair(innvl, pair)) {
- char *name = nvpair_name(pair);
+ char *name = (char *)nvpair_name(pair);
char *hashp = strchr(name, '#');
if (hashp == NULL) {
@@ -988,7 +987,7 @@ zfs_secpolicy_destroy_bookmarks(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
for (pair = nvlist_next_nvpair(innvl, NULL); pair != NULL;
pair = nextpair) {
- char *name = nvpair_name(pair);
+ char *name = (char *)nvpair_name(pair);
char *hashp = strchr(name, '#');
nextpair = nvlist_next_nvpair(innvl, pair);
@@ -1036,9 +1035,9 @@ zfs_secpolicy_log_history(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
static int
zfs_secpolicy_create_clone(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
{
- char parentname[ZFS_MAX_DATASET_NAME_LEN];
- int error;
- char *origin;
+ char parentname[ZFS_MAX_DATASET_NAME_LEN];
+ int error;
+ const char *origin;
if ((error = zfs_get_parent(zc->zc_name, parentname,
sizeof (parentname))) != 0)
@@ -1081,7 +1080,7 @@ zfs_secpolicy_diff(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
(void) innvl;
int error;
- if ((error = secpolicy_sys_config(cr, B_FALSE)) == 0)
+ if (secpolicy_sys_config(cr, B_FALSE) == 0)
return (0);
error = zfs_secpolicy_write_perms(zc->zc_name, ZFS_DELEG_PERM_DIFF, cr);
@@ -1230,8 +1229,8 @@ zfs_secpolicy_tmp_snapshot(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
*/
int error;
- if ((error = zfs_secpolicy_write_perms(zc->zc_name,
- ZFS_DELEG_PERM_DIFF, cr)) == 0)
+ if (zfs_secpolicy_write_perms(zc->zc_name,
+ ZFS_DELEG_PERM_DIFF, cr) == 0)
return (0);
error = zfs_secpolicy_snapshot_perms(zc->zc_name, cr);
@@ -1279,8 +1278,7 @@ get_nvlist(uint64_t nvl, uint64_t size, int iflag, nvlist_t **nvp)
packed = vmem_alloc(size, KM_SLEEP);
- if ((error = ddi_copyin((void *)(uintptr_t)nvl, packed, size,
- iflag)) != 0) {
+ if (ddi_copyin((void *)(uintptr_t)nvl, packed, size, iflag) != 0) {
vmem_free(packed, size);
return (SET_ERROR(EFAULT));
}
@@ -1461,7 +1459,7 @@ zfs_ioc_pool_create(zfs_cmd_t *zc)
nvlist_t *nvl = NULL;
nvlist_t *hidden_args = NULL;
uint64_t version = SPA_VERSION;
- char *tname;
+ const char *tname;
(void) nvlist_lookup_uint64(props,
zpool_prop_to_name(ZPOOL_PROP_VERSION), &version);
@@ -1583,8 +1581,9 @@ zfs_ioc_pool_configs(zfs_cmd_t *zc)
nvlist_t *configs;
int error;
- if ((configs = spa_all_configs(&zc->zc_cookie)) == NULL)
- return (SET_ERROR(EEXIST));
+ error = spa_all_configs(&zc->zc_cookie, &configs);
+ if (error)
+ return (error);
error = put_nvlist(zc, configs);
@@ -1686,6 +1685,47 @@ zfs_ioc_pool_scan(zfs_cmd_t *zc)
return (error);
}
+/*
+ * inputs:
+ * poolname name of the pool
+ * scan_type scan func (pool_scan_func_t)
+ * scan_command scrub pause/resume flag (pool_scrub_cmd_t)
+ */
+static const zfs_ioc_key_t zfs_keys_pool_scrub[] = {
+ {"scan_type", DATA_TYPE_UINT64, 0},
+ {"scan_command", DATA_TYPE_UINT64, 0},
+};
+
+static int
+zfs_ioc_pool_scrub(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl)
+{
+ spa_t *spa;
+ int error;
+ uint64_t scan_type, scan_cmd;
+
+ if (nvlist_lookup_uint64(innvl, "scan_type", &scan_type) != 0)
+ return (SET_ERROR(EINVAL));
+ if (nvlist_lookup_uint64(innvl, "scan_command", &scan_cmd) != 0)
+ return (SET_ERROR(EINVAL));
+
+ if (scan_cmd >= POOL_SCRUB_FLAGS_END)
+ return (SET_ERROR(EINVAL));
+
+ if ((error = spa_open(poolname, &spa, FTAG)) != 0)
+ return (error);
+
+ if (scan_cmd == POOL_SCRUB_PAUSE) {
+ error = spa_scrub_pause_resume(spa, POOL_SCRUB_PAUSE);
+ } else if (scan_type == POOL_SCAN_NONE) {
+ error = spa_scan_stop(spa);
+ } else {
+ error = spa_scan(spa, scan_type);
+ }
+
+ spa_close(spa, FTAG);
+ return (error);
+}
+
static int
zfs_ioc_pool_freeze(zfs_cmd_t *zc)
{
@@ -1846,7 +1886,7 @@ zfs_ioc_vdev_add(zfs_cmd_t *zc)
error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
zc->zc_iflags, &config);
if (error == 0) {
- error = spa_vdev_add(spa, config);
+ error = spa_vdev_add(spa, config, zc->zc_flags);
nvlist_free(config);
}
spa_close(spa, FTAG);
@@ -1912,6 +1952,10 @@ zfs_ioc_vdev_set_state(zfs_cmd_t *zc)
error = vdev_degrade(spa, zc->zc_guid, zc->zc_obj);
break;
+ case VDEV_STATE_REMOVED:
+ error = vdev_remove_wanted(spa, zc->zc_guid);
+ break;
+
default:
error = SET_ERROR(EINVAL);
}
@@ -2035,7 +2079,7 @@ zfs_ioc_objset_stats_impl(zfs_cmd_t *zc, objset_t *os)
dmu_objset_fast_stat(os, &zc->zc_objset_stats);
- if (zc->zc_nvlist_dst != 0 &&
+ if (!zc->zc_simple && zc->zc_nvlist_dst != 0 &&
(error = dsl_prop_get_all(os, &nv)) == 0) {
dmu_objset_stats(os, nv);
/*
@@ -2322,6 +2366,7 @@ zfs_ioc_snapshot_list_next(zfs_cmd_t *zc)
}
if (zc->zc_simple) {
+ dsl_dataset_fast_stat(ds, &zc->zc_objset_stats);
dsl_dataset_rele(ds, FTAG);
break;
}
@@ -2477,11 +2522,27 @@ zfs_prop_set_special(const char *dsname, zprop_source_t source,
case ZFS_PROP_VOLSIZE:
err = zvol_set_volsize(dsname, intval);
break;
- case ZFS_PROP_SNAPDEV:
- err = zvol_set_snapdev(dsname, source, intval);
+ case ZFS_PROP_VOLTHREADING:
+ err = zvol_set_volthreading(dsname, intval);
+ /*
+ * Set err to -1 to force the zfs_set_prop_nvlist code down the
+ * default path to set the value in the nvlist.
+ */
+ if (err == 0)
+ err = -1;
break;
+ case ZFS_PROP_SNAPDEV:
case ZFS_PROP_VOLMODE:
- err = zvol_set_volmode(dsname, source, intval);
+ err = zvol_set_common(dsname, prop, source, intval);
+ break;
+ case ZFS_PROP_READONLY:
+ err = zvol_set_ro(dsname, intval);
+ /*
+ * Set err to -1 to force the zfs_set_prop_nvlist code down the
+ * default path to set the value in the nvlist.
+ */
+ if (err == 0)
+ err = -1;
break;
case ZFS_PROP_VERSION:
{
@@ -2677,7 +2738,6 @@ retry:
pair = NULL;
while ((pair = nvlist_next_nvpair(genericnvl, pair)) != NULL) {
const char *propname = nvpair_name(pair);
- err = 0;
propval = pair;
if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
@@ -2926,7 +2986,7 @@ zfs_ioc_pool_set_props(zfs_cmd_t *zc)
mutex_enter(&spa_namespace_lock);
if ((spa = spa_lookup(zc->zc_name)) != NULL) {
spa_configfile_set(spa, props, B_FALSE);
- spa_write_cachefile(spa, B_FALSE, B_TRUE);
+ spa_write_cachefile(spa, B_FALSE, B_TRUE, B_FALSE);
}
mutex_exit(&spa_namespace_lock);
if (spa != NULL) {
@@ -3090,7 +3150,7 @@ zfs_ioc_set_fsacl(zfs_cmd_t *zc)
/*
* Verify nvlist is constructed correctly
*/
- if ((error = zfs_deleg_verify_nvlist(fsaclnv)) != 0) {
+ if (zfs_deleg_verify_nvlist(fsaclnv) != 0) {
nvlist_free(fsaclnv);
return (SET_ERROR(EINVAL));
}
@@ -3913,7 +3973,7 @@ static int
zfs_ioc_channel_program(const char *poolname, nvlist_t *innvl,
nvlist_t *outnvl)
{
- char *program;
+ const char *program;
uint64_t instrlimit, memlimit;
boolean_t sync_flag;
nvpair_t *nvarg = NULL;
@@ -4067,7 +4127,8 @@ zfs_ioc_pool_initialize(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl)
if (!(cmd_type == POOL_INITIALIZE_CANCEL ||
cmd_type == POOL_INITIALIZE_START ||
- cmd_type == POOL_INITIALIZE_SUSPEND)) {
+ cmd_type == POOL_INITIALIZE_SUSPEND ||
+ cmd_type == POOL_INITIALIZE_UNINIT)) {
return (SET_ERROR(EINVAL));
}
@@ -4333,7 +4394,7 @@ zfs_ioc_rollback(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl)
{
zfsvfs_t *zfsvfs;
zvol_state_handle_t *zv;
- char *target = NULL;
+ const char *target = NULL;
int error;
(void) nvlist_lookup_string(innvl, "target", &target);
@@ -4409,7 +4470,7 @@ zfs_ioc_redact(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl)
{
(void) outnvl;
nvlist_t *redactnvl = NULL;
- char *redactbook = NULL;
+ const char *redactbook = NULL;
if (nvlist_lookup_nvlist(innvl, "snapnv", &redactnvl) != 0)
return (SET_ERROR(EINVAL));
@@ -4805,10 +4866,10 @@ propval_equals(nvpair_t *p1, nvpair_t *p2)
return (B_FALSE);
if (nvpair_type(p1) == DATA_TYPE_STRING) {
- char *valstr1, *valstr2;
+ const char *valstr1, *valstr2;
- VERIFY(nvpair_value_string(p1, (char **)&valstr1) == 0);
- VERIFY(nvpair_value_string(p2, (char **)&valstr2) == 0);
+ VERIFY(nvpair_value_string(p1, &valstr1) == 0);
+ VERIFY(nvpair_value_string(p2, &valstr2) == 0);
return (strcmp(valstr1, valstr2) == 0);
} else {
uint64_t intval1, intval2;
@@ -4873,6 +4934,11 @@ extract_delay_props(nvlist_t *props)
static const zfs_prop_t delayable[] = {
ZFS_PROP_REFQUOTA,
ZFS_PROP_KEYLOCATION,
+ /*
+ * Setting ZFS_PROP_SHARESMB requires the objset type to be
+ * known, which is not possible prior to receipt of raw sends.
+ */
+ ZFS_PROP_SHARESMB,
0
};
int i;
@@ -4924,9 +4990,9 @@ static boolean_t zfs_ioc_recv_inject_err;
* encountered errors, if any. It's the callers responsibility to free.
*/
static int
-zfs_ioc_recv_impl(char *tofs, char *tosnap, char *origin, nvlist_t *recvprops,
- nvlist_t *localprops, nvlist_t *hidden_args, boolean_t force,
- boolean_t resumable, int input_fd,
+zfs_ioc_recv_impl(char *tofs, char *tosnap, const char *origin,
+ nvlist_t *recvprops, nvlist_t *localprops, nvlist_t *hidden_args,
+ boolean_t force, boolean_t heal, boolean_t resumable, int input_fd,
dmu_replay_record_t *begin_record, uint64_t *read_bytes,
uint64_t *errflags, nvlist_t **errors)
{
@@ -4936,6 +5002,7 @@ zfs_ioc_recv_impl(char *tofs, char *tosnap, char *origin, nvlist_t *recvprops,
offset_t off, noff;
nvlist_t *local_delayprops = NULL;
nvlist_t *recv_delayprops = NULL;
+ nvlist_t *inherited_delayprops = NULL;
nvlist_t *origprops = NULL; /* existing properties */
nvlist_t *origrecvd = NULL; /* existing received properties */
boolean_t first_recvd_props = B_FALSE;
@@ -4951,7 +5018,7 @@ zfs_ioc_recv_impl(char *tofs, char *tosnap, char *origin, nvlist_t *recvprops,
return (SET_ERROR(EBADF));
noff = off = zfs_file_off(input_fp);
- error = dmu_recv_begin(tofs, tosnap, begin_record, force,
+ error = dmu_recv_begin(tofs, tosnap, begin_record, force, heal,
resumable, localprops, hidden_args, origin, &drc, input_fp,
&off);
if (error != 0)
@@ -5050,6 +5117,7 @@ zfs_ioc_recv_impl(char *tofs, char *tosnap, char *origin, nvlist_t *recvprops,
local_delayprops = extract_delay_props(oprops);
(void) zfs_set_prop_nvlist(tofs, ZPROP_SRC_LOCAL,
oprops, *errors);
+ inherited_delayprops = extract_delay_props(xprops);
(void) zfs_set_prop_nvlist(tofs, ZPROP_SRC_INHERITED,
xprops, *errors);
@@ -5107,6 +5175,10 @@ zfs_ioc_recv_impl(char *tofs, char *tosnap, char *origin, nvlist_t *recvprops,
(void) zfs_set_prop_nvlist(tofs, ZPROP_SRC_LOCAL,
local_delayprops, *errors);
}
+ if (inherited_delayprops != NULL && error == 0) {
+ (void) zfs_set_prop_nvlist(tofs, ZPROP_SRC_INHERITED,
+ inherited_delayprops, *errors);
+ }
}
/*
@@ -5126,6 +5198,10 @@ zfs_ioc_recv_impl(char *tofs, char *tosnap, char *origin, nvlist_t *recvprops,
ASSERT(nvlist_merge(localprops, local_delayprops, 0) == 0);
nvlist_free(local_delayprops);
}
+ if (inherited_delayprops != NULL) {
+ ASSERT(nvlist_merge(localprops, inherited_delayprops, 0) == 0);
+ nvlist_free(inherited_delayprops);
+ }
*read_bytes = off - noff;
#ifdef ZFS_DEBUG
@@ -5262,7 +5338,7 @@ zfs_ioc_recv(zfs_cmd_t *zc)
nvlist_t *errors = NULL;
nvlist_t *recvdprops = NULL;
nvlist_t *localprops = NULL;
- char *origin = NULL;
+ const char *origin = NULL;
char *tosnap;
char tofs[ZFS_MAX_DATASET_NAME_LEN];
int error = 0;
@@ -5294,7 +5370,7 @@ zfs_ioc_recv(zfs_cmd_t *zc)
begin_record.drr_u.drr_begin = zc->zc_begin_record;
error = zfs_ioc_recv_impl(tofs, tosnap, origin, recvdprops, localprops,
- NULL, zc->zc_guid, B_FALSE, zc->zc_cookie, &begin_record,
+ NULL, zc->zc_guid, B_FALSE, B_FALSE, zc->zc_cookie, &begin_record,
&zc->zc_cookie, &zc->zc_obj, &errors);
nvlist_free(recvdprops);
nvlist_free(localprops);
@@ -5327,6 +5403,7 @@ zfs_ioc_recv(zfs_cmd_t *zc)
* "begin_record" -> non-byteswapped dmu_replay_record_t
* "input_fd" -> file descriptor to read stream from (int32)
* (optional) "force" -> force flag (value ignored)
+ * (optional) "heal" -> use send stream to heal data corruption
* (optional) "resumable" -> resumable flag (value ignored)
* (optional) "cleanup_fd" -> unused
* (optional) "action_handle" -> unused
@@ -5347,6 +5424,7 @@ static const zfs_ioc_key_t zfs_keys_recv_new[] = {
{"begin_record", DATA_TYPE_BYTE_ARRAY, 0},
{"input_fd", DATA_TYPE_INT32, 0},
{"force", DATA_TYPE_BOOLEAN, ZK_OPTIONAL},
+ {"heal", DATA_TYPE_BOOLEAN, ZK_OPTIONAL},
{"resumable", DATA_TYPE_BOOLEAN, ZK_OPTIONAL},
{"cleanup_fd", DATA_TYPE_INT32, ZK_OPTIONAL},
{"action_handle", DATA_TYPE_UINT64, ZK_OPTIONAL},
@@ -5362,11 +5440,12 @@ zfs_ioc_recv_new(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl)
nvlist_t *recvprops = NULL;
nvlist_t *localprops = NULL;
nvlist_t *hidden_args = NULL;
- char *snapname;
- char *origin = NULL;
+ const char *snapname;
+ const char *origin = NULL;
char *tosnap;
char tofs[ZFS_MAX_DATASET_NAME_LEN];
boolean_t force;
+ boolean_t heal;
boolean_t resumable;
uint64_t read_bytes = 0;
uint64_t errflags = 0;
@@ -5396,6 +5475,7 @@ zfs_ioc_recv_new(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl)
input_fd = fnvlist_lookup_int32(innvl, "input_fd");
force = nvlist_exists(innvl, "force");
+ heal = nvlist_exists(innvl, "heal");
resumable = nvlist_exists(innvl, "resumable");
/* we still use "props" here for backwards compatibility */
@@ -5412,7 +5492,7 @@ zfs_ioc_recv_new(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl)
return (error);
error = zfs_ioc_recv_impl(tofs, tosnap, origin, recvprops, localprops,
- hidden_args, force, resumable, input_fd, begin_record,
+ hidden_args, force, heal, resumable, input_fd, begin_record,
&read_bytes, &errflags, &errors);
fnvlist_add_uint64(outnvl, "read_bytes", read_bytes);
@@ -5671,17 +5751,12 @@ zfs_ioc_error_log(zfs_cmd_t *zc)
{
spa_t *spa;
int error;
- uint64_t count = zc->zc_nvlist_dst_size;
if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
return (error);
error = spa_get_errlog(spa, (void *)(uintptr_t)zc->zc_nvlist_dst,
- &count);
- if (error == 0)
- zc->zc_nvlist_dst_size = count;
- else
- zc->zc_nvlist_dst_size = spa_get_errlog_size(spa);
+ &zc->zc_nvlist_dst_size);
spa_close(spa, FTAG);
@@ -6215,7 +6290,7 @@ zfs_ioc_hold(const char *pool, nvlist_t *args, nvlist_t *errlist)
/* make sure the user didn't pass us any invalid (empty) tags */
for (pair = nvlist_next_nvpair(holds, NULL); pair != NULL;
pair = nvlist_next_nvpair(holds, pair)) {
- char *htag;
+ const char *htag;
error = nvpair_value_string(pair, &htag);
if (error != 0)
@@ -6334,7 +6409,7 @@ zfs_ioc_events_next(zfs_cmd_t *zc)
static int
zfs_ioc_events_clear(zfs_cmd_t *zc)
{
- int count;
+ uint_t count;
zfs_zevent_drain_all(&count);
zc->zc_cookie = count;
@@ -6435,7 +6510,7 @@ zfs_ioc_space_snaps(const char *lastsnap, nvlist_t *innvl, nvlist_t *outnvl)
int error;
dsl_pool_t *dp;
dsl_dataset_t *new, *old;
- char *firstsnap;
+ const char *firstsnap;
uint64_t used, comp, uncomp;
firstsnap = fnvlist_lookup_string(innvl, "firstsnap");
@@ -6516,7 +6591,7 @@ zfs_ioc_send_new(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl)
(void) outnvl;
int error;
offset_t off;
- char *fromname = NULL;
+ const char *fromname = NULL;
int fd;
zfs_file_t *fp;
boolean_t largeblockok;
@@ -6526,7 +6601,7 @@ zfs_ioc_send_new(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl)
boolean_t savedok;
uint64_t resumeobj = 0;
uint64_t resumeoff = 0;
- char *redactbook = NULL;
+ const char *redactbook = NULL;
fd = fnvlist_lookup_int32(innvl, "fd");
@@ -6616,8 +6691,8 @@ zfs_ioc_send_space(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl)
dsl_dataset_t *tosnap;
dsl_dataset_t *fromsnap = NULL;
int error;
- char *fromname = NULL;
- char *redactlist_book = NULL;
+ const char *fromname = NULL;
+ const char *redactlist_book = NULL;
boolean_t largeblockok;
boolean_t embedok;
boolean_t compressok;
@@ -7200,6 +7275,11 @@ zfs_ioctl_init(void)
POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_FALSE, B_FALSE,
zfs_keys_vdev_set_props, ARRAY_SIZE(zfs_keys_vdev_set_props));
+ zfs_ioctl_register("scrub", ZFS_IOC_POOL_SCRUB,
+ zfs_ioc_pool_scrub, zfs_secpolicy_config, POOL_NAME,
+ POOL_CHECK_NONE, B_TRUE, B_TRUE,
+ zfs_keys_pool_scrub, ARRAY_SIZE(zfs_keys_pool_scrub));
+
/* IOCTLS that use the legacy function signature */
zfs_ioctl_register_legacy(ZFS_IOC_POOL_FREEZE, zfs_ioc_pool_freeze,
@@ -7361,7 +7441,7 @@ zfs_check_input_nvpairs(nvlist_t *innvl, const zfs_ioc_vec_t *vec)
*/
for (nvpair_t *pair = nvlist_next_nvpair(innvl, NULL);
pair != NULL; pair = nvlist_next_nvpair(innvl, pair)) {
- char *name = nvpair_name(pair);
+ const char *name = nvpair_name(pair);
data_type_t type = nvpair_type(pair);
boolean_t identified = B_FALSE;
@@ -7452,7 +7532,7 @@ zfsdev_getminor(zfs_file_t *fp, minor_t *minorp)
mutex_enter(&zfsdev_state_lock);
- for (zs = zfsdev_state_list; zs != NULL; zs = zs->zs_next) {
+ for (zs = &zfsdev_state_listhead; zs != NULL; zs = zs->zs_next) {
if (zs->zs_minor == -1)
continue;
@@ -7474,9 +7554,9 @@ zfsdev_get_state(minor_t minor, enum zfsdev_state_type which)
{
zfsdev_state_t *zs;
- for (zs = zfsdev_state_list; zs != NULL; zs = zs->zs_next) {
+ for (zs = &zfsdev_state_listhead; zs != NULL; zs = zs->zs_next) {
if (zs->zs_minor == minor) {
- smp_rmb();
+ membar_consumer();
switch (which) {
case ZST_ONEXIT:
return (zs->zs_onexit);
@@ -7528,7 +7608,7 @@ zfsdev_state_init(void *priv)
if (minor == 0)
return (SET_ERROR(ENXIO));
- for (zs = zfsdev_state_list; zs != NULL; zs = zs->zs_next) {
+ for (zs = &zfsdev_state_listhead; zs != NULL; zs = zs->zs_next) {
if (zs->zs_minor == -1)
break;
zsprev = zs;
@@ -7812,13 +7892,11 @@ zfs_kmod_init(void)
zfs_ioctl_init();
mutex_init(&zfsdev_state_lock, NULL, MUTEX_DEFAULT, NULL);
- zfsdev_state_list = kmem_zalloc(sizeof (zfsdev_state_t), KM_SLEEP);
- zfsdev_state_list->zs_minor = -1;
+ zfsdev_state_listhead.zs_minor = -1;
if ((error = zfsdev_attach()) != 0)
goto out;
- tsd_create(&zfs_fsyncer_key, NULL);
tsd_create(&rrw_tsd_key, rrw_tsd_destroy);
tsd_create(&zfs_allow_log_key, zfs_allow_log_destroy);
@@ -7840,13 +7918,14 @@ zfs_kmod_fini(void)
mutex_destroy(&zfsdev_state_lock);
- for (zs = zfsdev_state_list; zs != NULL; zs = zsnext) {
+ for (zs = &zfsdev_state_listhead; zs != NULL; zs = zsnext) {
zsnext = zs->zs_next;
if (zs->zs_onexit)
zfs_onexit_destroy(zs->zs_onexit);
if (zs->zs_zevent)
zfs_zevent_destroy(zs->zs_zevent);
- kmem_free(zs, sizeof (zfsdev_state_t));
+ if (zs != &zfsdev_state_listhead)
+ kmem_free(zs, sizeof (zfsdev_state_t));
}
zfs_ereport_taskq_fini(); /* run before zfs_fini() on Linux */
@@ -7854,13 +7933,12 @@ zfs_kmod_fini(void)
spa_fini();
zvol_fini();
- tsd_destroy(&zfs_fsyncer_key);
tsd_destroy(&rrw_tsd_key);
tsd_destroy(&zfs_allow_log_key);
}
-ZFS_MODULE_PARAM(zfs, zfs_, max_nvlist_src_size, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs, zfs_, max_nvlist_src_size, U64, ZMOD_RW,
"Maximum size in bytes allowed for src nvlist passed with ZFS ioctls");
-ZFS_MODULE_PARAM(zfs, zfs_, history_output_max, ULONG, ZMOD_RW,
+ZFS_MODULE_PARAM(zfs, zfs_, history_output_max, U64, ZMOD_RW,
"Maximum size in bytes of ZFS ioctl output that will be logged");