summaryrefslogtreecommitdiffstats
path: root/lib/libzfs
diff options
context:
space:
mode:
authorJoe Stein <[email protected]>2016-01-13 15:05:59 -0800
committerBrian Behlendorf <[email protected]>2016-01-15 15:38:35 -0800
commit82f6f6e654a51b47f9f2d642197852ced80487ee (patch)
tree638b0d3abd9318a50622c9d033d4a6ef17053b07 /lib/libzfs
parent59d4c71cca3bd6a1f122129ebb001089f903f182 (diff)
Illumos 6298 - zfs_create_008_neg and zpool_create_023_neg
6298 zfs_create_008_neg and zpool_create_023_neg need to be updated for large block support Reviewed by: Matthew Ahrens <[email protected]> Reviewed by: John Kennedy <[email protected]> Approved by: Robert Mustacchi <[email protected]> References: https://www.illumos.org/issues/6298 https://github.com/illumos/illumos-gate/commit/e9316f7 Ported-by: Brian Behlendorf <[email protected]> Closes #4217
Diffstat (limited to 'lib/libzfs')
-rw-r--r--lib/libzfs/libzfs_dataset.c54
-rw-r--r--lib/libzfs/libzfs_pool.c19
2 files changed, 53 insertions, 20 deletions
diff --git a/lib/libzfs/libzfs_dataset.c b/lib/libzfs/libzfs_dataset.c
index 7bcfd6a81..7518a3bca 100644
--- a/lib/libzfs/libzfs_dataset.c
+++ b/lib/libzfs/libzfs_dataset.c
@@ -22,7 +22,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
- * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
* Copyright (c) 2012 DEY Storage Systems, Inc. All rights reserved.
* Copyright (c) 2012 Pawel Jakub Dawidek <[email protected]>.
* Copyright (c) 2013 Martin Matuska. All rights reserved.
@@ -865,7 +865,8 @@ zfs_which_resv_prop(zfs_handle_t *zhp, zfs_prop_t *resv_prop)
*/
nvlist_t *
zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl,
- uint64_t zoned, zfs_handle_t *zhp, const char *errbuf)
+ uint64_t zoned, zfs_handle_t *zhp, zpool_handle_t *zpool_hdl,
+ const char *errbuf)
{
nvpair_t *elem;
uint64_t intval;
@@ -1061,8 +1062,8 @@ zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl,
int maxbs = SPA_MAXBLOCKSIZE;
char buf[64];
- if (zhp != NULL) {
- maxbs = zpool_get_prop_int(zhp->zpool_hdl,
+ if (zpool_hdl != NULL) {
+ maxbs = zpool_get_prop_int(zpool_hdl,
ZPOOL_PROP_MAXBLOCKSIZE, NULL);
}
/*
@@ -1581,7 +1582,8 @@ zfs_prop_set_list(zfs_handle_t *zhp, nvlist_t *props)
zhp->zfs_name);
if ((nvl = zfs_valid_proplist(hdl, zhp->zfs_type, props,
- zfs_prop_get_int(zhp, ZFS_PROP_ZONED), zhp, errbuf)) == NULL)
+ zfs_prop_get_int(zhp, ZFS_PROP_ZONED), zhp, zhp->zpool_hdl,
+ errbuf)) == NULL)
goto error;
/*
@@ -3241,9 +3243,23 @@ zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
else
ost = DMU_OST_ZFS;
+ /* open zpool handle for prop validation */
+ char pool_path[MAXNAMELEN];
+ (void) strlcpy(pool_path, path, sizeof (pool_path));
+
+ /* truncate pool_path at first slash */
+ char *p = strchr(pool_path, '/');
+ if (p != NULL)
+ *p = '\0';
+
+ zpool_handle_t *zpool_handle = zpool_open(hdl, pool_path);
+
if (props && (props = zfs_valid_proplist(hdl, type, props,
- zoned, NULL, errbuf)) == 0)
+ zoned, NULL, zpool_handle, errbuf)) == 0) {
+ zpool_close(zpool_handle);
return (-1);
+ }
+ zpool_close(zpool_handle);
if (type == ZFS_TYPE_VOLUME) {
/*
@@ -3298,8 +3314,6 @@ zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
/* check for failure */
if (ret != 0) {
char parent[ZFS_MAXNAMELEN];
- char buf[64];
-
(void) parent_name(path, parent, sizeof (parent));
switch (errno) {
@@ -3313,14 +3327,6 @@ zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
"parent '%s' is not a filesystem"), parent);
return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
- case EDOM:
- zfs_nicenum(SPA_MAXBLOCKSIZE, buf, sizeof (buf));
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "volume block size must be power of 2 from "
- "512B to %s"), buf);
-
- return (zfs_error(hdl, EZFS_BADPROP, errbuf));
-
case ENOTSUP:
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"pool must be upgraded to set this "
@@ -3516,7 +3522,7 @@ zfs_clone(zfs_handle_t *zhp, const char *target, nvlist_t *props)
type = ZFS_TYPE_FILESYSTEM;
}
if ((props = zfs_valid_proplist(hdl, type, props, zoned,
- zhp, errbuf)) == NULL)
+ zhp, zhp->zpool_hdl, errbuf)) == NULL)
return (-1);
}
@@ -3660,11 +3666,23 @@ zfs_snapshot_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, nvlist_t *props)
}
}
+ /*
+ * get pool handle for prop validation. assumes all snaps are in the
+ * same pool, as does lzc_snapshot (below).
+ */
+ char pool[MAXNAMELEN];
+ elem = nvlist_next_nvpair(snaps, NULL);
+ (void) strlcpy(pool, nvpair_name(elem), sizeof (pool));
+ pool[strcspn(pool, "/@")] = '\0';
+ zpool_handle_t *zpool_hdl = zpool_open(hdl, pool);
+
if (props != NULL &&
(props = zfs_valid_proplist(hdl, ZFS_TYPE_SNAPSHOT,
- props, B_FALSE, NULL, errbuf)) == NULL) {
+ props, B_FALSE, NULL, zpool_hdl, errbuf)) == NULL) {
+ zpool_close(zpool_hdl);
return (-1);
}
+ zpool_close(zpool_hdl);
ret = lzc_snapshot(snaps, props, &errors);
diff --git a/lib/libzfs/libzfs_pool.c b/lib/libzfs/libzfs_pool.c
index 60213a638..e603526f4 100644
--- a/lib/libzfs/libzfs_pool.c
+++ b/lib/libzfs/libzfs_pool.c
@@ -1215,8 +1215,8 @@ zpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot,
zfs_prop_to_name(ZFS_PROP_ZONED), &zonestr) == 0) &&
strcmp(zonestr, "on") == 0);
- if ((zc_fsprops = zfs_valid_proplist(hdl,
- ZFS_TYPE_FILESYSTEM, fsprops, zoned, NULL, msg)) == NULL) {
+ if ((zc_fsprops = zfs_valid_proplist(hdl, ZFS_TYPE_FILESYSTEM,
+ fsprops, zoned, NULL, NULL, msg)) == NULL) {
goto create_failed;
}
if (!zc_props &&
@@ -1255,6 +1255,21 @@ zpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot,
"lvm device"));
return (zfs_error(hdl, EZFS_BADDEV, msg));
+ case ERANGE:
+ /*
+ * This happens if the record size is smaller or larger
+ * than the allowed size range, or not a power of 2.
+ *
+ * NOTE: although zfs_valid_proplist is called earlier,
+ * this case may have slipped through since the
+ * pool does not exist yet and it is therefore
+ * impossible to read properties e.g. max blocksize
+ * from the pool.
+ */
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "record size invalid"));
+ return (zfs_error(hdl, EZFS_BADPROP, msg));
+
case EOVERFLOW:
/*
* This occurs when one of the devices is below