aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd/zfs/zfs_iter.c4
-rw-r--r--cmd/zfs/zfs_main.c6
-rw-r--r--include/sys/fs/zfs.h2
-rw-r--r--include/zfs_prop.h2
-rw-r--r--lib/libzfs/libzfs_dataset.c19
-rw-r--r--lib/libzfs/libzfs_mount.c3
-rw-r--r--lib/libzfs/libzfs_util.c2
-rw-r--r--module/zcommon/zfs_prop.c6
-rw-r--r--module/zcommon/zprop_common.c8
-rw-r--r--module/zfs/dsl_prop.c2
10 files changed, 34 insertions, 20 deletions
diff --git a/cmd/zfs/zfs_iter.c b/cmd/zfs/zfs_iter.c
index 8892d91f2..eb1d9a54e 100644
--- a/cmd/zfs/zfs_iter.c
+++ b/cmd/zfs/zfs_iter.c
@@ -328,9 +328,9 @@ zfs_sort(const void *larg, const void *rarg, void *data)
rstr = rbuf;
} else {
lvalid = zfs_prop_valid_for_type(psc->sc_prop,
- zfs_get_type(l));
+ zfs_get_type(l), B_FALSE);
rvalid = zfs_prop_valid_for_type(psc->sc_prop,
- zfs_get_type(r));
+ zfs_get_type(r), B_FALSE);
if (lvalid)
(void) zfs_prop_get_numeric(l, psc->sc_prop,
diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c
index d7c1a2a47..7faab4734 100644
--- a/cmd/zfs/zfs_main.c
+++ b/cmd/zfs/zfs_main.c
@@ -846,7 +846,7 @@ zfs_do_create(int argc, char **argv)
* if the user doesn't want the dataset automatically mounted,
* then skip the mount/share step
*/
- if (zfs_prop_valid_for_type(ZFS_PROP_CANMOUNT, type))
+ if (zfs_prop_valid_for_type(ZFS_PROP_CANMOUNT, type, B_FALSE))
canmount = zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT);
/*
@@ -1429,7 +1429,7 @@ get_callback(zfs_handle_t *zhp, void *data)
if (pl->pl_all)
continue;
if (!zfs_prop_valid_for_type(pl->pl_prop,
- ZFS_TYPE_DATASET)) {
+ ZFS_TYPE_DATASET, B_FALSE)) {
(void) fprintf(stderr,
gettext("No such property '%s'\n"),
zfs_prop_to_name(pl->pl_prop));
@@ -1763,7 +1763,7 @@ inherit_recurse_cb(zfs_handle_t *zhp, void *data)
* are not valid for this type of dataset.
*/
if (prop != ZPROP_INVAL &&
- !zfs_prop_valid_for_type(prop, zfs_get_type(zhp)))
+ !zfs_prop_valid_for_type(prop, zfs_get_type(zhp), B_FALSE))
return (0);
return (zfs_prop_inherit(zhp, cb->cb_propname, cb->cb_received) != 0);
diff --git a/include/sys/fs/zfs.h b/include/sys/fs/zfs.h
index ae72f834d..7b3ae6cff 100644
--- a/include/sys/fs/zfs.h
+++ b/include/sys/fs/zfs.h
@@ -255,7 +255,7 @@ boolean_t zfs_prop_written(const char *);
int zfs_prop_index_to_string(zfs_prop_t, uint64_t, const char **);
int zfs_prop_string_to_index(zfs_prop_t, const char *, uint64_t *);
uint64_t zfs_prop_random_value(zfs_prop_t, uint64_t seed);
-boolean_t zfs_prop_valid_for_type(int, zfs_type_t);
+boolean_t zfs_prop_valid_for_type(int, zfs_type_t, boolean_t);
/*
* Pool property functions shared between libzfs and kernel.
diff --git a/include/zfs_prop.h b/include/zfs_prop.h
index a63262311..5e7d3f55a 100644
--- a/include/zfs_prop.h
+++ b/include/zfs_prop.h
@@ -120,7 +120,7 @@ int zprop_index_to_string(int, uint64_t, const char **, zfs_type_t);
uint64_t zprop_random_value(int, uint64_t, zfs_type_t);
const char *zprop_values(int, zfs_type_t);
size_t zprop_width(int, boolean_t *, zfs_type_t);
-boolean_t zprop_valid_for_type(int, zfs_type_t);
+boolean_t zprop_valid_for_type(int, zfs_type_t, boolean_t);
#ifdef __cplusplus
}
diff --git a/lib/libzfs/libzfs_dataset.c b/lib/libzfs/libzfs_dataset.c
index 316927c0a..5e43aab2b 100644
--- a/lib/libzfs/libzfs_dataset.c
+++ b/lib/libzfs/libzfs_dataset.c
@@ -948,7 +948,7 @@ zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl,
goto error;
}
- if (!zfs_prop_valid_for_type(prop, type)) {
+ if (!zfs_prop_valid_for_type(prop, type, B_FALSE)) {
zfs_error_aux(hdl,
dgettext(TEXT_DOMAIN, "'%s' does not "
"apply to datasets of this type"), propname);
@@ -1610,7 +1610,7 @@ zfs_prop_inherit(zfs_handle_t *zhp, const char *propname, boolean_t received)
/*
* Check to see if the value applies to this type
*/
- if (!zfs_prop_valid_for_type(prop, zhp->zfs_type))
+ if (!zfs_prop_valid_for_type(prop, zhp->zfs_type, B_FALSE))
return (zfs_error(hdl, EZFS_PROPTYPE, errbuf));
/*
@@ -1760,6 +1760,14 @@ get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src,
*source = NULL;
+ /*
+ * If the property is being fetched for a snapshot, check whether
+ * the property is valid for the snapshot's head dataset type.
+ */
+ if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT &&
+ !zfs_prop_valid_for_type(prop, zhp->zfs_head_type, B_TRUE))
+ return (-1);
+
switch (prop) {
case ZFS_PROP_ATIME:
mntopt_on = MNTOPT_ATIME;
@@ -1880,8 +1888,7 @@ get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src,
case ZFS_PROP_NORMALIZE:
case ZFS_PROP_UTF8ONLY:
case ZFS_PROP_CASE:
- if (!zfs_prop_valid_for_type(prop, zhp->zfs_head_type) ||
- zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0) != 0)
+ if (zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0) != 0)
return (-1);
(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_OBJSET_ZPLPROPS, &zc)) {
@@ -2124,7 +2131,7 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
/*
* Check to see if this property applies to our object
*/
- if (!zfs_prop_valid_for_type(prop, zhp->zfs_type))
+ if (!zfs_prop_valid_for_type(prop, zhp->zfs_type, B_FALSE))
return (-1);
if (received && zfs_prop_readonly(prop))
@@ -2445,7 +2452,7 @@ zfs_prop_get_numeric(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t *value,
/*
* Check to see if this property applies to our object
*/
- if (!zfs_prop_valid_for_type(prop, zhp->zfs_type)) {
+ if (!zfs_prop_valid_for_type(prop, zhp->zfs_type, B_FALSE)) {
return (zfs_error_fmt(zhp->zfs_hdl, EZFS_PROPTYPE,
dgettext(TEXT_DOMAIN, "cannot get property '%s'"),
zfs_prop_to_name(prop)));
diff --git a/lib/libzfs/libzfs_mount.c b/lib/libzfs/libzfs_mount.c
index 83396c402..ac3b68226 100644
--- a/lib/libzfs/libzfs_mount.c
+++ b/lib/libzfs/libzfs_mount.c
@@ -231,7 +231,8 @@ zfs_is_mountable(zfs_handle_t *zhp, char *buf, size_t buflen,
char sourceloc[ZFS_MAXNAMELEN];
zprop_source_t sourcetype;
- if (!zfs_prop_valid_for_type(ZFS_PROP_MOUNTPOINT, zhp->zfs_type))
+ if (!zfs_prop_valid_for_type(ZFS_PROP_MOUNTPOINT, zhp->zfs_type,
+ B_FALSE))
return (B_FALSE);
verify(zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, buf, buflen,
diff --git a/lib/libzfs/libzfs_util.c b/lib/libzfs/libzfs_util.c
index e99603b49..d029b61e7 100644
--- a/lib/libzfs/libzfs_util.c
+++ b/lib/libzfs/libzfs_util.c
@@ -1531,7 +1531,7 @@ addlist(libzfs_handle_t *hdl, char *propname, zprop_list_t **listp,
prop = zprop_name_to_prop(propname, type);
- if (prop != ZPROP_INVAL && !zprop_valid_for_type(prop, type))
+ if (prop != ZPROP_INVAL && !zprop_valid_for_type(prop, type, B_FALSE))
prop = ZPROP_INVAL;
/*
diff --git a/module/zcommon/zfs_prop.c b/module/zcommon/zfs_prop.c
index dd456b59a..d81ff3bc6 100644
--- a/module/zcommon/zfs_prop.c
+++ b/module/zcommon/zfs_prop.c
@@ -391,7 +391,7 @@ zfs_prop_init(void)
PROP_DEFAULT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
"<size> | none", "RESERV");
zprop_register_number(ZFS_PROP_VOLSIZE, "volsize", 0, PROP_DEFAULT,
- ZFS_TYPE_VOLUME, "<size>", "VOLSIZE");
+ ZFS_TYPE_SNAPSHOT | ZFS_TYPE_VOLUME, "<size>", "VOLSIZE");
zprop_register_number(ZFS_PROP_REFQUOTA, "refquota", 0, PROP_DEFAULT,
ZFS_TYPE_FILESYSTEM, "<size> | none", "REFQUOTA");
zprop_register_number(ZFS_PROP_REFRESERVATION, "refreservation", 0,
@@ -555,9 +555,9 @@ zfs_prop_random_value(zfs_prop_t prop, uint64_t seed)
* Returns TRUE if the property applies to any of the given dataset types.
*/
boolean_t
-zfs_prop_valid_for_type(int prop, zfs_type_t types)
+zfs_prop_valid_for_type(int prop, zfs_type_t types, boolean_t headcheck)
{
- return (zprop_valid_for_type(prop, types));
+ return (zprop_valid_for_type(prop, types, headcheck));
}
zprop_type_t
diff --git a/module/zcommon/zprop_common.c b/module/zcommon/zprop_common.c
index 6d9f89a98..035f3378d 100644
--- a/module/zcommon/zprop_common.c
+++ b/module/zcommon/zprop_common.c
@@ -351,9 +351,13 @@ zprop_values(int prop, zfs_type_t type)
/*
* Returns TRUE if the property applies to any of the given dataset types.
+ *
+ * If headcheck is set, the check is being made against the head dataset
+ * type of a snapshot which requires to return B_TRUE when the property
+ * is only valid for snapshots.
*/
boolean_t
-zprop_valid_for_type(int prop, zfs_type_t type)
+zprop_valid_for_type(int prop, zfs_type_t type, boolean_t headcheck)
{
zprop_desc_t *prop_tbl;
@@ -362,6 +366,8 @@ zprop_valid_for_type(int prop, zfs_type_t type)
ASSERT(prop < zprop_get_numprops(type));
prop_tbl = zprop_get_proptable(type);
+ if (headcheck && prop_tbl[prop].pd_types == ZFS_TYPE_SNAPSHOT)
+ return (B_TRUE);
return ((prop_tbl[prop].pd_types & type) != 0);
}
diff --git a/module/zfs/dsl_prop.c b/module/zfs/dsl_prop.c
index 079ef9742..ded0da991 100644
--- a/module/zfs/dsl_prop.c
+++ b/module/zfs/dsl_prop.c
@@ -925,7 +925,7 @@ dsl_prop_get_all_impl(objset_t *mos, uint64_t propobj,
/* Skip properties not valid for this type. */
if ((flags & DSL_PROP_GET_SNAPSHOT) && prop != ZPROP_INVAL &&
- !zfs_prop_valid_for_type(prop, ZFS_TYPE_SNAPSHOT))
+ !zfs_prop_valid_for_type(prop, ZFS_TYPE_SNAPSHOT, B_FALSE))
continue;
/* Skip properties already defined. */