aboutsummaryrefslogtreecommitdiffstats
path: root/module
diff options
context:
space:
mode:
Diffstat (limited to 'module')
-rw-r--r--module/zfs/zfs_ioctl.c78
1 files changed, 60 insertions, 18 deletions
diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c
index ab40ae185..047193c61 100644
--- a/module/zfs/zfs_ioctl.c
+++ b/module/zfs/zfs_ioctl.c
@@ -34,9 +34,9 @@
* Copyright 2016 Toomas Soome <[email protected]>
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
* Copyright (c) 2018, loli10K <[email protected]>. All rights reserved.
- * Copyright (c) 2017 Datto Inc. All rights reserved.
* Copyright 2017 RackTop Systems.
* Copyright (c) 2017 Open-E, Inc. All Rights Reserved.
+ * Copyright (c) 2019 Datto Inc.
*/
/*
@@ -2315,7 +2315,8 @@ top:
* inputs:
* zc_name name of filesystem
* zc_cookie zap cursor
- * zc_nvlist_dst_size size of buffer for property nvlist
+ * zc_nvlist_src iteration range nvlist
+ * zc_nvlist_src_size size of iteration range nvlist
*
* outputs:
* zc_name name of next snapshot
@@ -2326,8 +2327,23 @@ top:
static int
zfs_ioc_snapshot_list_next(zfs_cmd_t *zc)
{
- objset_t *os;
int error;
+ objset_t *os, *ossnap;
+ dsl_dataset_t *ds;
+ uint64_t min_txg = 0, max_txg = 0;
+
+ if (zc->zc_nvlist_src_size != 0) {
+ nvlist_t *props = NULL;
+ error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
+ zc->zc_iflags, &props);
+ if (error != 0)
+ return (error);
+ (void) nvlist_lookup_uint64(props, SNAP_ITER_MIN_TXG,
+ &min_txg);
+ (void) nvlist_lookup_uint64(props, SNAP_ITER_MAX_TXG,
+ &max_txg);
+ nvlist_free(props);
+ }
error = dmu_objset_hold(zc->zc_name, FTAG, &os);
if (error != 0) {
@@ -2344,26 +2360,52 @@ zfs_ioc_snapshot_list_next(zfs_cmd_t *zc)
return (SET_ERROR(ESRCH));
}
- error = dmu_snapshot_list_next(os,
- sizeof (zc->zc_name) - strlen(zc->zc_name),
- zc->zc_name + strlen(zc->zc_name), &zc->zc_obj, &zc->zc_cookie,
- NULL);
+ while (error == 0) {
+ if (issig(JUSTLOOKING) && issig(FORREAL)) {
+ error = SET_ERROR(EINTR);
+ break;
+ }
- if (error == 0 && !zc->zc_simple) {
- dsl_dataset_t *ds;
- dsl_pool_t *dp = os->os_dsl_dataset->ds_dir->dd_pool;
+ error = dmu_snapshot_list_next(os,
+ sizeof (zc->zc_name) - strlen(zc->zc_name),
+ zc->zc_name + strlen(zc->zc_name), &zc->zc_obj,
+ &zc->zc_cookie, NULL);
+ if (error == ENOENT) {
+ error = SET_ERROR(ESRCH);
+ break;
+ } else if (error != 0) {
+ break;
+ }
- error = dsl_dataset_hold_obj(dp, zc->zc_obj, FTAG, &ds);
- if (error == 0) {
- objset_t *ossnap;
+ error = dsl_dataset_hold_obj(dmu_objset_pool(os), zc->zc_obj,
+ FTAG, &ds);
+ if (error != 0)
+ break;
- error = dmu_objset_from_ds(ds, &ossnap);
- if (error == 0)
- error = zfs_ioc_objset_stats_impl(zc, ossnap);
+ if ((min_txg != 0 && dsl_get_creationtxg(ds) < min_txg) ||
+ (max_txg != 0 && dsl_get_creationtxg(ds) > max_txg)) {
dsl_dataset_rele(ds, FTAG);
+ /* undo snapshot name append */
+ *(strchr(zc->zc_name, '@') + 1) = '\0';
+ /* skip snapshot */
+ continue;
}
- } else if (error == ENOENT) {
- error = SET_ERROR(ESRCH);
+
+ if (zc->zc_simple) {
+ dsl_dataset_rele(ds, FTAG);
+ break;
+ }
+
+ if ((error = dmu_objset_from_ds(ds, &ossnap)) != 0) {
+ dsl_dataset_rele(ds, FTAG);
+ break;
+ }
+ if ((error = zfs_ioc_objset_stats_impl(zc, ossnap)) != 0) {
+ dsl_dataset_rele(ds, FTAG);
+ break;
+ }
+ dsl_dataset_rele(ds, FTAG);
+ break;
}
dmu_objset_rele(os, FTAG);