diff options
author | Matthew Ahrens <mahrens@delphix.com> | 2013-06-20 14:43:17 -0800 |
---|---|---|
committer | Christopher Siden <chris.siden@delphix.com> | 2013-06-20 15:43:17 -0700 |
commit | bb6e70758d0c30c09f148026d6e686e21cfc8d18 (patch) | |
tree | 459ebb70610e7dc95b527e8a677b92f9a6d670e9 | |
parent | 296749875bd503e7a14e25b4c57d3142cb496df1 (diff) | |
download | illumos-joyent-bb6e70758d0c30c09f148026d6e686e21cfc8d18.tar.gz |
3829 fix for 3740 changed behavior of zfs destroy/hold/release ioctl
Reviewed by: Matt Amdur <matt.amdur@delphix.com>
Reviewed by: Christopher Siden <christopher.siden@delphix.com>
Approved by: Richard Lowe <richlowe@richlowe.net>
-rw-r--r-- | usr/src/lib/libzfs/common/libzfs_dataset.c | 27 | ||||
-rw-r--r-- | usr/src/lib/libzfs_core/common/libzfs_core.c | 23 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/dsl_destroy.c | 3 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/dsl_userhold.c | 8 |
4 files changed, 25 insertions, 36 deletions
diff --git a/usr/src/lib/libzfs/common/libzfs_dataset.c b/usr/src/lib/libzfs/common/libzfs_dataset.c index 635bc87e29..58af6dfa04 100644 --- a/usr/src/lib/libzfs/common/libzfs_dataset.c +++ b/usr/src/lib/libzfs/common/libzfs_dataset.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012 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) 2013 Martin Matuska. All rights reserved. @@ -4073,6 +4073,7 @@ struct holdarg { const char *snapname; const char *tag; boolean_t recursive; + int error; }; static int @@ -4200,15 +4201,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) @@ -4232,16 +4238,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/usr/src/lib/libzfs_core/common/libzfs_core.c b/usr/src/lib/libzfs_core/common/libzfs_core.c index 990beafd1f..a4f51233f4 100644 --- a/usr/src/lib/libzfs_core/common/libzfs_core.c +++ b/usr/src/lib/libzfs_core/common/libzfs_core.c @@ -255,11 +255,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 @@ -350,15 +347,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. @@ -402,13 +394,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/usr/src/uts/common/fs/zfs/dsl_destroy.c b/usr/src/uts/common/fs/zfs/dsl_destroy.c index e74b53f1aa..f968215db0 100644 --- a/usr/src/uts/common/fs/zfs/dsl_destroy.c +++ b/usr/src/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/usr/src/uts/common/fs/zfs/dsl_userhold.c b/usr/src/uts/common/fs/zfs/dsl_userhold.c index b6fa417eec..a948e10b12 100644 --- a/usr/src/uts/common/fs/zfs/dsl_userhold.c +++ b/usr/src/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); } |