diff options
author | Don Brady <[email protected]> | 2018-09-05 19:33:36 -0600 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2018-09-05 18:33:36 -0700 |
commit | cc99f275a28c43fe450a66a7544f73c4935f7361 (patch) | |
tree | f867e1d2cbb550a047c0f87986831252c41a2fd9 /lib | |
parent | cfa37548ebc880580782b245f2d233ed540e7a01 (diff) |
Pool allocation classes
Allocation Classes add the ability to have allocation classes in a
pool that are dedicated to serving specific block categories, such
as DDT data, metadata, and small file blocks. A pool can opt-in to
this feature by adding a 'special' or 'dedup' top-level VDEV.
Reviewed by: Pavel Zakharov <[email protected]>
Reviewed-by: Richard Laager <[email protected]>
Reviewed-by: Alek Pinchuk <[email protected]>
Reviewed-by: HÃ¥kan Johansson <[email protected]>
Reviewed-by: Andreas Dilger <[email protected]>
Reviewed-by: DHE <[email protected]>
Reviewed-by: Richard Elling <[email protected]>
Reviewed-by: Gregor Kopka <[email protected]>
Reviewed-by: Kash Pande <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Reviewed-by: Matthew Ahrens <[email protected]>
Signed-off-by: Don Brady <[email protected]>
Closes #5182
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libzfs/libzfs_dataset.c | 30 | ||||
-rw-r--r-- | lib/libzfs/libzfs_pool.c | 37 | ||||
-rw-r--r-- | lib/libzpool/util.c | 23 |
3 files changed, 83 insertions, 7 deletions
diff --git a/lib/libzfs/libzfs_dataset.c b/lib/libzfs/libzfs_dataset.c index 85b4c5531..76a316a9c 100644 --- a/lib/libzfs/libzfs_dataset.c +++ b/lib/libzfs/libzfs_dataset.c @@ -1195,6 +1195,36 @@ zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl, } break; } + + case ZFS_PROP_SPECIAL_SMALL_BLOCKS: + if (zpool_hdl != NULL) { + char state[64] = ""; + + /* + * Issue a warning but do not fail so that + * tests for setable properties succeed. + */ + if (zpool_prop_get_feature(zpool_hdl, + "feature@allocation_classes", state, + sizeof (state)) != 0 || + strcmp(state, ZFS_FEATURE_ACTIVE) != 0) { + (void) fprintf(stderr, gettext( + "%s: property requires a special " + "device in the pool\n"), propname); + } + } + if (intval != 0 && + (intval < SPA_MINBLOCKSIZE || + intval > SPA_OLD_MAXBLOCKSIZE || !ISP2(intval))) { + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "invalid '%s=%d' property: must be zero or " + "a power of 2 from 512B to 128K"), propname, + intval); + (void) zfs_error(hdl, EZFS_BADPROP, errbuf); + goto error; + } + break; + case ZFS_PROP_MLSLABEL: { #ifdef HAVE_MLSLABEL diff --git a/lib/libzfs/libzfs_pool.c b/lib/libzfs/libzfs_pool.c index 0785c3170..fca1a4178 100644 --- a/lib/libzfs/libzfs_pool.c +++ b/lib/libzfs/libzfs_pool.c @@ -26,6 +26,7 @@ * Copyright 2016 Igor Kozhukhov <[email protected]> * Copyright (c) 2018 Datto Inc. * Copyright (c) 2017 Open-E, Inc. All Rights Reserved. + * Copyright (c) 2017, Intel Corporation. */ #include <ctype.h> @@ -720,6 +721,7 @@ zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname, goto error; } break; + default: zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "property '%s'(%d) not defined"), propname, prop); @@ -1173,6 +1175,30 @@ zpool_get_state(zpool_handle_t *zhp) } /* + * Check if vdev list contains a special vdev + */ +static boolean_t +zpool_has_special_vdev(nvlist_t *nvroot) +{ + nvlist_t **child; + uint_t children; + + if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, &child, + &children) == 0) { + for (uint_t c = 0; c < children; c++) { + char *bias; + + if (nvlist_lookup_string(child[c], + ZPOOL_CONFIG_ALLOCATION_BIAS, &bias) == 0 && + strcmp(bias, VDEV_ALLOC_BIAS_SPECIAL) == 0) { + return (B_TRUE); + } + } + } + return (B_FALSE); +} + +/* * Create the named pool, using the provided vdev list. It is assumed * that the consumer has already validated the contents of the nvlist, so we * don't have to worry about error semantics. @@ -1220,6 +1246,17 @@ zpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot, fsprops, zoned, NULL, NULL, B_TRUE, msg)) == NULL) { goto create_failed; } + + if (nvlist_exists(zc_fsprops, + zfs_prop_to_name(ZFS_PROP_SPECIAL_SMALL_BLOCKS)) && + !zpool_has_special_vdev(nvroot)) { + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "%s property requires a special vdev"), + zfs_prop_to_name(ZFS_PROP_SPECIAL_SMALL_BLOCKS)); + (void) zfs_error(hdl, EZFS_BADPROP, msg); + goto create_failed; + } + if (!zc_props && (nvlist_alloc(&zc_props, NV_UNIQUE_NAME, 0) != 0)) { goto create_failed; diff --git a/lib/libzpool/util.c b/lib/libzpool/util.c index bb1710e79..8a6f4c325 100644 --- a/lib/libzpool/util.c +++ b/lib/libzpool/util.c @@ -22,6 +22,7 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016 by Delphix. All rights reserved. * Copyright 2017 Jason King + * Copyright (c) 2017, Intel Corporation. */ #include <assert.h> @@ -150,7 +151,6 @@ show_vdev_stats(const char *desc, const char *ctype, nvlist_t *nv, int indent) uint_t c, children; char used[6], avail[6]; char rops[6], wops[6], rbytes[6], wbytes[6], rerr[6], werr[6], cerr[6]; - char *prefix = ""; v0 = umem_zalloc(sizeof (*v0), UMEM_NOFAIL); @@ -162,15 +162,24 @@ show_vdev_stats(const char *desc, const char *ctype, nvlist_t *nv, int indent) } if (desc != NULL) { - (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_LOG, &is_log); - - if (is_log) - prefix = "log "; + char *suffix = "", *bias = NULL; + char bias_suffix[32]; + (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_LOG, &is_log); + (void) nvlist_lookup_string(nv, ZPOOL_CONFIG_ALLOCATION_BIAS, + &bias); if (nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&vs, &c) != 0) vs = v0; + if (bias != NULL) { + (void) snprintf(bias_suffix, sizeof (bias_suffix), + " (%s)", bias); + suffix = bias_suffix; + } else if (is_log) { + suffix = " (log)"; + } + sec = MAX(1, vs->vs_timestamp / NANOSEC); nicenum(vs->vs_alloc, used, sizeof (used)); @@ -187,9 +196,9 @@ show_vdev_stats(const char *desc, const char *ctype, nvlist_t *nv, int indent) (void) printf("%*s%s%*s%*s%*s %5s %5s %5s %5s %5s %5s %5s\n", indent, "", - prefix, - (int)(indent+strlen(prefix)-25-(vs->vs_space ? 0 : 12)), desc, + (int)(indent+strlen(desc)-25-(vs->vs_space ? 0 : 12)), + suffix, vs->vs_space ? 6 : 0, vs->vs_space ? used : "", vs->vs_space ? 6 : 0, vs->vs_space ? avail : "", rops, wops, rbytes, wbytes, rerr, werr, cerr); |