xref: /illumos-gate/usr/src/cmd/smbsrv/smbd/smbd_vss.c (revision 87b81758)
189dc44ceSjose borrego /*
289dc44ceSjose borrego  * CDDL HEADER START
389dc44ceSjose borrego  *
489dc44ceSjose borrego  * The contents of this file are subject to the terms of the
589dc44ceSjose borrego  * Common Development and Distribution License (the "License").
689dc44ceSjose borrego  * You may not use this file except in compliance with the License.
789dc44ceSjose borrego  *
889dc44ceSjose borrego  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
989dc44ceSjose borrego  * or http://www.opensolaris.org/os/licensing.
1089dc44ceSjose borrego  * See the License for the specific language governing permissions
1189dc44ceSjose borrego  * and limitations under the License.
1289dc44ceSjose borrego  *
1389dc44ceSjose borrego  * When distributing Covered Code, include this CDDL HEADER in each
1489dc44ceSjose borrego  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1589dc44ceSjose borrego  * If applicable, add the following below this CDDL HEADER, with the
1689dc44ceSjose borrego  * fields enclosed by brackets "[]" replaced with your own identifying
1789dc44ceSjose borrego  * information: Portions Copyright [yyyy] [name of copyright owner]
1889dc44ceSjose borrego  *
1989dc44ceSjose borrego  * CDDL HEADER END
2089dc44ceSjose borrego  */
21148c5f43SAlan Wright 
2289dc44ceSjose borrego /*
23148c5f43SAlan Wright  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24*87b81758SJoyce McIntosh  * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
250d8fa8f8SMartin Matuska  * Copyright 2016 Martin Matuska. All rights reserved.
2689dc44ceSjose borrego  */
2789dc44ceSjose borrego 
2889dc44ceSjose borrego #include <synch.h>
2989dc44ceSjose borrego #include <pthread.h>
3089dc44ceSjose borrego #include <unistd.h>
3189dc44ceSjose borrego #include <string.h>
3289dc44ceSjose borrego #include <strings.h>
3389dc44ceSjose borrego #include <sys/errno.h>
346d57f833SAlan Wright #include <libzfs.h>
3589dc44ceSjose borrego 
3689dc44ceSjose borrego #include <smbsrv/libsmb.h>
3789dc44ceSjose borrego #include <smbsrv/libsmbns.h>
3889dc44ceSjose borrego #include <smbsrv/libmlsvc.h>
3989dc44ceSjose borrego #include <smbsrv/smbinfo.h>
4089dc44ceSjose borrego #include "smbd.h"
4189dc44ceSjose borrego 
4289dc44ceSjose borrego /*
4389dc44ceSjose borrego  * This file supports three basic functions that all use the
4489dc44ceSjose borrego  * the zfs_iter_snapshots function to get the snapshot info
4589dc44ceSjose borrego  * from ZFS.  If the filesystem is not ZFS, the an error is sent
4689dc44ceSjose borrego  * to the caller (door functions in this case) with the count of
4789dc44ceSjose borrego  * zero in the case of smbd_vss_get_count.  Each function
4889dc44ceSjose borrego  * is expecting a path that is the root of the dataset.
4989dc44ceSjose borrego  * The basic idea is to define a structure for the data and
5089dc44ceSjose borrego  * an iterator function that will be called for every snapshot
5189dc44ceSjose borrego  * in the dataset that was opened.  The iterator function gets
5289dc44ceSjose borrego  * a zfs_handle_t(that needs to be closed) for the snapshot
5389dc44ceSjose borrego  * and a pointer to the structure of data defined passed to it.
5489dc44ceSjose borrego  * If the iterator function returns a non-zero value, no more
5589dc44ceSjose borrego  * snapshots will be processed.  There is no guarantee in the
5689dc44ceSjose borrego  * order in which the snapshots are processed.
5789dc44ceSjose borrego  *
5889dc44ceSjose borrego  * The structure of this file is:
5989dc44ceSjose borrego  * Three structures that are used between the iterator functions
6089dc44ceSjose borrego  * and "main" functions
6189dc44ceSjose borrego  * The 3 "main" functions
6289dc44ceSjose borrego  * Support functions
6389dc44ceSjose borrego  * The 3 iterator functions
6489dc44ceSjose borrego  */
6589dc44ceSjose borrego 
668b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States /*
678b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * The maximum number of snapshots returned per request.
688b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  */
698b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States #define	SMBD_VSS_SNAPSHOT_MAX	725
708b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 
7189dc44ceSjose borrego static void smbd_vss_time2gmttoken(time_t time, char *gmttoken);
7289dc44ceSjose borrego static int smbd_vss_cmp_time(const void *a, const void *b);
7389dc44ceSjose borrego static int smbd_vss_iterate_count(zfs_handle_t *zhp, void *data);
7489dc44ceSjose borrego static int smbd_vss_iterate_get_uint64_date(zfs_handle_t *zhp, void *data);
7589dc44ceSjose borrego static int smbd_vss_iterate_map_gmttoken(zfs_handle_t *zhp, void *data);
7689dc44ceSjose borrego 
7789dc44ceSjose borrego typedef struct smbd_vss_count {
7889dc44ceSjose borrego 	int vc_count;
7989dc44ceSjose borrego } smbd_vss_count_t;
8089dc44ceSjose borrego 
8189dc44ceSjose borrego /*
8289dc44ceSjose borrego  * gd_count how many @GMT tokens are expected
8389dc44ceSjose borrego  * gd_return_count how many @GMT tokens are being returned
8489dc44ceSjose borrego  * gd_gmt_array array of the @GMT token with max size of gd_count
8589dc44ceSjose borrego  */
8689dc44ceSjose borrego typedef struct smbd_vss_get_uint64_date {
8789dc44ceSjose borrego 	int gd_count;
8889dc44ceSjose borrego 	int gd_return_count;
8989dc44ceSjose borrego 	uint64_t *gd_gmt_array;
9089dc44ceSjose borrego } smbd_vss_get_uint64_date_t;
9189dc44ceSjose borrego 
9289dc44ceSjose borrego typedef struct smbd_vss_map_gmttoken {
93a90cf9f2SGordon Ross 	time_t mg_snaptime;
9489dc44ceSjose borrego 	char *mg_snapname;
9589dc44ceSjose borrego } smbd_vss_map_gmttoken_t;
9689dc44ceSjose borrego 
9789dc44ceSjose borrego 
9889dc44ceSjose borrego /*
9989dc44ceSjose borrego  * path - path of the dataset
10089dc44ceSjose borrego  * count - return value of the number of snapshots for the dataset
10189dc44ceSjose borrego  */
10289dc44ceSjose borrego int
smbd_vss_get_count(const char * path,uint32_t * count)1036d57f833SAlan Wright smbd_vss_get_count(const char *path, uint32_t *count)
10489dc44ceSjose borrego {
1056d57f833SAlan Wright 	char dataset[MAXPATHLEN];
1066d57f833SAlan Wright 	libzfs_handle_t *libhd;
1076d57f833SAlan Wright 	zfs_handle_t *zfshd;
10889dc44ceSjose borrego 	smbd_vss_count_t vss_count;
10989dc44ceSjose borrego 
11089dc44ceSjose borrego 	bzero(&vss_count, sizeof (smbd_vss_count_t));
11189dc44ceSjose borrego 	*count = 0;
11289dc44ceSjose borrego 
113*87b81758SJoyce McIntosh 	if ((libhd = libzfs_init()) == NULL)
1146d57f833SAlan Wright 		return (-1);
11589dc44ceSjose borrego 
116*87b81758SJoyce McIntosh 	if (smb_getdataset(libhd, path, dataset, MAXPATHLEN) != 0) {
117*87b81758SJoyce McIntosh 		libzfs_fini(libhd);
1186d57f833SAlan Wright 		return (-1);
119*87b81758SJoyce McIntosh 	}
12089dc44ceSjose borrego 
1216d57f833SAlan Wright 	if ((zfshd = zfs_open(libhd, dataset, ZFS_TYPE_DATASET)) == NULL) {
1226d57f833SAlan Wright 		libzfs_fini(libhd);
12389dc44ceSjose borrego 		return (-1);
12489dc44ceSjose borrego 	}
12589dc44ceSjose borrego 
1260d8fa8f8SMartin Matuska 	(void) zfs_iter_snapshots(zfshd, B_FALSE, smbd_vss_iterate_count,
12789dc44ceSjose borrego 	    (void *)&vss_count);
12889dc44ceSjose borrego 
1298b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	if (vss_count.vc_count > SMBD_VSS_SNAPSHOT_MAX)
1308b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		vss_count.vc_count = SMBD_VSS_SNAPSHOT_MAX;
1318b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 
13289dc44ceSjose borrego 	*count = vss_count.vc_count;
1336d57f833SAlan Wright 	zfs_close(zfshd);
1346d57f833SAlan Wright 	libzfs_fini(libhd);
13589dc44ceSjose borrego 	return (0);
13689dc44ceSjose borrego }
13789dc44ceSjose borrego 
13889dc44ceSjose borrego /*
13989dc44ceSjose borrego  * path - is the path of the dataset
14089dc44ceSjose borrego  * count - is the maxium number of GMT tokens allowed to be returned
14189dc44ceSjose borrego  * return_count - is how many should be returned
14289dc44ceSjose borrego  * num_gmttokens - how many gmttokens in gmttokenp (0 if error)
14389dc44ceSjose borrego  * gmttokenp - array of @GMT tokens (even if zero, elements still need
14489dc44ceSjose borrego  * to be freed)
14589dc44ceSjose borrego  */
14689dc44ceSjose borrego 
14789dc44ceSjose borrego void
smbd_vss_get_snapshots(const char * path,uint32_t count,uint32_t * return_count,uint32_t * num_gmttokens,char ** gmttokenp)1486d57f833SAlan Wright smbd_vss_get_snapshots(const char *path, uint32_t count,
1496d57f833SAlan Wright     uint32_t *return_count, uint32_t *num_gmttokens, char **gmttokenp)
15089dc44ceSjose borrego {
1516d57f833SAlan Wright 	char dataset[MAXPATHLEN];
1526d57f833SAlan Wright 	libzfs_handle_t *libhd;
1536d57f833SAlan Wright 	zfs_handle_t *zfshd;
15489dc44ceSjose borrego 	smbd_vss_get_uint64_date_t vss_uint64_date;
15589dc44ceSjose borrego 	int i;
15689dc44ceSjose borrego 	uint64_t *timep;
15789dc44ceSjose borrego 
15889dc44ceSjose borrego 	*return_count = 0;
15989dc44ceSjose borrego 	*num_gmttokens = 0;
16089dc44ceSjose borrego 
1618b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	if (count == 0)
1626d57f833SAlan Wright 		return;
16389dc44ceSjose borrego 
1648b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	if (count > SMBD_VSS_SNAPSHOT_MAX)
1658b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		count = SMBD_VSS_SNAPSHOT_MAX;
1668b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 
1678b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	vss_uint64_date.gd_count = count;
1688b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	vss_uint64_date.gd_return_count = 0;
1698b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	vss_uint64_date.gd_gmt_array = malloc(count * sizeof (uint64_t));
170*87b81758SJoyce McIntosh 
1718b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	if (vss_uint64_date.gd_gmt_array == NULL)
1726d57f833SAlan Wright 		return;
17389dc44ceSjose borrego 
174*87b81758SJoyce McIntosh 	if ((libhd = libzfs_init()) == NULL) {
1758b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		free(vss_uint64_date.gd_gmt_array);
17689dc44ceSjose borrego 		return;
17789dc44ceSjose borrego 	}
17889dc44ceSjose borrego 
179*87b81758SJoyce McIntosh 	if (smb_getdataset(libhd, path, dataset, MAXPATHLEN) != 0) {
1808b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		free(vss_uint64_date.gd_gmt_array);
181*87b81758SJoyce McIntosh 		libzfs_fini(libhd);
1828b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		return;
1838b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	}
18489dc44ceSjose borrego 
1858b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	if ((zfshd = zfs_open(libhd, dataset, ZFS_TYPE_DATASET)) == NULL) {
1868b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		free(vss_uint64_date.gd_gmt_array);
1878b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		libzfs_fini(libhd);
1888b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		return;
1898b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	}
19089dc44ceSjose borrego 
1910d8fa8f8SMartin Matuska 	(void) zfs_iter_snapshots(zfshd, B_FALSE,
1920d8fa8f8SMartin Matuska 	    smbd_vss_iterate_get_uint64_date, (void *)&vss_uint64_date);
19389dc44ceSjose borrego 
1948b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	*num_gmttokens = vss_uint64_date.gd_return_count;
1958b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	*return_count = vss_uint64_date.gd_return_count;
19689dc44ceSjose borrego 
1978b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	/*
1988b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	 * Sort the list since neither zfs nor the client sorts it.
1998b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	 */
2008b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	qsort((char *)vss_uint64_date.gd_gmt_array,
2018b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	    vss_uint64_date.gd_return_count,
2028b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	    sizeof (uint64_t), smbd_vss_cmp_time);
20389dc44ceSjose borrego 
2048b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	timep = vss_uint64_date.gd_gmt_array;
20589dc44ceSjose borrego 
2068b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	for (i = 0; i < vss_uint64_date.gd_return_count; i++) {
2078b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		*gmttokenp = malloc(SMB_VSS_GMT_SIZE);
20889dc44ceSjose borrego 
2098b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		if (*gmttokenp)
2108b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 			smbd_vss_time2gmttoken(*timep, *gmttokenp);
2118b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		else
2128b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 			vss_uint64_date.gd_return_count = 0;
21389dc44ceSjose borrego 
2148b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		timep++;
2158b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		gmttokenp++;
21689dc44ceSjose borrego 	}
21789dc44ceSjose borrego 
2188b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	free(vss_uint64_date.gd_gmt_array);
2196d57f833SAlan Wright 	zfs_close(zfshd);
2206d57f833SAlan Wright 	libzfs_fini(libhd);
22189dc44ceSjose borrego }
22289dc44ceSjose borrego 
223a90cf9f2SGordon Ross static const char
224a90cf9f2SGordon Ross smbd_vss_gmttoken_fmt[] = "@GMT-%Y.%m.%d-%H.%M.%S";
225a90cf9f2SGordon Ross 
22689dc44ceSjose borrego /*
22789dc44ceSjose borrego  * path - path of the dataset for the operation
22889dc44ceSjose borrego  * gmttoken - the @GMT token to be looked up
229a90cf9f2SGordon Ross  * toktime - time_t used if gmttoken == NULL
230a90cf9f2SGordon Ross  * snapname - the snapshot name to be returned [MAXPATHLEN]
23189dc44ceSjose borrego  *
23289dc44ceSjose borrego  * Here we are going to get the snapshot name from the @GMT token
23389dc44ceSjose borrego  * The snapname returned by ZFS is : <dataset name>@<snapshot name>
23489dc44ceSjose borrego  * So we are going to make sure there is the @ symbol in
23589dc44ceSjose borrego  * the right place and then just return the snapshot name
23689dc44ceSjose borrego  */
23789dc44ceSjose borrego int
smbd_vss_map_gmttoken(const char * path,char * gmttoken,time_t toktime,char * snapname)238a90cf9f2SGordon Ross smbd_vss_map_gmttoken(const char *path, char *gmttoken, time_t toktime,
239a90cf9f2SGordon Ross 	char *snapname)
24089dc44ceSjose borrego {
2416d57f833SAlan Wright 	char dataset[MAXPATHLEN];
2426d57f833SAlan Wright 	libzfs_handle_t *libhd;
2436d57f833SAlan Wright 	zfs_handle_t *zfshd;
24489dc44ceSjose borrego 	smbd_vss_map_gmttoken_t vss_map_gmttoken;
2456d57f833SAlan Wright 	char *zsnap;
2466d57f833SAlan Wright 	const char *lsnap;
247a90cf9f2SGordon Ross 	struct tm tm;
248a90cf9f2SGordon Ross 
249a90cf9f2SGordon Ross 	if (gmttoken != NULL && *gmttoken == '@' &&
250a90cf9f2SGordon Ross 	    strptime(gmttoken, smbd_vss_gmttoken_fmt, &tm) != NULL) {
251a90cf9f2SGordon Ross 		toktime = timegm(&tm);
252a90cf9f2SGordon Ross 	}
25389dc44ceSjose borrego 
254a90cf9f2SGordon Ross 	vss_map_gmttoken.mg_snaptime = toktime;
25589dc44ceSjose borrego 	vss_map_gmttoken.mg_snapname = snapname;
25689dc44ceSjose borrego 	*snapname = '\0';
25789dc44ceSjose borrego 
258*87b81758SJoyce McIntosh 	if ((libhd = libzfs_init()) == NULL)
2596d57f833SAlan Wright 		return (-1);
26089dc44ceSjose borrego 
261*87b81758SJoyce McIntosh 	if (smb_getdataset(libhd, path, dataset, MAXPATHLEN) != 0) {
262*87b81758SJoyce McIntosh 		libzfs_fini(libhd);
2636d57f833SAlan Wright 		return (-1);
264*87b81758SJoyce McIntosh 	}
26589dc44ceSjose borrego 
2666d57f833SAlan Wright 	if ((zfshd = zfs_open(libhd, dataset, ZFS_TYPE_DATASET)) == NULL) {
2676d57f833SAlan Wright 		libzfs_fini(libhd);
26889dc44ceSjose borrego 		return (-1);
26989dc44ceSjose borrego 	}
27089dc44ceSjose borrego 
2710d8fa8f8SMartin Matuska 	(void) zfs_iter_snapshots(zfshd, B_FALSE, smbd_vss_iterate_map_gmttoken,
27289dc44ceSjose borrego 	    (void *)&vss_map_gmttoken);
27389dc44ceSjose borrego 
27489dc44ceSjose borrego 	/* compare the zfs snapshot name and the local snap name */
27589dc44ceSjose borrego 	zsnap = snapname;
2766d57f833SAlan Wright 	lsnap = dataset;
27789dc44ceSjose borrego 	while ((*lsnap != '\0') && (*zsnap != '\0') && (*lsnap == *zsnap)) {
27889dc44ceSjose borrego 		zsnap++;
27989dc44ceSjose borrego 		lsnap++;
28089dc44ceSjose borrego 	}
28189dc44ceSjose borrego 
28289dc44ceSjose borrego 	/* Now we should be passed the dataset name */
28389dc44ceSjose borrego 	if ((*zsnap == '@') && (*lsnap == '\0')) {
28489dc44ceSjose borrego 		zsnap++;
28589dc44ceSjose borrego 		(void) strlcpy(snapname, zsnap, MAXPATHLEN);
28689dc44ceSjose borrego 	} else {
28789dc44ceSjose borrego 		*snapname = '\0';
28889dc44ceSjose borrego 	}
28989dc44ceSjose borrego 
2906d57f833SAlan Wright 	zfs_close(zfshd);
2916d57f833SAlan Wright 	libzfs_fini(libhd);
29289dc44ceSjose borrego 	return (0);
29389dc44ceSjose borrego }
29489dc44ceSjose borrego 
29589dc44ceSjose borrego static void
smbd_vss_time2gmttoken(time_t time,char * gmttoken)29689dc44ceSjose borrego smbd_vss_time2gmttoken(time_t time, char *gmttoken)
29789dc44ceSjose borrego {
29889dc44ceSjose borrego 	struct tm t;
29989dc44ceSjose borrego 
30089dc44ceSjose borrego 	(void) gmtime_r(&time, &t);
30189dc44ceSjose borrego 
30289dc44ceSjose borrego 	(void) strftime(gmttoken, SMB_VSS_GMT_SIZE,
303a90cf9f2SGordon Ross 	    smbd_vss_gmttoken_fmt, &t);
30489dc44ceSjose borrego }
30589dc44ceSjose borrego 
30689dc44ceSjose borrego static int
smbd_vss_cmp_time(const void * a,const void * b)30789dc44ceSjose borrego smbd_vss_cmp_time(const void *a, const void *b)
30889dc44ceSjose borrego {
30989dc44ceSjose borrego 	if (*(uint64_t *)a < *(uint64_t *)b)
31089dc44ceSjose borrego 		return (1);
31189dc44ceSjose borrego 	if (*(uint64_t *)a == *(uint64_t *)b)
31289dc44ceSjose borrego 		return (0);
31389dc44ceSjose borrego 	return (-1);
31489dc44ceSjose borrego }
31589dc44ceSjose borrego 
3168b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States /*
3178b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * ZFS snapshot iterator to count snapshots.
3188b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * Note: libzfs expects us to close the handle.
3198b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * Return 0 to continue iterating or non-zreo to terminate the iteration.
3208b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  */
32189dc44ceSjose borrego static int
smbd_vss_iterate_count(zfs_handle_t * zhp,void * data)32289dc44ceSjose borrego smbd_vss_iterate_count(zfs_handle_t *zhp, void *data)
32389dc44ceSjose borrego {
3248b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	smbd_vss_count_t *vss_data = data;
3258b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 
3268b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	if (vss_data->vc_count < SMBD_VSS_SNAPSHOT_MAX) {
3278b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		vss_data->vc_count++;
3288b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		zfs_close(zhp);
3298b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		return (0);
3308b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	}
3318b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 
33289dc44ceSjose borrego 	zfs_close(zhp);
3338b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	return (-1);
33489dc44ceSjose borrego }
33589dc44ceSjose borrego 
3368b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States /*
3378b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * ZFS snapshot iterator to get snapshot creation time.
3388b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * Note: libzfs expects us to close the handle.
3398b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * Return 0 to continue iterating or non-zreo to terminate the iteration.
3408b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  */
34189dc44ceSjose borrego static int
smbd_vss_iterate_get_uint64_date(zfs_handle_t * zhp,void * data)34289dc44ceSjose borrego smbd_vss_iterate_get_uint64_date(zfs_handle_t *zhp, void *data)
34389dc44ceSjose borrego {
3448b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	smbd_vss_get_uint64_date_t *vss_data = data;
3458b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	int count;
34689dc44ceSjose borrego 
3478b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	count = vss_data->gd_return_count;
34889dc44ceSjose borrego 
3498b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	if (count < vss_data->gd_count) {
3508b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		vss_data->gd_gmt_array[count] =
35189dc44ceSjose borrego 		    zfs_prop_get_int(zhp, ZFS_PROP_CREATION);
3528b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		vss_data->gd_return_count++;
3538b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		zfs_close(zhp);
3548b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		return (0);
35589dc44ceSjose borrego 	}
35689dc44ceSjose borrego 
35789dc44ceSjose borrego 	zfs_close(zhp);
3588b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	return (-1);
35989dc44ceSjose borrego }
36089dc44ceSjose borrego 
3618b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States /*
3628b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * ZFS snapshot iterator to map a snapshot creation time to a token.
3638b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * Note: libzfs expects us to close the handle.
3648b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * Return 0 to continue iterating or non-zreo to terminate the iteration.
3658b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  */
36689dc44ceSjose borrego static int
smbd_vss_iterate_map_gmttoken(zfs_handle_t * zhp,void * data)36789dc44ceSjose borrego smbd_vss_iterate_map_gmttoken(zfs_handle_t *zhp, void *data)
36889dc44ceSjose borrego {
3698b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	smbd_vss_map_gmttoken_t *vss_data = data;
37089dc44ceSjose borrego 	time_t time;
37189dc44ceSjose borrego 
37289dc44ceSjose borrego 	time = (time_t)zfs_prop_get_int(zhp, ZFS_PROP_CREATION);
373a90cf9f2SGordon Ross 	if (time == vss_data->mg_snaptime) {
37489dc44ceSjose borrego 		(void) strlcpy(vss_data->mg_snapname, zfs_get_name(zhp),
37589dc44ceSjose borrego 		    MAXPATHLEN);
37689dc44ceSjose borrego 
37789dc44ceSjose borrego 		/* we found a match, do not process anymore snapshots */
3788b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		zfs_close(zhp);
37989dc44ceSjose borrego 		return (-1);
38089dc44ceSjose borrego 	}
38189dc44ceSjose borrego 
38289dc44ceSjose borrego 	zfs_close(zhp);
38389dc44ceSjose borrego 	return (0);
38489dc44ceSjose borrego }
385