mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 02:27:36 +03:00
2619 asynchronous destruction of ZFS file systems 2747 SPA versioning with zfs feature flags Reviewed by: Matt Ahrens <mahrens@delphix.com> Reviewed by: George Wilson <gwilson@delphix.com> Reviewed by: Richard Lowe <richlowe@richlowe.net> Reviewed by: Dan Kruchinin <dan.kruchinin@gmail.com> Approved by: Eric Schrock <Eric.Schrock@delphix.com> References: illumos/illumos-gate@53089ab7c8 illumos/illumos-gate@ad135b5d64 illumos changeset: 13700:2889e2596bd6 https://www.illumos.org/issues/2619 https://www.illumos.org/issues/2747 NOTE: The grub specific changes were not ported. This change must be made to the Linux grub packages. Ported-by: Brian Behlendorf <behlendorf1@llnl.gov>
This commit is contained in:
committed by
Brian Behlendorf
parent
15313c5e18
commit
9ae529ec5d
@@ -12,7 +12,8 @@ libnvpair_la_SOURCES = \
|
||||
$(top_srcdir)/lib/libnvpair/libnvpair.c \
|
||||
$(top_srcdir)/lib/libnvpair/nvpair_alloc_system.c \
|
||||
$(top_srcdir)/module/nvpair/nvpair_alloc_fixed.c \
|
||||
$(top_srcdir)/module/nvpair/nvpair.c
|
||||
$(top_srcdir)/module/nvpair/nvpair.c \
|
||||
$(top_srcdir)/module/nvpair/fnvpair.c
|
||||
|
||||
libnvpair_la_LIBADD = \
|
||||
$(top_builddir)/lib/libuutil/libuutil.la
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
@@ -803,6 +804,10 @@ dump_nvlist(nvlist_t *list, int indent)
|
||||
|
||||
while ((elem = nvlist_next_nvpair(list, elem)) != NULL) {
|
||||
switch (nvpair_type(elem)) {
|
||||
case DATA_TYPE_BOOLEAN:
|
||||
(void) printf("%*s%s\n", indent, "", nvpair_name(elem));
|
||||
break;
|
||||
|
||||
case DATA_TYPE_BOOLEAN_VALUE:
|
||||
(void) nvpair_value_boolean_value(elem, &bool_value);
|
||||
(void) printf("%*s%s: %s\n", indent, "",
|
||||
|
||||
@@ -18,11 +18,16 @@
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The pool configuration repository is stored in /etc/zfs/zpool.cache as a
|
||||
* single packed nvlist. While it would be nice to just read in this
|
||||
@@ -217,6 +222,36 @@ zpool_get_config(zpool_handle_t *zhp, nvlist_t **oldconfig)
|
||||
return (zhp->zpool_config);
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieves a list of enabled features and their refcounts and caches it in
|
||||
* the pool handle.
|
||||
*/
|
||||
nvlist_t *
|
||||
zpool_get_features(zpool_handle_t *zhp)
|
||||
{
|
||||
nvlist_t *config, *features;
|
||||
|
||||
config = zpool_get_config(zhp, NULL);
|
||||
|
||||
if (config == NULL || !nvlist_exists(config,
|
||||
ZPOOL_CONFIG_FEATURE_STATS)) {
|
||||
int error;
|
||||
boolean_t missing = B_FALSE;
|
||||
|
||||
error = zpool_refresh_stats(zhp, &missing);
|
||||
|
||||
if (error != 0 || missing)
|
||||
return (NULL);
|
||||
|
||||
config = zpool_get_config(zhp, NULL);
|
||||
}
|
||||
|
||||
verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_FEATURE_STATS,
|
||||
&features) == 0);
|
||||
|
||||
return (features);
|
||||
}
|
||||
|
||||
/*
|
||||
* Refresh the vdev statistics associated with the given pool. This is used in
|
||||
* iostat to show configuration changes and determine the delta from the last
|
||||
|
||||
+223
-3
@@ -45,6 +45,7 @@
|
||||
#include "zfs_prop.h"
|
||||
#include "libzfs_impl.h"
|
||||
#include "zfs_comutil.h"
|
||||
#include "zfeature_common.h"
|
||||
|
||||
static int read_efi_label(nvlist_t *config, diskaddr_t *sb);
|
||||
|
||||
@@ -273,6 +274,7 @@ zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, size_t len,
|
||||
case ZPOOL_PROP_SIZE:
|
||||
case ZPOOL_PROP_ALLOCATED:
|
||||
case ZPOOL_PROP_FREE:
|
||||
case ZPOOL_PROP_FREEING:
|
||||
case ZPOOL_PROP_EXPANDSZ:
|
||||
case ZPOOL_PROP_ASHIFT:
|
||||
(void) zfs_nicenum(intval, buf, len);
|
||||
@@ -299,6 +301,12 @@ zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, size_t len,
|
||||
(void) strlcpy(buf, zpool_state_to_name(intval,
|
||||
vs->vs_aux), len);
|
||||
break;
|
||||
case ZPOOL_PROP_VERSION:
|
||||
if (intval >= SPA_VERSION_FEATURES) {
|
||||
(void) snprintf(buf, len, "-");
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
(void) snprintf(buf, len, "%llu", (u_longlong_t)intval);
|
||||
}
|
||||
@@ -403,10 +411,48 @@ zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname,
|
||||
while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
|
||||
const char *propname = nvpair_name(elem);
|
||||
|
||||
prop = zpool_name_to_prop(propname);
|
||||
if (prop == ZPROP_INVAL && zpool_prop_feature(propname)) {
|
||||
int err;
|
||||
zfeature_info_t *feature;
|
||||
char *fname = strchr(propname, '@') + 1;
|
||||
|
||||
err = zfeature_lookup_name(fname, &feature);
|
||||
if (err != 0) {
|
||||
ASSERT3U(err, ==, ENOENT);
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"invalid feature '%s'"), fname);
|
||||
(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (nvpair_type(elem) != DATA_TYPE_STRING) {
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"'%s' must be a string"), propname);
|
||||
(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
|
||||
goto error;
|
||||
}
|
||||
|
||||
(void) nvpair_value_string(elem, &strval);
|
||||
if (strcmp(strval, ZFS_FEATURE_ENABLED) != 0) {
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"property '%s' can only be set to "
|
||||
"'enabled'"), propname);
|
||||
(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (nvlist_add_uint64(retprops, propname, 0) != 0) {
|
||||
(void) no_memory(hdl);
|
||||
goto error;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure this property is valid and applies to this type.
|
||||
*/
|
||||
if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL) {
|
||||
if (prop == ZPROP_INVAL) {
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"invalid property '%s'"), propname);
|
||||
(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
|
||||
@@ -431,7 +477,8 @@ zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname,
|
||||
default:
|
||||
break;
|
||||
case ZPOOL_PROP_VERSION:
|
||||
if (intval < version || intval > SPA_VERSION) {
|
||||
if (intval < version ||
|
||||
!SPA_VERSION_IS_SUPPORTED(intval)) {
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"property '%s' number %d is invalid."),
|
||||
propname, intval);
|
||||
@@ -673,10 +720,79 @@ zpool_expand_proplist(zpool_handle_t *zhp, zprop_list_t **plp)
|
||||
libzfs_handle_t *hdl = zhp->zpool_hdl;
|
||||
zprop_list_t *entry;
|
||||
char buf[ZFS_MAXPROPLEN];
|
||||
nvlist_t *features = NULL;
|
||||
nvpair_t *nvp;
|
||||
zprop_list_t **last;
|
||||
boolean_t firstexpand = (NULL == *plp);
|
||||
int i;
|
||||
|
||||
if (zprop_expand_list(hdl, plp, ZFS_TYPE_POOL) != 0)
|
||||
return (-1);
|
||||
|
||||
last = plp;
|
||||
while (*last != NULL)
|
||||
last = &(*last)->pl_next;
|
||||
|
||||
if ((*plp)->pl_all)
|
||||
features = zpool_get_features(zhp);
|
||||
|
||||
if ((*plp)->pl_all && firstexpand) {
|
||||
for (i = 0; i < SPA_FEATURES; i++) {
|
||||
zprop_list_t *entry = zfs_alloc(hdl,
|
||||
sizeof (zprop_list_t));
|
||||
entry->pl_prop = ZPROP_INVAL;
|
||||
entry->pl_user_prop = zfs_asprintf(hdl, "feature@%s",
|
||||
spa_feature_table[i].fi_uname);
|
||||
entry->pl_width = strlen(entry->pl_user_prop);
|
||||
entry->pl_all = B_TRUE;
|
||||
|
||||
*last = entry;
|
||||
last = &entry->pl_next;
|
||||
}
|
||||
}
|
||||
|
||||
/* add any unsupported features */
|
||||
for (nvp = nvlist_next_nvpair(features, NULL);
|
||||
nvp != NULL; nvp = nvlist_next_nvpair(features, nvp)) {
|
||||
char *propname;
|
||||
boolean_t found;
|
||||
zprop_list_t *entry;
|
||||
|
||||
if (zfeature_is_supported(nvpair_name(nvp)))
|
||||
continue;
|
||||
|
||||
propname = zfs_asprintf(hdl, "unsupported@%s",
|
||||
nvpair_name(nvp));
|
||||
|
||||
/*
|
||||
* Before adding the property to the list make sure that no
|
||||
* other pool already added the same property.
|
||||
*/
|
||||
found = B_FALSE;
|
||||
entry = *plp;
|
||||
while (entry != NULL) {
|
||||
if (entry->pl_user_prop != NULL &&
|
||||
strcmp(propname, entry->pl_user_prop) == 0) {
|
||||
found = B_TRUE;
|
||||
break;
|
||||
}
|
||||
entry = entry->pl_next;
|
||||
}
|
||||
if (found) {
|
||||
free(propname);
|
||||
continue;
|
||||
}
|
||||
|
||||
entry = zfs_alloc(hdl, sizeof (zprop_list_t));
|
||||
entry->pl_prop = ZPROP_INVAL;
|
||||
entry->pl_user_prop = propname;
|
||||
entry->pl_width = strlen(entry->pl_user_prop);
|
||||
entry->pl_all = B_TRUE;
|
||||
|
||||
*last = entry;
|
||||
last = &entry->pl_next;
|
||||
}
|
||||
|
||||
for (entry = *plp; entry != NULL; entry = entry->pl_next) {
|
||||
|
||||
if (entry->pl_fixed)
|
||||
@@ -693,6 +809,66 @@ zpool_expand_proplist(zpool_handle_t *zhp, zprop_list_t **plp)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the state for the given feature on the given ZFS pool.
|
||||
*/
|
||||
int
|
||||
zpool_prop_get_feature(zpool_handle_t *zhp, const char *propname, char *buf,
|
||||
size_t len)
|
||||
{
|
||||
uint64_t refcount;
|
||||
boolean_t found = B_FALSE;
|
||||
nvlist_t *features = zpool_get_features(zhp);
|
||||
boolean_t supported;
|
||||
const char *feature = strchr(propname, '@') + 1;
|
||||
|
||||
supported = zpool_prop_feature(propname);
|
||||
ASSERT(supported || zpool_prop_unsupported(propname));
|
||||
|
||||
/*
|
||||
* Convert from feature name to feature guid. This conversion is
|
||||
* unecessary for unsupported@... properties because they already
|
||||
* use guids.
|
||||
*/
|
||||
if (supported) {
|
||||
int ret;
|
||||
zfeature_info_t *fi;
|
||||
|
||||
ret = zfeature_lookup_name(feature, &fi);
|
||||
if (ret != 0) {
|
||||
(void) strlcpy(buf, "-", len);
|
||||
return (ENOTSUP);
|
||||
}
|
||||
feature = fi->fi_guid;
|
||||
}
|
||||
|
||||
if (nvlist_lookup_uint64(features, feature, &refcount) == 0)
|
||||
found = B_TRUE;
|
||||
|
||||
if (supported) {
|
||||
if (!found) {
|
||||
(void) strlcpy(buf, ZFS_FEATURE_DISABLED, len);
|
||||
} else {
|
||||
if (refcount == 0)
|
||||
(void) strlcpy(buf, ZFS_FEATURE_ENABLED, len);
|
||||
else
|
||||
(void) strlcpy(buf, ZFS_FEATURE_ACTIVE, len);
|
||||
}
|
||||
} else {
|
||||
if (found) {
|
||||
if (refcount == 0) {
|
||||
(void) strcpy(buf, ZFS_UNSUPPORTED_INACTIVE);
|
||||
} else {
|
||||
(void) strcpy(buf, ZFS_UNSUPPORTED_READONLY);
|
||||
}
|
||||
} else {
|
||||
(void) strlcpy(buf, "-", len);
|
||||
return (ENOTSUP);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't start the slice at the default block of 34; many storage
|
||||
@@ -1291,8 +1467,10 @@ zpool_rewind_exclaim(libzfs_handle_t *hdl, const char *name, boolean_t dryrun,
|
||||
if (!hdl->libzfs_printerr || config == NULL)
|
||||
return;
|
||||
|
||||
if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO, &nv) != 0)
|
||||
if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO, &nv) != 0 ||
|
||||
nvlist_lookup_nvlist(nv, ZPOOL_CONFIG_REWIND_INFO, &nv) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_TIME, &rewindto) != 0)
|
||||
return;
|
||||
@@ -1349,6 +1527,7 @@ zpool_explain_recover(libzfs_handle_t *hdl, const char *name, int reason,
|
||||
|
||||
/* All attempted rewinds failed if ZPOOL_CONFIG_LOAD_TIME missing */
|
||||
if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO, &nv) != 0 ||
|
||||
nvlist_lookup_nvlist(nv, ZPOOL_CONFIG_REWIND_INFO, &nv) != 0 ||
|
||||
nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_TIME, &rewindto) != 0)
|
||||
goto no_info;
|
||||
|
||||
@@ -1473,6 +1652,31 @@ print_vdev_tree(libzfs_handle_t *hdl, const char *name, nvlist_t *nv,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
zpool_print_unsup_feat(nvlist_t *config)
|
||||
{
|
||||
nvlist_t *nvinfo, *unsup_feat;
|
||||
nvpair_t *nvp;
|
||||
|
||||
verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO, &nvinfo) ==
|
||||
0);
|
||||
verify(nvlist_lookup_nvlist(nvinfo, ZPOOL_CONFIG_UNSUP_FEAT,
|
||||
&unsup_feat) == 0);
|
||||
|
||||
for (nvp = nvlist_next_nvpair(unsup_feat, NULL); nvp != NULL;
|
||||
nvp = nvlist_next_nvpair(unsup_feat, nvp)) {
|
||||
char *desc;
|
||||
|
||||
verify(nvpair_type(nvp) == DATA_TYPE_STRING);
|
||||
verify(nvpair_value_string(nvp, &desc) == 0);
|
||||
|
||||
if (strlen(desc) > 0)
|
||||
(void) printf("\t%s (%s)\n", nvpair_name(nvp), desc);
|
||||
else
|
||||
(void) printf("\t%s\n", nvpair_name(nvp));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Import the given pool using the known configuration and a list of
|
||||
* properties to be set. The configuration should have come from
|
||||
@@ -1579,6 +1783,22 @@ zpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
|
||||
|
||||
switch (error) {
|
||||
case ENOTSUP:
|
||||
if (nv != NULL && nvlist_lookup_nvlist(nv,
|
||||
ZPOOL_CONFIG_LOAD_INFO, &nvinfo) == 0 &&
|
||||
nvlist_exists(nvinfo, ZPOOL_CONFIG_UNSUP_FEAT)) {
|
||||
(void) printf(dgettext(TEXT_DOMAIN, "This "
|
||||
"pool uses the following feature(s) not "
|
||||
"supported by this system:\n"));
|
||||
zpool_print_unsup_feat(nv);
|
||||
if (nvlist_exists(nvinfo,
|
||||
ZPOOL_CONFIG_CAN_RDONLY)) {
|
||||
(void) printf(dgettext(TEXT_DOMAIN,
|
||||
"All unsupported features are only "
|
||||
"required for writing to the pool."
|
||||
"\nThe pool can be imported using "
|
||||
"'-o readonly=on'.\n"));
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Unsupported version.
|
||||
*/
|
||||
|
||||
@@ -18,8 +18,10 @@
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -214,6 +216,20 @@ check_status(nvlist_t *config, boolean_t isimport)
|
||||
vs->vs_aux == VDEV_AUX_VERSION_NEWER)
|
||||
return (ZPOOL_STATUS_VERSION_NEWER);
|
||||
|
||||
/*
|
||||
* Unsupported feature(s).
|
||||
*/
|
||||
if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
|
||||
vs->vs_aux == VDEV_AUX_UNSUP_FEAT) {
|
||||
nvlist_t *nvinfo;
|
||||
|
||||
verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO,
|
||||
&nvinfo) == 0);
|
||||
if (nvlist_exists(nvinfo, ZPOOL_CONFIG_CAN_RDONLY))
|
||||
return (ZPOOL_STATUS_UNSUP_FEAT_WRITE);
|
||||
return (ZPOOL_STATUS_UNSUP_FEAT_READ);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the config is complete.
|
||||
*/
|
||||
@@ -301,7 +317,7 @@ check_status(nvlist_t *config, boolean_t isimport)
|
||||
/*
|
||||
* Outdated, but usable, version
|
||||
*/
|
||||
if (version < SPA_VERSION)
|
||||
if (SPA_VERSION_IS_SUPPORTED(version) && version != SPA_VERSION)
|
||||
return (ZPOOL_STATUS_VERSION_OLDER);
|
||||
|
||||
return (ZPOOL_STATUS_OK);
|
||||
|
||||
@@ -18,9 +18,10 @@
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -47,6 +48,7 @@
|
||||
|
||||
#include "libzfs_impl.h"
|
||||
#include "zfs_prop.h"
|
||||
#include "zfeature_common.h"
|
||||
|
||||
int
|
||||
libzfs_errno(libzfs_handle_t *hdl)
|
||||
@@ -114,7 +116,8 @@ libzfs_error_description(libzfs_handle_t *hdl)
|
||||
case EZFS_RESILVERING:
|
||||
return (dgettext(TEXT_DOMAIN, "currently resilvering"));
|
||||
case EZFS_BADVERSION:
|
||||
return (dgettext(TEXT_DOMAIN, "unsupported version"));
|
||||
return (dgettext(TEXT_DOMAIN, "unsupported version or "
|
||||
"feature"));
|
||||
case EZFS_POOLUNAVAIL:
|
||||
return (dgettext(TEXT_DOMAIN, "pool is unavailable"));
|
||||
case EZFS_DEVOVERFLOW:
|
||||
@@ -709,6 +712,7 @@ libzfs_init(void)
|
||||
|
||||
zfs_prop_init();
|
||||
zpool_prop_init();
|
||||
zpool_feature_init();
|
||||
libzfs_mnttab_init(hdl);
|
||||
|
||||
return (hdl);
|
||||
@@ -1532,9 +1536,11 @@ addlist(libzfs_handle_t *hdl, char *propname, zprop_list_t **listp,
|
||||
* this is a pool property or if this isn't a user-defined
|
||||
* dataset property,
|
||||
*/
|
||||
if (prop == ZPROP_INVAL && (type == ZFS_TYPE_POOL ||
|
||||
(!zfs_prop_user(propname) && !zfs_prop_userquota(propname) &&
|
||||
!zfs_prop_written(propname)))) {
|
||||
if (prop == ZPROP_INVAL && ((type == ZFS_TYPE_POOL &&
|
||||
!zpool_prop_feature(propname) &&
|
||||
!zpool_prop_unsupported(propname)) ||
|
||||
(type == ZFS_TYPE_DATASET && !zfs_prop_user(propname) &&
|
||||
!zfs_prop_userquota(propname) && !zfs_prop_written(propname)))) {
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"invalid property '%s'"), propname);
|
||||
return (zfs_error(hdl, EZFS_BADPROP,
|
||||
@@ -1546,7 +1552,8 @@ addlist(libzfs_handle_t *hdl, char *propname, zprop_list_t **listp,
|
||||
|
||||
entry->pl_prop = prop;
|
||||
if (prop == ZPROP_INVAL) {
|
||||
if ((entry->pl_user_prop = zfs_strdup(hdl, propname)) == NULL) {
|
||||
if ((entry->pl_user_prop = zfs_strdup(hdl, propname)) ==
|
||||
NULL) {
|
||||
free(entry);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ libzpool_la_SOURCES = \
|
||||
$(top_srcdir)/module/zfs/arc.c \
|
||||
$(top_srcdir)/module/zfs/bplist.c \
|
||||
$(top_srcdir)/module/zfs/bpobj.c \
|
||||
$(top_srcdir)/module/zfs/bptree.c \
|
||||
$(top_srcdir)/module/zfs/dbuf.c \
|
||||
$(top_srcdir)/module/zfs/ddt.c \
|
||||
$(top_srcdir)/module/zfs/ddt_zap.c \
|
||||
@@ -74,6 +75,8 @@ libzpool_la_SOURCES = \
|
||||
$(top_srcdir)/module/zfs/zap.c \
|
||||
$(top_srcdir)/module/zfs/zap_leaf.c \
|
||||
$(top_srcdir)/module/zfs/zap_micro.c \
|
||||
$(top_srcdir)/module/zfs/zfeature.c \
|
||||
$(top_srcdir)/module/zfs/zfeature_common.c \
|
||||
$(top_srcdir)/module/zfs/zfs_byteswap.c \
|
||||
$(top_srcdir)/module/zfs/zfs_debug.c \
|
||||
$(top_srcdir)/module/zfs/zfs_fm.c \
|
||||
|
||||
@@ -647,7 +647,9 @@ vn_rdwr(int uio, vnode_t *vp, void *addr, ssize_t len, offset_t offset,
|
||||
* To simulate partial disk writes, we split writes into two
|
||||
* system calls so that the process can be killed in between.
|
||||
*/
|
||||
split = (len > 0 ? rand() % len : 0);
|
||||
int sectors = len >> SPA_MINBLOCKSHIFT;
|
||||
split = (sectors > 0 ? rand() % sectors : 0) <<
|
||||
SPA_MINBLOCKSHIFT;
|
||||
rc = pwrite64(vp->v_fd, addr, split, offset);
|
||||
if (rc != -1) {
|
||||
done = rc;
|
||||
|
||||
Reference in New Issue
Block a user