aboutsummaryrefslogtreecommitdiff
path: root/lib/libzfs/libzfs_dataset.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libzfs/libzfs_dataset.c')
-rw-r--r--lib/libzfs/libzfs_dataset.c215
1 files changed, 167 insertions, 48 deletions
diff --git a/lib/libzfs/libzfs_dataset.c b/lib/libzfs/libzfs_dataset.c
index 4e25985a4ae8..231bbbd92dbf 100644
--- a/lib/libzfs/libzfs_dataset.c
+++ b/lib/libzfs/libzfs_dataset.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.
*
@@ -67,6 +67,10 @@
#include "libzfs_impl.h"
#include "zfs_deleg.h"
+static __thread struct passwd gpwd;
+static __thread struct group ggrp;
+static __thread char rpbuf[2048];
+
static int userquota_propname_decode(const char *propname, boolean_t zoned,
zfs_userquota_prop_t *typep, char *domain, int domainlen, uint64_t *ridp);
@@ -528,6 +532,30 @@ make_dataset_simple_handle_zc(zfs_handle_t *pzhp, zfs_cmd_t *zc)
zhp->zfs_type = ZFS_TYPE_SNAPSHOT;
zhp->zpool_hdl = zpool_handle(zhp);
+ if (zc->zc_objset_stats.dds_creation_txg != 0) {
+ /* structure assignment */
+ zhp->zfs_dmustats = zc->zc_objset_stats;
+ } else {
+ if (get_stats_ioctl(zhp, zc) == -1) {
+ zcmd_free_nvlists(zc);
+ free(zhp);
+ return (NULL);
+ }
+ if (make_dataset_handle_common(zhp, zc) == -1) {
+ zcmd_free_nvlists(zc);
+ free(zhp);
+ return (NULL);
+ }
+ }
+
+ if (zhp->zfs_dmustats.dds_is_snapshot ||
+ strchr(zc->zc_name, '@') != NULL)
+ zhp->zfs_type = ZFS_TYPE_SNAPSHOT;
+ else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL)
+ zhp->zfs_type = ZFS_TYPE_VOLUME;
+ else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZFS)
+ zhp->zfs_type = ZFS_TYPE_FILESYSTEM;
+
return (zhp);
}
@@ -689,6 +717,7 @@ zfs_open(libzfs_handle_t *hdl, const char *path, int types)
*/
if (!zfs_validate_name(hdl, path, types, B_FALSE)) {
(void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
+ errno = EINVAL;
return (NULL);
}
@@ -716,8 +745,8 @@ zfs_open(libzfs_handle_t *hdl, const char *path, int types)
* to get the parent dataset name only.
*/
assert(bookp - path < sizeof (dsname));
- (void) strncpy(dsname, path, bookp - path);
- dsname[bookp - path] = '\0';
+ (void) strlcpy(dsname, path,
+ MIN(sizeof (dsname), bookp - path + 1));
/*
* Create handle for the parent dataset.
@@ -732,10 +761,11 @@ zfs_open(libzfs_handle_t *hdl, const char *path, int types)
* Iterate bookmarks to find the right one.
*/
errno = 0;
- if ((zfs_iter_bookmarks(pzhp, zfs_open_bookmarks_cb,
+ if ((zfs_iter_bookmarks_v2(pzhp, 0, zfs_open_bookmarks_cb,
&cb_data) == 0) && (cb_data.zhp == NULL)) {
(void) zfs_error(hdl, EZFS_NOENT, errbuf);
zfs_close(pzhp);
+ errno = ENOENT;
return (NULL);
}
if (cb_data.zhp == NULL) {
@@ -754,6 +784,7 @@ zfs_open(libzfs_handle_t *hdl, const char *path, int types)
if (!(types & zhp->zfs_type)) {
(void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
zfs_close(zhp);
+ errno = EINVAL;
return (NULL);
}
@@ -1002,11 +1033,12 @@ zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl,
{
nvpair_t *elem;
uint64_t intval;
- char *strval;
+ const char *strval;
zfs_prop_t prop;
nvlist_t *ret;
int chosen_normal = -1;
int chosen_utf = -1;
+ int set_maxbs = 0;
if (nvlist_alloc(&ret, NV_UNIQUE_NAME, 0) != 0) {
(void) no_memory(hdl);
@@ -1225,12 +1257,17 @@ zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl,
(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
goto error;
}
+ /* save the ZFS_PROP_RECORDSIZE during create op */
+ if (zpool_hdl == NULL && prop == ZFS_PROP_RECORDSIZE) {
+ set_maxbs = intval;
+ }
break;
}
case ZFS_PROP_SPECIAL_SMALL_BLOCKS:
{
- int maxbs = SPA_OLD_MAXBLOCKSIZE;
+ int maxbs =
+ set_maxbs == 0 ? SPA_OLD_MAXBLOCKSIZE : set_maxbs;
char buf[64];
if (zpool_hdl != NULL) {
@@ -1738,8 +1775,6 @@ error:
return (ret);
}
-
-
/*
* Given an nvlist of property names and values, set the properties for the
* given dataset.
@@ -1747,6 +1782,18 @@ error:
int
zfs_prop_set_list(zfs_handle_t *zhp, nvlist_t *props)
{
+ return (zfs_prop_set_list_flags(zhp, props, 0));
+}
+
+/*
+ * Given an nvlist of property names, values and flags, set the properties
+ * for the given dataset. If ZFS_SET_NOMOUNT is set, it allows to update
+ * mountpoint, sharenfs and sharesmb properties without (un/re)mounting
+ * and (un/re)sharing the dataset.
+ */
+int
+zfs_prop_set_list_flags(zfs_handle_t *zhp, nvlist_t *props, int flags)
+{
zfs_cmd_t zc = {"\0"};
int ret = -1;
prop_changelist_t **cls = NULL;
@@ -1756,7 +1803,8 @@ zfs_prop_set_list(zfs_handle_t *zhp, nvlist_t *props)
nvlist_t *nvl;
int nvl_len = 0;
int added_resv = 0;
- zfs_prop_t prop = 0;
+ zfs_prop_t prop;
+ boolean_t nsprop = B_FALSE;
nvpair_t *elem;
(void) snprintf(errbuf, sizeof (errbuf),
@@ -1803,6 +1851,7 @@ zfs_prop_set_list(zfs_handle_t *zhp, nvlist_t *props)
elem = nvlist_next_nvpair(nvl, elem)) {
prop = zfs_name_to_prop(nvpair_name(elem));
+ nsprop |= zfs_is_namespace_prop(prop);
assert(cl_idx < nvl_len);
/*
@@ -1813,7 +1862,9 @@ zfs_prop_set_list(zfs_handle_t *zhp, nvlist_t *props)
if (prop != ZFS_PROP_CANMOUNT ||
(fnvpair_value_uint64(elem) == ZFS_CANMOUNT_OFF &&
zfs_is_mounted(zhp, NULL))) {
- cls[cl_idx] = changelist_gather(zhp, prop, 0, 0);
+ cls[cl_idx] = changelist_gather(zhp, prop,
+ ((flags & ZFS_SET_NOMOUNT) ?
+ CL_GATHER_DONT_UNMOUNT : 0), 0);
if (cls[cl_idx] == NULL)
goto error;
}
@@ -1901,8 +1952,7 @@ zfs_prop_set_list(zfs_handle_t *zhp, nvlist_t *props)
* if one of the options handled by the generic
* Linux namespace layer has been modified.
*/
- if (zfs_is_namespace_prop(prop) &&
- zfs_is_mounted(zhp, NULL))
+ if (nsprop && zfs_is_mounted(zhp, NULL))
ret = zfs_mount(zhp, MNTOPT_REMOUNT, 0);
}
}
@@ -2005,7 +2055,8 @@ zfs_prop_inherit(zfs_handle_t *zhp, const char *propname, boolean_t received)
if ((ret = changelist_prefix(cl)) != 0)
goto error;
- if ((ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_INHERIT_PROP, &zc)) != 0) {
+ if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_INHERIT_PROP, &zc) != 0) {
+ changelist_free(cl);
return (zfs_standard_error(hdl, errno, errbuf));
} else {
@@ -2037,7 +2088,7 @@ error:
* extract them appropriately.
*/
uint64_t
-getprop_uint64(zfs_handle_t *zhp, zfs_prop_t prop, char **source)
+getprop_uint64(zfs_handle_t *zhp, zfs_prop_t prop, const char **source)
{
nvlist_t *nv;
uint64_t value;
@@ -2051,14 +2102,14 @@ getprop_uint64(zfs_handle_t *zhp, zfs_prop_t prop, char **source)
verify(!zhp->zfs_props_table ||
zhp->zfs_props_table[prop] == B_TRUE);
value = zfs_prop_default_numeric(prop);
- *source = (char *)"";
+ *source = "";
}
return (value);
}
static const char *
-getprop_string(zfs_handle_t *zhp, zfs_prop_t prop, char **source)
+getprop_string(zfs_handle_t *zhp, zfs_prop_t prop, const char **source)
{
nvlist_t *nv;
const char *value;
@@ -2072,7 +2123,7 @@ getprop_string(zfs_handle_t *zhp, zfs_prop_t prop, char **source)
verify(!zhp->zfs_props_table ||
zhp->zfs_props_table[prop] == B_TRUE);
value = zfs_prop_default_string(prop);
- *source = (char *)"";
+ *source = "";
}
return (value);
@@ -2081,20 +2132,21 @@ getprop_string(zfs_handle_t *zhp, zfs_prop_t prop, char **source)
static boolean_t
zfs_is_recvd_props_mode(zfs_handle_t *zhp)
{
- return (zhp->zfs_props == zhp->zfs_recvd_props);
+ return (zhp->zfs_props != NULL &&
+ zhp->zfs_props == zhp->zfs_recvd_props);
}
static void
-zfs_set_recvd_props_mode(zfs_handle_t *zhp, uint64_t *cookie)
+zfs_set_recvd_props_mode(zfs_handle_t *zhp, uintptr_t *cookie)
{
- *cookie = (uint64_t)(uintptr_t)zhp->zfs_props;
+ *cookie = (uintptr_t)zhp->zfs_props;
zhp->zfs_props = zhp->zfs_recvd_props;
}
static void
-zfs_unset_recvd_props_mode(zfs_handle_t *zhp, uint64_t *cookie)
+zfs_unset_recvd_props_mode(zfs_handle_t *zhp, uintptr_t *cookie)
{
- zhp->zfs_props = (nvlist_t *)(uintptr_t)*cookie;
+ zhp->zfs_props = (nvlist_t *)*cookie;
*cookie = 0;
}
@@ -2109,7 +2161,7 @@ zfs_unset_recvd_props_mode(zfs_handle_t *zhp, uint64_t *cookie)
*/
static int
get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src,
- char **source, uint64_t *val)
+ const char **source, uint64_t *val)
{
zfs_cmd_t zc = {"\0"};
nvlist_t *zplprops = NULL;
@@ -2283,6 +2335,28 @@ get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src,
*val = zhp->zfs_dmustats.dds_redacted;
break;
+ case ZFS_PROP_GUID:
+ if (zhp->zfs_dmustats.dds_guid != 0)
+ *val = zhp->zfs_dmustats.dds_guid;
+ else
+ *val = getprop_uint64(zhp, prop, source);
+ break;
+
+ case ZFS_PROP_CREATETXG:
+ /*
+ * We can directly read createtxg property from zfs
+ * handle for Filesystem, Snapshot and ZVOL types.
+ */
+ if (((zhp->zfs_type == ZFS_TYPE_FILESYSTEM) ||
+ (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) ||
+ (zhp->zfs_type == ZFS_TYPE_VOLUME)) &&
+ (zhp->zfs_dmustats.dds_creation_txg != 0)) {
+ *val = zhp->zfs_dmustats.dds_creation_txg;
+ break;
+ } else {
+ *val = getprop_uint64(zhp, prop, source);
+ }
+ zfs_fallthrough;
default:
switch (zfs_prop_get_type(prop)) {
case PROP_TYPE_NUMBER:
@@ -2319,7 +2393,7 @@ get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src,
* Calculate the source type, given the raw source string.
*/
static void
-get_source(zfs_handle_t *zhp, zprop_source_t *srctype, char *source,
+get_source(zfs_handle_t *zhp, zprop_source_t *srctype, const char *source,
char *statbuf, size_t statlen)
{
if (statbuf == NULL ||
@@ -2358,7 +2432,7 @@ zfs_prop_get_recvd(zfs_handle_t *zhp, const char *propname, char *propbuf,
prop = zfs_name_to_prop(propname);
if (prop != ZPROP_USERPROP) {
- uint64_t cookie;
+ uintptr_t cookie;
if (!nvlist_exists(zhp->zfs_recvd_props, propname))
return (-1);
zfs_set_recvd_props_mode(zhp, &cookie);
@@ -2367,7 +2441,7 @@ zfs_prop_get_recvd(zfs_handle_t *zhp, const char *propname, char *propbuf,
zfs_unset_recvd_props_mode(zhp, &cookie);
} else {
nvlist_t *propval;
- char *recvdval;
+ const char *recvdval;
if (nvlist_lookup_nvlist(zhp->zfs_recvd_props,
propname, &propval) != 0)
return (-1);
@@ -2425,7 +2499,7 @@ get_clones_cb(zfs_handle_t *zhp, void *arg)
}
out:
- (void) zfs_iter_children(zhp, get_clones_cb, gca);
+ (void) zfs_iter_children_v2(zhp, 0, get_clones_cb, gca);
zfs_close(zhp);
return (0);
}
@@ -2569,7 +2643,7 @@ zcp_check(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t intval,
(u_longlong_t)intval, (u_longlong_t)ans);
}
} else {
- char *str_ans;
+ const char *str_ans;
error = nvlist_lookup_string(retnvl, "value", &str_ans);
if (error != 0) {
(void) fprintf(stderr, "%s: zcp check error: "
@@ -2601,7 +2675,7 @@ int
zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
zprop_source_t *src, char *statbuf, size_t statlen, boolean_t literal)
{
- char *source = NULL;
+ const char *source = NULL;
uint64_t val;
const char *str;
const char *strval;
@@ -2710,7 +2784,13 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
break;
case ZFS_PROP_ORIGIN:
- str = getprop_string(zhp, prop, &source);
+ if (*zhp->zfs_dmustats.dds_origin != '\0') {
+ str = (char *)&zhp->zfs_dmustats.dds_origin;
+ } else {
+ str = getprop_string(zhp, prop, &source);
+ }
+ if (str == NULL || *str == '\0')
+ str = zfs_prop_default_string(prop);
if (str == NULL)
return (-1);
(void) strlcpy(propbuf, str, proplen);
@@ -2921,6 +3001,26 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
zcp_check(zhp, prop, val, NULL);
break;
+ case ZFS_PROP_SNAPSHOTS_CHANGED:
+ {
+ if ((get_numeric_property(zhp, prop, src, &source,
+ &val) != 0) || val == 0) {
+ return (-1);
+ }
+
+ time_t time = (time_t)val;
+ struct tm t;
+
+ if (literal ||
+ localtime_r(&time, &t) == NULL ||
+ strftime(propbuf, proplen, "%a %b %e %k:%M:%S %Y",
+ &t) == 0)
+ (void) snprintf(propbuf, proplen, "%llu",
+ (u_longlong_t)val);
+ }
+ zcp_check(zhp, prop, val, NULL);
+ break;
+
default:
switch (zfs_prop_get_type(prop)) {
case PROP_TYPE_NUMBER:
@@ -2976,7 +3076,7 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
uint64_t
zfs_prop_get_int(zfs_handle_t *zhp, zfs_prop_t prop)
{
- char *source;
+ const char *source;
uint64_t val = 0;
(void) get_numeric_property(zhp, prop, NULL, &source, &val);
@@ -3000,7 +3100,7 @@ int
zfs_prop_get_numeric(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t *value,
zprop_source_t *src, char *statbuf, size_t statlen)
{
- char *source;
+ const char *source;
/*
* Check to see if this property applies to our object
@@ -3099,11 +3199,15 @@ userquota_propname_decode(const char *propname, boolean_t zoned,
cp = strchr(propname, '@') + 1;
- if (isuser && (pw = getpwnam(cp)) != NULL) {
+ if (isuser &&
+ getpwnam_r(cp, &gpwd, rpbuf, sizeof (rpbuf), &pw) == 0 &&
+ pw != NULL) {
if (zoned && getzoneid() == GLOBAL_ZONEID)
return (ENOENT);
*ridp = pw->pw_uid;
- } else if (isgroup && (gr = getgrnam(cp)) != NULL) {
+ } else if (isgroup &&
+ getgrnam_r(cp, &ggrp, rpbuf, sizeof (rpbuf), &gr) == 0 &&
+ gr != NULL) {
if (zoned && getzoneid() == GLOBAL_ZONEID)
return (ENOENT);
*ridp = gr->gr_gid;
@@ -3419,8 +3523,8 @@ check_parents(libzfs_handle_t *hdl, const char *path, uint64_t *zoned,
/* check to see if the pool exists */
if ((slash = strchr(parent, '/')) == NULL)
slash = parent + strlen(parent);
- (void) strncpy(zc.zc_name, parent, slash - parent);
- zc.zc_name[slash - parent] = '\0';
+ (void) strlcpy(zc.zc_name, parent,
+ MIN(sizeof (zc.zc_name), slash - parent + 1));
if (zfs_ioctl(hdl, ZFS_IOC_OBJSET_STATS, &zc) != 0 &&
errno == ENOENT) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
@@ -3848,7 +3952,7 @@ zfs_check_snap_cb(zfs_handle_t *zhp, void *arg)
if (lzc_exists(name))
fnvlist_add_boolean(dd->nvl, name);
- rv = zfs_iter_filesystems(zhp, zfs_check_snap_cb, dd);
+ rv = zfs_iter_filesystems_v2(zhp, 0, zfs_check_snap_cb, dd);
zfs_close(zhp);
return (rv);
}
@@ -4086,7 +4190,7 @@ zfs_snapshot_cb(zfs_handle_t *zhp, void *arg)
fnvlist_add_boolean(sd->sd_nvl, name);
- rv = zfs_iter_filesystems(zhp, zfs_snapshot_cb, sd);
+ rv = zfs_iter_filesystems_v2(zhp, 0, zfs_snapshot_cb, sd);
}
zfs_close(zhp);
@@ -4129,6 +4233,8 @@ zfs_snapshot_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, nvlist_t *props)
* same pool, as does lzc_snapshot (below).
*/
elem = nvlist_next_nvpair(snaps, NULL);
+ if (elem == NULL)
+ return (-1);
(void) strlcpy(pool, nvpair_name(elem), sizeof (pool));
pool[strcspn(pool, "/@")] = '\0';
zpool_hdl = zpool_open(hdl, pool);
@@ -4261,7 +4367,7 @@ rollback_destroy(zfs_handle_t *zhp, void *data)
rollback_data_t *cbp = data;
if (zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) > cbp->cb_create) {
- cbp->cb_error |= zfs_iter_dependents(zhp, B_FALSE,
+ cbp->cb_error |= zfs_iter_dependents_v2(zhp, 0, B_FALSE,
rollback_destroy_dependent, cbp);
cbp->cb_error |= zfs_destroy(zhp, B_FALSE);
@@ -4301,10 +4407,10 @@ zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap, boolean_t force)
if (cb.cb_create > 0)
min_txg = cb.cb_create;
- (void) zfs_iter_snapshots(zhp, B_FALSE, rollback_destroy, &cb,
+ (void) zfs_iter_snapshots_v2(zhp, 0, rollback_destroy, &cb,
min_txg, 0);
- (void) zfs_iter_bookmarks(zhp, rollback_destroy, &cb);
+ (void) zfs_iter_bookmarks_v2(zhp, 0, rollback_destroy, &cb);
if (cb.cb_error)
return (-1);
@@ -4619,7 +4725,7 @@ zfs_expand_proplist(zfs_handle_t *zhp, zprop_list_t **plp, boolean_t received,
zprop_list_t **last, **start;
nvlist_t *userprops, *propval;
nvpair_t *elem;
- char *strval;
+ const char *strval;
char buf[ZFS_MAXPROPLEN];
if (zprop_expand_list(hdl, plp, ZFS_TYPE_DATASET) != 0)
@@ -4885,7 +4991,7 @@ zfs_hold_one(zfs_handle_t *zhp, void *arg)
fnvlist_add_string(ha->nvl, name, ha->tag);
if (ha->recursive)
- rv = zfs_iter_filesystems(zhp, zfs_hold_one, ha);
+ rv = zfs_iter_filesystems_v2(zhp, 0, zfs_hold_one, ha);
zfs_close(zhp);
return (rv);
}
@@ -5016,7 +5122,7 @@ zfs_release_one(zfs_handle_t *zhp, void *arg)
}
if (ha->recursive)
- rv = zfs_iter_filesystems(zhp, zfs_release_one, ha);
+ rv = zfs_iter_filesystems_v2(zhp, 0, zfs_release_one, ha);
zfs_close(zhp);
return (rv);
}
@@ -5119,7 +5225,7 @@ tryagain:
nvbuf = malloc(nvsz);
if (nvbuf == NULL) {
- err = (zfs_error(hdl, EZFS_NOMEM, strerror(errno)));
+ err = (zfs_error(hdl, EZFS_NOMEM, zfs_strerror(errno)));
goto out;
}
@@ -5405,7 +5511,7 @@ volsize_from_vdevs(zpool_handle_t *zhp, uint64_t nblocks, uint64_t blksize)
}
for (int v = 0; v < nvdevs; v++) {
- char *type;
+ const char *type;
uint64_t nparity, ashift, asize, tsize;
uint64_t volsize;
@@ -5459,8 +5565,21 @@ volsize_from_vdevs(zpool_handle_t *zhp, uint64_t nblocks, uint64_t blksize)
/*
* Scale this size down as a ratio of 128k / tsize.
* See theory statement above.
+ *
+ * Bitshift is to avoid the case of nblocks * asize < tsize
+ * producing a size of 0.
+ */
+ volsize = (nblocks * asize) / (tsize >> SPA_MINBLOCKSHIFT);
+ /*
+ * If we would blow UINT64_MAX with this next multiplication,
+ * don't.
*/
- volsize = nblocks * asize * SPA_OLD_MAXBLOCKSIZE / tsize;
+ if (volsize >
+ (UINT64_MAX / (SPA_OLD_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT)))
+ volsize = UINT64_MAX;
+ else
+ volsize *= (SPA_OLD_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT);
+
if (volsize > ret) {
ret = volsize;
}
@@ -5487,7 +5606,7 @@ zvol_volsize_to_reservation(zpool_handle_t *zph, uint64_t volsize,
uint64_t numdb;
uint64_t nblocks, volblocksize;
int ncopies;
- char *strval;
+ const char *strval;
if (nvlist_lookup_string(props,
zfs_prop_to_name(ZFS_PROP_COPIES), &strval) == 0)