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
This commit is contained in:
parent
5240466227
commit
4dfc3c75a2
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
* added to errlist, but will not cause an overall failure.
|
||||
*
|
||||
* The return value will be ENOENT if none of the snapshots for the requested
|
||||
* holds existed.
|
||||
*
|
||||
* 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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user