Destroy makes full snap list before destroying

Change zfs destroy logic so destroying begins before
the entire list of snapshots is built.

Reviewed-by: loli10K <ezomori.nozomu@gmail.com>
Reviewed-by: Kash Pande <kash@tripleback.net>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Paul Zuchowski <pzuchowski@datto.com>
Closes #7271
This commit is contained in:
Paul Zuchowski 2018-03-12 18:24:08 -04:00 committed by Brian Behlendorf
parent 9470cbd4f9
commit 83362e8e67
2 changed files with 18 additions and 7 deletions

View File

@ -1060,6 +1060,7 @@ typedef struct destroy_cbdata {
int64_t cb_snapused; int64_t cb_snapused;
char *cb_snapspec; char *cb_snapspec;
char *cb_bookmark; char *cb_bookmark;
uint64_t cb_snap_count;
} destroy_cbdata_t; } destroy_cbdata_t;
/* /*
@ -1122,11 +1123,22 @@ out:
return (0); return (0);
} }
static int
destroy_batched(destroy_cbdata_t *cb)
{
int error = zfs_destroy_snaps_nvl(g_zfs,
cb->cb_batchedsnaps, B_FALSE);
fnvlist_free(cb->cb_batchedsnaps);
cb->cb_batchedsnaps = fnvlist_alloc();
return (error);
}
static int static int
destroy_callback(zfs_handle_t *zhp, void *data) destroy_callback(zfs_handle_t *zhp, void *data)
{ {
destroy_cbdata_t *cb = data; destroy_cbdata_t *cb = data;
const char *name = zfs_get_name(zhp); const char *name = zfs_get_name(zhp);
int error;
if (cb->cb_verbose) { if (cb->cb_verbose) {
if (cb->cb_parsable) { if (cb->cb_parsable) {
@ -1161,13 +1173,12 @@ destroy_callback(zfs_handle_t *zhp, void *data)
* because we must delete a clone before its origin. * because we must delete a clone before its origin.
*/ */
if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) { if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) {
cb->cb_snap_count++;
fnvlist_add_boolean(cb->cb_batchedsnaps, name); fnvlist_add_boolean(cb->cb_batchedsnaps, name);
if (cb->cb_snap_count % 10 == 0 && cb->cb_defer_destroy)
error = destroy_batched(cb);
} else { } else {
int error = zfs_destroy_snaps_nvl(g_zfs, error = destroy_batched(cb);
cb->cb_batchedsnaps, B_FALSE);
fnvlist_free(cb->cb_batchedsnaps);
cb->cb_batchedsnaps = fnvlist_alloc();
if (error != 0 || if (error != 0 ||
zfs_unmount(zhp, NULL, cb->cb_force ? MS_FORCE : 0) != 0 || zfs_unmount(zhp, NULL, cb->cb_force ? MS_FORCE : 0) != 0 ||
zfs_destroy(zhp, cb->cb_defer_destroy) != 0) { zfs_destroy(zhp, cb->cb_defer_destroy) != 0) {
@ -1524,7 +1535,6 @@ zfs_do_destroy(int argc, char **argv)
rv = 1; rv = 1;
goto out; goto out;
} }
cb.cb_batchedsnaps = fnvlist_alloc(); cb.cb_batchedsnaps = fnvlist_alloc();
if (zfs_iter_dependents(zhp, B_FALSE, destroy_callback, if (zfs_iter_dependents(zhp, B_FALSE, destroy_callback,
&cb) != 0) { &cb) != 0) {

View File

@ -2528,7 +2528,8 @@ If this flag is specified, the
.Fl d .Fl d
flag will have no effect. flag will have no effect.
.It Fl d .It Fl d
Defer snapshot deletion. Destroy immediately. If a snapshot cannot be destroyed now, mark it for
deferred destruction.
.It Fl n .It Fl n
Do a dry-run Do a dry-run
.Pq Qq No-op .Pq Qq No-op