]> granicus.if.org Git - zfs/commitdiff
Destroy makes full snap list before destroying
authorPaul Zuchowski <31706010+PaulZ-98@users.noreply.github.com>
Mon, 12 Mar 2018 22:24:08 +0000 (18:24 -0400)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Mon, 12 Mar 2018 22:24:08 +0000 (15:24 -0700)
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

cmd/zfs/zfs_main.c
man/man8/zfs.8

index cb416b9d3a9d007756fa589163a090e8d08e9765..e241831db5bf1f19de49ea0e96638534f5fd5cb3 100644 (file)
@@ -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;
 
 /*
@@ -1122,11 +1123,22 @@ out:
        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
 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) {
index ea585b5331a964729675dc2f944b03cb50467368..7d7af154099b352ea019434beda886a64927521f 100644 (file)
@@ -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