summaryrefslogtreecommitdiffstats
path: root/lib/libzfs/libzfs_iter.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libzfs/libzfs_iter.c')
-rw-r--r--lib/libzfs/libzfs_iter.c37
1 files changed, 30 insertions, 7 deletions
diff --git a/lib/libzfs/libzfs_iter.c b/lib/libzfs/libzfs_iter.c
index b1bdc4a6d..e765a7ee7 100644
--- a/lib/libzfs/libzfs_iter.c
+++ b/lib/libzfs/libzfs_iter.c
@@ -23,7 +23,7 @@
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2015 by Delphix. All rights reserved.
* Copyright 2014 Nexenta Systems, Inc. All rights reserved.
- * Copyright (c) 2018 Datto Inc.
+ * Copyright (c) 2019 Datto Inc.
*/
#include <stdio.h>
@@ -141,11 +141,12 @@ zfs_iter_filesystems(zfs_handle_t *zhp, zfs_iter_f func, void *data)
*/
int
zfs_iter_snapshots(zfs_handle_t *zhp, boolean_t simple, zfs_iter_f func,
- void *data)
+ void *data, uint64_t min_txg, uint64_t max_txg)
{
zfs_cmd_t zc = {"\0"};
zfs_handle_t *nzhp;
int ret;
+ nvlist_t *range_nvl = NULL;
if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT ||
zhp->zfs_type == ZFS_TYPE_BOOKMARK)
@@ -155,6 +156,24 @@ zfs_iter_snapshots(zfs_handle_t *zhp, boolean_t simple, zfs_iter_f func,
if (zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0) != 0)
return (-1);
+
+ if (min_txg != 0) {
+ range_nvl = fnvlist_alloc();
+ fnvlist_add_uint64(range_nvl, SNAP_ITER_MIN_TXG, min_txg);
+ }
+ if (max_txg != 0) {
+ if (range_nvl == NULL)
+ range_nvl = fnvlist_alloc();
+ fnvlist_add_uint64(range_nvl, SNAP_ITER_MAX_TXG, max_txg);
+ }
+
+ if (range_nvl != NULL &&
+ zcmd_write_src_nvlist(zhp->zfs_hdl, &zc, range_nvl) != 0) {
+ zcmd_free_nvlists(&zc);
+ fnvlist_free(range_nvl);
+ return (-1);
+ }
+
while ((ret = zfs_do_list_ioctl(zhp, ZFS_IOC_SNAPSHOT_LIST_NEXT,
&zc)) == 0) {
@@ -167,10 +186,12 @@ zfs_iter_snapshots(zfs_handle_t *zhp, boolean_t simple, zfs_iter_f func,
if ((ret = func(nzhp, data)) != 0) {
zcmd_free_nvlists(&zc);
+ fnvlist_free(range_nvl);
return (ret);
}
}
zcmd_free_nvlists(&zc);
+ fnvlist_free(range_nvl);
return ((ret < 0) ? ret : 0);
}
@@ -282,7 +303,8 @@ zfs_snapshot_compare(const void *larg, const void *rarg)
}
int
-zfs_iter_snapshots_sorted(zfs_handle_t *zhp, zfs_iter_f callback, void *data)
+zfs_iter_snapshots_sorted(zfs_handle_t *zhp, zfs_iter_f callback, void *data,
+ uint64_t min_txg, uint64_t max_txg)
{
int ret = 0;
zfs_node_t *node;
@@ -292,7 +314,8 @@ zfs_iter_snapshots_sorted(zfs_handle_t *zhp, zfs_iter_f callback, void *data)
avl_create(&avl, zfs_snapshot_compare,
sizeof (zfs_node_t), offsetof(zfs_node_t, zn_avlnode));
- ret = zfs_iter_snapshots(zhp, B_FALSE, zfs_sort_snaps, &avl);
+ ret = zfs_iter_snapshots(zhp, B_FALSE, zfs_sort_snaps, &avl, min_txg,
+ max_txg);
for (node = avl_first(&avl); node != NULL; node = AVL_NEXT(&avl, node))
ret |= callback(node->zn_handle, data);
@@ -395,7 +418,7 @@ zfs_iter_snapspec(zfs_handle_t *fs_zhp, const char *spec_orig,
}
err = zfs_iter_snapshots_sorted(fs_zhp,
- snapspec_cb, &ssa);
+ snapspec_cb, &ssa, 0, 0);
if (ret == 0)
ret = err;
if (ret == 0 && (!ssa.ssa_seenfirst ||
@@ -435,7 +458,7 @@ zfs_iter_children(zfs_handle_t *zhp, zfs_iter_f func, void *data)
{
int ret;
- if ((ret = zfs_iter_snapshots(zhp, B_FALSE, func, data)) != 0)
+ if ((ret = zfs_iter_snapshots(zhp, B_FALSE, func, data, 0, 0)) != 0)
return (ret);
return (zfs_iter_filesystems(zhp, func, data));
@@ -501,7 +524,7 @@ iter_dependents_cb(zfs_handle_t *zhp, void *arg)
err = zfs_iter_filesystems(zhp, iter_dependents_cb, ida);
if (err == 0)
err = zfs_iter_snapshots(zhp, B_FALSE,
- iter_dependents_cb, ida);
+ iter_dependents_cb, ida, 0, 0);
ida->stack = isf.next;
}