diff options
author | delphij <delphij@FreeBSD.org> | 2013-06-25 22:14:32 +0000 |
---|---|---|
committer | delphij <delphij@FreeBSD.org> | 2013-06-25 22:14:32 +0000 |
commit | 4dfc3c75a2687795bcf32661c8434cf7628e82a2 (patch) | |
tree | 4b1454baea37713509a3ede6d1c64c528e9a810f | |
parent | 524046622706f82ee0244247e5a37dc1c966856f (diff) | |
download | FreeBSD-src-4dfc3c75a2687795bcf32661c8434cf7628e82a2.zip FreeBSD-src-4dfc3c75a2687795bcf32661c8434cf7628e82a2.tar.gz |
MFV r252215:
Restore a previous behavior before r251646, where when destructing
ZFS snapshot, the ioctl would return ENOENT when it hit any of
them in the errlist (the new behavior was only return ENOENT when
all returns error).
Illumos ZFS issues:
3829 fix for 3740 changed behavior of zfs destroy/hold/release ioctl
MFC after: 1 week
4 files changed, 26 insertions, 37 deletions
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c index e10133c..3d96da2 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c @@ -21,9 +21,9 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2012 Nexenta Systems, Inc. All rights reserved. - * Copyright (c) 2011 by Delphix. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. * Copyright (c) 2012 DEY Storage Systems, Inc. All rights reserved. + * Copyright 2012 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2011-2012 Pawel Jakub Dawidek <pawel@dawidek.net>. * All rights reserved. * Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved. @@ -4159,6 +4159,7 @@ struct holdarg { const char *snapname; const char *tag; boolean_t recursive; + int error; }; static int @@ -4286,15 +4287,20 @@ zfs_release_one(zfs_handle_t *zhp, void *arg) struct holdarg *ha = arg; char name[ZFS_MAXNAMELEN]; int rv = 0; + nvlist_t *existing_holds; (void) snprintf(name, sizeof (name), "%s@%s", zhp->zfs_name, ha->snapname); - if (lzc_exists(name)) { - nvlist_t *holds = fnvlist_alloc(); - fnvlist_add_boolean(holds, ha->tag); - fnvlist_add_nvlist(ha->nvl, name, holds); - fnvlist_free(holds); + if (lzc_get_holds(name, &existing_holds) != 0) { + ha->error = ENOENT; + } else if (!nvlist_exists(existing_holds, ha->tag)) { + ha->error = ESRCH; + } else { + nvlist_t *torelease = fnvlist_alloc(); + fnvlist_add_boolean(torelease, ha->tag); + fnvlist_add_nvlist(ha->nvl, name, torelease); + fnvlist_free(torelease); } if (ha->recursive) @@ -4318,16 +4324,21 @@ zfs_release(zfs_handle_t *zhp, const char *snapname, const char *tag, ha.snapname = snapname; ha.tag = tag; ha.recursive = recursive; + ha.error = 0; (void) zfs_release_one(zfs_handle_dup(zhp), &ha); if (nvlist_empty(ha.nvl)) { fnvlist_free(ha.nvl); - ret = ENOENT; + ret = ha.error; (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, "cannot release hold from snapshot '%s@%s'"), zhp->zfs_name, snapname); - (void) zfs_standard_error(hdl, ret, errbuf); + if (ret == ESRCH) { + (void) zfs_error(hdl, EZFS_REFTAG_RELE, errbuf); + } else { + (void) zfs_standard_error(hdl, ret, errbuf); + } return (ret); } diff --git a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c index 31d5fd5..c5c3b0e 100644 --- a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c +++ b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c @@ -302,11 +302,8 @@ lzc_snapshot(nvlist_t *snaps, nvlist_t *props, nvlist_t **errlist) * marked for deferred destruction, and will be destroyed when the last hold * or clone is removed/destroyed. * - * The return value will be ENOENT if none of the snapshots existed. - * * The return value will be 0 if all snapshots were destroyed (or marked for - * later destruction if 'defer' is set) or didn't exist to begin with and - * at least one snapshot was destroyed. + * later destruction if 'defer' is set) or didn't exist to begin with. * * Otherwise the return value will be the errno of a (unspecified) snapshot * that failed, no snapshots will be destroyed, and the errlist will have an @@ -397,15 +394,10 @@ lzc_exists(const char *dataset) * or imported. * * Holds for snapshots which don't exist will be skipped and have an entry - * added to errlist, but will not cause an overall failure, except in the - * case that all holds where skipped. - * - * The return value will be ENOENT if none of the snapshots for the requested - * holds existed. + * added to errlist, but will not cause an overall failure. * - * The return value will be 0 if the nvl holds was empty or all holds, for - * snapshots that existed, were succesfully created and at least one hold - * was created. + * The return value will be 0 if all holds, for snapshots that existed, + * were succesfully created. * * Otherwise the return value will be the errno of a (unspecified) hold that * failed and no holds will be created. @@ -449,13 +441,10 @@ lzc_hold(nvlist_t *holds, int cleanup_fd, nvlist_t **errlist) * The value is a nvlist whose keys are the holds to remove. * * Holds which failed to release because they didn't exist will have an entry - * added to errlist, but will not cause an overall failure, except in the - * case that all releases where skipped. - * - * The return value will be ENOENT if none of the specified holds existed. + * added to errlist, but will not cause an overall failure. * * The return value will be 0 if the nvl holds was empty or all holds that - * existed, were successfully removed and at least one hold was removed. + * existed, were successfully removed. * * Otherwise the return value will be the errno of a (unspecified) hold that * failed to release and no holds will be released. diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_destroy.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_destroy.c index e74b53f..f968215 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_destroy.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_destroy.c @@ -129,9 +129,6 @@ dsl_destroy_snapshot_check(void *arg, dmu_tx_t *tx) if (pair != NULL) return (fnvpair_value_int32(pair)); - if (nvlist_empty(dsda->dsda_successful_snaps)) - return (SET_ERROR(ENOENT)); - return (0); } diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_userhold.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_userhold.c index b6fa417..a948e10 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_userhold.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_userhold.c @@ -126,10 +126,6 @@ dsl_dataset_user_hold_check(void *arg, dmu_tx_t *tx) } } - /* Return ENOENT if no holds would be created. */ - if (nvlist_empty(dduha->dduha_chkholds)) - return (SET_ERROR(ENOENT)); - return (0); } @@ -468,10 +464,6 @@ dsl_dataset_user_release_check(void *arg, dmu_tx_t *tx) } } - /* Return ENOENT if none of the holds existed. */ - if (nvlist_empty(ddura->ddura_chkholds)) - return (SET_ERROR(ENOENT)); - return (0); } |