aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Zuchowski <[email protected]>2018-03-12 18:24:08 -0400
committerBrian Behlendorf <[email protected]>2018-03-12 15:24:08 -0700
commit83362e8e676a3ffae6b3b21f350f9b999a068605 (patch)
treefc19045897b722c9d0d193600fcb5059b24b1572
parent9470cbd4f95ecd730d18f7dadd56bcf54c6711b0 (diff)
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 <[email protected]> Reviewed-by: Kash Pande <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Paul Zuchowski <[email protected]> Closes #7271
-rw-r--r--cmd/zfs/zfs_main.c22
-rw-r--r--man/man8/zfs.83
2 files changed, 18 insertions, 7 deletions
diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c
index cb416b9d3..e241831db 100644
--- a/cmd/zfs/zfs_main.c
+++ b/cmd/zfs/zfs_main.c
@@ -1060,6 +1060,7 @@ typedef struct destroy_cbdata {
int64_t cb_snapused;
char *cb_snapspec;
char *cb_bookmark;
+ uint64_t cb_snap_count;
} destroy_cbdata_t;
/*
@@ -1123,10 +1124,21 @@ out:
}
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
destroy_callback(zfs_handle_t *zhp, void *data)
{
destroy_cbdata_t *cb = data;
const char *name = zfs_get_name(zhp);
+ int error;
if (cb->cb_verbose) {
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.
*/
if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) {
+ cb->cb_snap_count++;
fnvlist_add_boolean(cb->cb_batchedsnaps, name);
+ if (cb->cb_snap_count % 10 == 0 && cb->cb_defer_destroy)
+ error = destroy_batched(cb);
} else {
- int error = zfs_destroy_snaps_nvl(g_zfs,
- cb->cb_batchedsnaps, B_FALSE);
- fnvlist_free(cb->cb_batchedsnaps);
- cb->cb_batchedsnaps = fnvlist_alloc();
-
+ error = destroy_batched(cb);
if (error != 0 ||
zfs_unmount(zhp, NULL, cb->cb_force ? MS_FORCE : 0) != 0 ||
zfs_destroy(zhp, cb->cb_defer_destroy) != 0) {
@@ -1524,7 +1535,6 @@ zfs_do_destroy(int argc, char **argv)
rv = 1;
goto out;
}
-
cb.cb_batchedsnaps = fnvlist_alloc();
if (zfs_iter_dependents(zhp, B_FALSE, destroy_callback,
&cb) != 0) {
diff --git a/man/man8/zfs.8 b/man/man8/zfs.8
index ea585b533..7d7af1540 100644
--- a/man/man8/zfs.8
+++ b/man/man8/zfs.8
@@ -2528,7 +2528,8 @@ If this flag is specified, the
.Fl d
flag will have no effect.
.It Fl d
-Defer snapshot deletion.
+Destroy immediately. If a snapshot cannot be destroyed now, mark it for
+deferred destruction.
.It Fl n
Do a dry-run
.Pq Qq No-op