svn commit: r354116 - in head: cddl/contrib/opensolaris/cmd/zfs cddl/contrib/opensolaris/lib/libzfs/common sys/cddl/contrib/opensolaris/uts/common/fs/zfs sys/cddl/contrib/opensolaris/uts/common/sys/fs

Dan Mack mack at macktronics.com
Sat Oct 26 18:37:05 UTC 2019


This appears to have broken my buildworld unless I did something wrong on 
my end: Last Changed Rev: 354116


snip ...

===> lib/ofed/libibumad (all)
--- all_subdir_lib/libbe ---
/usr/src/lib/libbe/be_info.c:260:67: error: too few arguments to function 
call, expected 5, have 3
         return (zfs_iter_snapshots_sorted(hdl, prop_list_builder_cb, 
data));
                 ~~~~~~~~~~~~~~~~~~~~~~~~~                                ^
/usr/src/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h:575:1: note: 
'zfs_iter_snapshots_sorted' declared here
extern int zfs_iter_snapshots_sorted(zfs_handle_t *, zfs_iter_f, void *,
^
1 error generated.
*** [be_info.o] Error code 1

On Sat, 26 Oct 2019, Alan Somers wrote:

> Author: asomers
> Date: Sat Oct 26 17:11:02 2019
> New Revision: 354116
> URL: https://svnweb.freebsd.org/changeset/base/354116
>
> Log:
>  MFZoL:  Avoid retrieving unused snapshot props
>
>  This patch modifies the zfs_ioc_snapshot_list_next() ioctl to enable it
>  to take input parameters that alter the way looping through the list of
>  snapshots is performed. The idea here is to restrict functions that
>  throw away some of the snapshots returned by the ioctl to a range of
>  snapshots that these functions actually use. This improves efficiency
>  and execution speed for some rollback and send operations.
>
>  Reviewed-by: Tom Caputi <tcaputi at datto.com>
>  Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
>  Reviewed by: Matt Ahrens <mahrens at delphix.com>
>  Signed-off-by: Alek Pinchuk <apinchuk at datto.com>
>  Closes #8077
>  zfsonlinux/zfs at 4c0883fb4af0d5565459099b98fcf90ecbfa1ca1
>
>  MFC after:	2 weeks
>
> Modified:
>  head/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c
>  head/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
>  head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
>  head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
>  head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c
>  head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c
>  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
>  head/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h
>
> Modified: head/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c
> ==============================================================================
> --- head/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c	Sat Oct 26 17:10:27 2019	(r354115)
> +++ head/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c	Sat Oct 26 17:11:02 2019	(r354116)
> @@ -139,7 +139,7 @@ zfs_callback(zfs_handle_t *zhp, void *data)
> 		    ZFS_TYPE_BOOKMARK)) == 0) && include_snaps)
> 			(void) zfs_iter_snapshots(zhp,
> 			    (cb->cb_flags & ZFS_ITER_SIMPLE) != 0, zfs_callback,
> -			    data);
> +			    data, 0, 0);
> 		if (((zfs_get_type(zhp) & (ZFS_TYPE_SNAPSHOT |
> 		    ZFS_TYPE_BOOKMARK)) == 0) && include_bmarks)
> 			(void) zfs_iter_bookmarks(zhp, zfs_callback, data);
>
> Modified: head/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
> ==============================================================================
> --- head/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c	Sat Oct 26 17:10:27 2019	(r354115)
> +++ head/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c	Sat Oct 26 17:11:02 2019	(r354116)
> @@ -30,7 +30,7 @@
>  * Copyright (c) 2014 Integros [integros.com]
>  * Copyright 2016 Igor Kozhukhov <ikozhukhov at gmail.com>.
>  * Copyright 2016 Nexenta Systems, Inc.
> - * Copyright (c) 2018 Datto Inc.
> + * Copyright (c) 2019 Datto Inc.
>  */
>
> #include <assert.h>
> @@ -1174,7 +1174,7 @@ destroy_print_snapshots(zfs_handle_t *fs_zhp, destroy_
> 	int err = 0;
> 	assert(cb->cb_firstsnap == NULL);
> 	assert(cb->cb_prevsnap == NULL);
> -	err = zfs_iter_snapshots_sorted(fs_zhp, destroy_print_cb, cb);
> +	err = zfs_iter_snapshots_sorted(fs_zhp, destroy_print_cb, cb, 0, 0);
> 	if (cb->cb_firstsnap != NULL) {
> 		uint64_t used = 0;
> 		if (err == 0) {
> @@ -3437,6 +3437,7 @@ zfs_do_promote(int argc, char **argv)
>  */
> typedef struct rollback_cbdata {
> 	uint64_t	cb_create;
> +	uint8_t		cb_younger_ds_printed;
> 	boolean_t	cb_first;
> 	int		cb_doclones;
> 	char		*cb_target;
> @@ -3467,15 +3468,20 @@ rollback_check_dependent(zfs_handle_t *zhp, void *data
> }
>
> /*
> - * Report any snapshots more recent than the one specified.  Used when '-r' is
> - * not specified.  We reuse this same callback for the snapshot dependents - if
> - * 'cb_dependent' is set, then this is a dependent and we should report it
> - * without checking the transaction group.
> + * Report some snapshots/bookmarks more recent than the one specified.
> + * Used when '-r' is not specified. We reuse this same callback for the
> + * snapshot dependents - if 'cb_dependent' is set, then this is a
> + * dependent and we should report it without checking the transaction group.
>  */
> static int
> rollback_check(zfs_handle_t *zhp, void *data)
> {
> 	rollback_cbdata_t *cbp = data;
> +	/*
> +	 * Max number of younger snapshots and/or bookmarks to display before
> +	 * we stop the iteration.
> +	 */
> +	const uint8_t max_younger = 32;
>
> 	if (cbp->cb_doclones) {
> 		zfs_close(zhp);
> @@ -3504,9 +3510,24 @@ rollback_check(zfs_handle_t *zhp, void *data)
> 		} else {
> 			(void) fprintf(stderr, "%s\n",
> 			    zfs_get_name(zhp));
> +			cbp->cb_younger_ds_printed++;
> 		}
> 	}
> 	zfs_close(zhp);
> +
> +	if (cbp->cb_younger_ds_printed == max_younger) {
> +		/*
> +		 * This non-recursive rollback is going to fail due to the
> +		 * presence of snapshots and/or bookmarks that are younger than
> +		 * the rollback target.
> +		 * We printed some of the offending objects, now we stop
> +		 * zfs_iter_snapshot/bookmark iteration so we can fail fast and
> +		 * avoid iterating over the rest of the younger objects
> +		 */
> +		(void) fprintf(stderr, gettext("Output limited to %d "
> +		    "snapshots/bookmarks\n"), max_younger);
> +		return (-1);
> +	}
> 	return (0);
> }
>
> @@ -3520,6 +3541,7 @@ zfs_do_rollback(int argc, char **argv)
> 	zfs_handle_t *zhp, *snap;
> 	char parentname[ZFS_MAX_DATASET_NAME_LEN];
> 	char *delim;
> +	uint64_t min_txg = 0;
>
> 	/* check options */
> 	while ((c = getopt(argc, argv, "rRf")) != -1) {
> @@ -3575,7 +3597,12 @@ zfs_do_rollback(int argc, char **argv)
> 	cb.cb_create = zfs_prop_get_int(snap, ZFS_PROP_CREATETXG);
> 	cb.cb_first = B_TRUE;
> 	cb.cb_error = 0;
> -	if ((ret = zfs_iter_snapshots(zhp, B_FALSE, rollback_check, &cb)) != 0)
> +
> +	if (cb.cb_create > 0)
> +		min_txg = cb.cb_create;
> +
> +	if ((ret = zfs_iter_snapshots(zhp, B_FALSE, rollback_check, &cb,
> +	    min_txg, 0)) != 0)
> 		goto out;
> 	if ((ret = zfs_iter_bookmarks(zhp, rollback_check, &cb)) != 0)
> 		goto out;
>
> Modified: head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
> ==============================================================================
> --- head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h	Sat Oct 26 17:10:27 2019	(r354115)
> +++ head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h	Sat Oct 26 17:11:02 2019	(r354116)
> @@ -28,7 +28,7 @@
>  * Copyright (c) 2013 Steven Hartland. All rights reserved.
>  * Copyright (c) 2014 Integros [integros.com]
>  * Copyright 2016 Nexenta Systems, Inc.
> - * Copyright (c) 2017 Datto Inc.
> + * Copyright (c) 2019 Datto Inc.
>  */
>
> #ifndef	_LIBZFS_H
> @@ -570,8 +570,10 @@ extern int zfs_iter_root(libzfs_handle_t *, zfs_iter_f
> extern int zfs_iter_children(zfs_handle_t *, zfs_iter_f, void *);
> extern int zfs_iter_dependents(zfs_handle_t *, boolean_t, zfs_iter_f, void *);
> extern int zfs_iter_filesystems(zfs_handle_t *, zfs_iter_f, void *);
> -extern int zfs_iter_snapshots(zfs_handle_t *, boolean_t, zfs_iter_f, void *);
> -extern int zfs_iter_snapshots_sorted(zfs_handle_t *, zfs_iter_f, void *);
> +extern int zfs_iter_snapshots(zfs_handle_t *, boolean_t, zfs_iter_f, void *,
> +    uint64_t, uint64_t);
> +extern int zfs_iter_snapshots_sorted(zfs_handle_t *, zfs_iter_f, void *,
> +    uint64_t, uint64_t);
> extern int zfs_iter_snapspec(zfs_handle_t *, const char *, zfs_iter_f, void *);
> extern int zfs_iter_bookmarks(zfs_handle_t *, zfs_iter_f, void *);
>
>
> Modified: head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
> ==============================================================================
> --- head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c	Sat Oct 26 17:10:27 2019	(r354115)
> +++ head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c	Sat Oct 26 17:11:02 2019	(r354116)
> @@ -31,6 +31,7 @@
>  * Copyright 2017 Nexenta Systems, Inc.
>  * Copyright 2016 Igor Kozhukhov <ikozhukhov at gmail.com>
>  * Copyright 2017-2018 RackTop Systems.
> + * Copyright (c) 2019 Datto Inc.
>  */
>
> #include <ctype.h>
> @@ -4163,7 +4164,7 @@ zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap, bo
> 	rollback_data_t cb = { 0 };
> 	int err;
> 	boolean_t restore_resv = 0;
> -	uint64_t old_volsize = 0, new_volsize;
> +	uint64_t min_txg = 0, old_volsize = 0, new_volsize;
> 	zfs_prop_t resv_prop;
>
> 	assert(zhp->zfs_type == ZFS_TYPE_FILESYSTEM ||
> @@ -4175,7 +4176,13 @@ zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap, bo
> 	cb.cb_force = force;
> 	cb.cb_target = snap->zfs_name;
> 	cb.cb_create = zfs_prop_get_int(snap, ZFS_PROP_CREATETXG);
> -	(void) zfs_iter_snapshots(zhp, B_FALSE, rollback_destroy, &cb);
> +
> +	if (cb.cb_create > 0)
> +		min_txg = cb.cb_create;
> +
> +	(void) zfs_iter_snapshots(zhp, B_FALSE, rollback_destroy, &cb,
> +	    min_txg, 0);
> +
> 	(void) zfs_iter_bookmarks(zhp, rollback_destroy, &cb);
>
> 	if (cb.cb_error)
>
> Modified: head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c
> ==============================================================================
> --- head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c	Sat Oct 26 17:10:27 2019	(r354115)
> +++ head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c	Sat Oct 26 17:11:02 2019	(r354116)
> @@ -24,6 +24,7 @@
>  * Copyright (c) 2013, 2015 by Delphix. All rights reserved.
>  * Copyright (c) 2012 Pawel Jakub Dawidek. All rights reserved.
>  * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
> + * Copyright (c) 2019 Datto Inc.
>  */
>
> #include <stdio.h>
> @@ -139,11 +140,12 @@ zfs_iter_filesystems(zfs_handle_t *zhp, zfs_iter_f fun
>  */
> 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)
> @@ -153,6 +155,24 @@ zfs_iter_snapshots(zfs_handle_t *zhp, boolean_t simple
>
> 	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) {
>
> @@ -165,10 +185,12 @@ zfs_iter_snapshots(zfs_handle_t *zhp, boolean_t simple
>
> 		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);
> }
>
> @@ -276,7 +298,8 @@ zfs_snapshot_compare(const void *larg, const void *rar
> }
>
> 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;
> @@ -286,7 +309,8 @@ zfs_iter_snapshots_sorted(zfs_handle_t *zhp, zfs_iter_
> 	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);
> @@ -389,7 +413,7 @@ zfs_iter_snapspec(zfs_handle_t *fs_zhp, const char *sp
> 			}
>
> 			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 ||
> @@ -429,7 +453,7 @@ zfs_iter_children(zfs_handle_t *zhp, zfs_iter_f func,
> {
> 	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));
> @@ -495,7 +519,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;
> 	}
>
> Modified: head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c
> ==============================================================================
> --- head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c	Sat Oct 26 17:10:27 2019	(r354115)
> +++ head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c	Sat Oct 26 17:11:02 2019	(r354116)
> @@ -28,6 +28,7 @@
>  * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved.
>  * Copyright (c) 2014 Integros [integros.com]
>  * Copyright 2016 Igor Kozhukhov <ikozhukhov at gmail.com>
> + * Copyright (c) 2019 Datto Inc.
>  */
>
> #include <assert.h>
> @@ -612,6 +613,7 @@ typedef struct send_data {
> 	const char *tosnap;
> 	boolean_t recursive;
> 	boolean_t verbose;
> +	boolean_t replicate;
>
> 	/*
> 	 * The header nvlist is of the following format:
> @@ -789,6 +791,7 @@ send_iterate_fs(zfs_handle_t *zhp, void *arg)
> 	send_data_t *sd = arg;
> 	nvlist_t *nvfs, *nv;
> 	int rv = 0;
> +	uint64_t min_txg = 0, max_txg = 0;
> 	uint64_t parent_fromsnap_guid_save = sd->parent_fromsnap_guid;
> 	uint64_t fromsnap_txg_save = sd->fromsnap_txg;
> 	uint64_t tosnap_txg_save = sd->tosnap_txg;
> @@ -832,10 +835,10 @@ send_iterate_fs(zfs_handle_t *zhp, void *arg)
> 		goto out;
> 	}
>
> -	VERIFY(0 == nvlist_alloc(&nvfs, NV_UNIQUE_NAME, 0));
> -	VERIFY(0 == nvlist_add_string(nvfs, "name", zhp->zfs_name));
> -	VERIFY(0 == nvlist_add_uint64(nvfs, "parentfromsnap",
> -	    sd->parent_fromsnap_guid));
> +	nvfs = fnvlist_alloc();
> +	fnvlist_add_string(nvfs, "name", zhp->zfs_name);
> +	fnvlist_add_uint64(nvfs, "parentfromsnap",
> +	    sd->parent_fromsnap_guid);
>
> 	if (zhp->zfs_dmustats.dds_origin[0]) {
> 		zfs_handle_t *origin = zfs_open(zhp->zfs_hdl,
> @@ -855,14 +858,19 @@ send_iterate_fs(zfs_handle_t *zhp, void *arg)
> 	nvlist_free(nv);
>
> 	/* iterate over snaps, and set sd->parent_fromsnap_guid */
> +	if (!sd->replicate && fromsnap_txg != 0)
> +		min_txg = fromsnap_txg;
> +	if (!sd->replicate && tosnap_txg != 0)
> +		max_txg = tosnap_txg;
> 	sd->parent_fromsnap_guid = 0;
> 	VERIFY(0 == nvlist_alloc(&sd->parent_snaps, NV_UNIQUE_NAME, 0));
> 	VERIFY(0 == nvlist_alloc(&sd->snapprops, NV_UNIQUE_NAME, 0));
> -	(void) zfs_iter_snapshots_sorted(zhp, send_iterate_snap, sd);
> +	(void) zfs_iter_snapshots_sorted(zhp, send_iterate_snap, sd,
> +	    min_txg, max_txg);
> 	VERIFY(0 == nvlist_add_nvlist(nvfs, "snaps", sd->parent_snaps));
> 	VERIFY(0 == nvlist_add_nvlist(nvfs, "snapprops", sd->snapprops));
> -	nvlist_free(sd->parent_snaps);
> -	nvlist_free(sd->snapprops);
> +	fnvlist_free(sd->parent_snaps);
> +	fnvlist_free(sd->snapprops);
>
> 	/* add this fs to nvlist */
> 	(void) snprintf(guidstring, sizeof (guidstring),
> @@ -886,11 +894,12 @@ out:
> static int
> gather_nvlist(libzfs_handle_t *hdl, const char *fsname, const char *fromsnap,
>     const char *tosnap, boolean_t recursive, boolean_t verbose,
> -    nvlist_t **nvlp, avl_tree_t **avlp)
> +    boolean_t replicate, nvlist_t **nvlp, avl_tree_t **avlp)
> {
> 	zfs_handle_t *zhp;
> -	send_data_t sd = { 0 };
> 	int error;
> +	uint64_t min_txg = 0, max_txg = 0;
> +	send_data_t sd = { 0 };
>
> 	zhp = zfs_open(hdl, fsname, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
> 	if (zhp == NULL)
> @@ -902,6 +911,7 @@ gather_nvlist(libzfs_handle_t *hdl, const char *fsname
> 	sd.tosnap = tosnap;
> 	sd.recursive = recursive;
> 	sd.verbose = verbose;
> +	sd.replicate = replicate;
>
> 	if ((error = send_iterate_fs(zhp, &sd)) != 0) {
> 		nvlist_free(sd.fss);
> @@ -1338,6 +1348,7 @@ static int
> dump_filesystem(zfs_handle_t *zhp, void *arg)
> {
> 	int rv = 0;
> +	uint64_t min_txg = 0, max_txg = 0;
> 	send_dump_data_t *sdd = arg;
> 	boolean_t missingfrom = B_FALSE;
> 	zfs_cmd_t zc = { 0 };
> @@ -1373,7 +1384,15 @@ dump_filesystem(zfs_handle_t *zhp, void *arg)
> 	if (sdd->fromsnap == NULL || missingfrom)
> 		sdd->seenfrom = B_TRUE;
>
> -	rv = zfs_iter_snapshots_sorted(zhp, dump_snapshot, arg);
> +	if (!sdd->replicate && sdd->fromsnap != NULL)
> +		min_txg = get_snap_txg(zhp->zfs_hdl, zhp->zfs_name,
> +		    sdd->fromsnap);
> +	if (!sdd->replicate && sdd->tosnap != NULL)
> +		max_txg = get_snap_txg(zhp->zfs_hdl, zhp->zfs_name,
> +		    sdd->tosnap);
> +
> +	rv = zfs_iter_snapshots_sorted(zhp, dump_snapshot, arg,
> +	    min_txg, max_txg);
> 	if (!sdd->seenfrom) {
> 		(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
> 		    "WARNING: could not send %s@%s:\n"
> @@ -1834,7 +1853,7 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, cons
>
> 			err = gather_nvlist(zhp->zfs_hdl, zhp->zfs_name,
> 			    fromsnap, tosnap, flags->replicate, flags->verbose,
> -			    &fss, &fsavl);
> +			    flags->replicate, &fss, &fsavl);
> 			if (err)
> 				goto err_out;
> 			VERIFY(0 == nvlist_add_nvlist(hdrnv, "fss", fss));
> @@ -2477,7 +2496,7 @@ again:
> 	VERIFY(0 == nvlist_alloc(&deleted, NV_UNIQUE_NAME, 0));
>
> 	if ((error = gather_nvlist(hdl, tofs, fromsnap, NULL,
> -	    recursive, B_FALSE, &local_nv, &local_avl)) != 0)
> +	    recursive, B_FALSE, B_FALSE, &local_nv, &local_avl)) != 0)
> 		return (error);
>
> 	/*
> @@ -3554,7 +3573,7 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const
> 		 */
> 		*cp = '\0';
> 		if (gather_nvlist(hdl, zc.zc_value, NULL, NULL, B_FALSE,
> -		    B_FALSE, &local_nv, &local_avl) == 0) {
> +		    B_FALSE, B_FALSE, &local_nv, &local_avl) == 0) {
> 			*cp = '@';
> 			fs = fsavl_find(local_avl, drrb->drr_toguid, NULL);
> 			fsavl_destroy(local_avl);
>
> Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
> ==============================================================================
> --- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c	Sat Oct 26 17:10:27 2019	(r354115)
> +++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c	Sat Oct 26 17:11:02 2019	(r354116)
> @@ -33,7 +33,7 @@
>  * Copyright (c) 2014 Integros [integros.com]
>  * Copyright 2016 Toomas Soome <tsoome at me.com>
>  * Copyright 2017 RackTop Systems.
> - * Copyright (c) 2017 Datto Inc.
> + * Copyright (c) 2019 Datto Inc.
>  */
>
> /*
> @@ -2345,7 +2345,8 @@ dataset_name_hidden(const char *name)
>  * 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 filesystem
> @@ -2414,9 +2415,24 @@ 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) {
> 		return (error == ENOENT ? ESRCH : error);
> @@ -2432,26 +2448,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);
>
> Modified: head/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h
> ==============================================================================
> --- head/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h	Sat Oct 26 17:10:27 2019	(r354115)
> +++ head/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h	Sat Oct 26 17:11:02 2019	(r354116)
> @@ -26,7 +26,7 @@
>  * Copyright (c) 2012, Martin Matuska <mm at FreeBSD.org>. All rights reserved.
>  * Copyright (c) 2014 Integros [integros.com]
>  * Copyright 2017 Joyent, Inc.
> - * Copyright (c) 2017 Datto Inc.
> + * Copyright (c) 2019 Datto Inc.
>  */
>
> /* Portions Copyright 2010 Robert Milkowski */
> @@ -1122,6 +1122,13 @@ typedef enum {
> #define	ZCP_MAX_INSTRLIMIT	(10 * ZCP_DEFAULT_INSTRLIMIT)
> #define	ZCP_DEFAULT_MEMLIMIT	(10 * 1024 * 1024)
> #define	ZCP_MAX_MEMLIMIT	(10 * ZCP_DEFAULT_MEMLIMIT)
> +
> +/*
> + * nvlist name constants. Facilitate restricting snapshot iteration range for
> + * the "list next snapshot" ioctl
> + */
> +#define	SNAP_ITER_MIN_TXG	"snap_iter_min_txg"
> +#define	SNAP_ITER_MAX_TXG	"snap_iter_max_txg"
>
> /*
>  * Sysevent payload members.  ZFS will generate the following sysevents with the
> _______________________________________________
> svn-src-all at freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/svn-src-all
> To unsubscribe, send any mail to "svn-src-all-unsubscribe at freebsd.org"
>


More information about the svn-src-head mailing list