xref: /onnv-gate/usr/src/cmd/smbsrv/smbd/smbd_vss.c (revision 9231:152b6e0d9b1a)
18474SJose.Borrego@Sun.COM /*
28474SJose.Borrego@Sun.COM  * CDDL HEADER START
38474SJose.Borrego@Sun.COM  *
48474SJose.Borrego@Sun.COM  * The contents of this file are subject to the terms of the
58474SJose.Borrego@Sun.COM  * Common Development and Distribution License (the "License").
68474SJose.Borrego@Sun.COM  * You may not use this file except in compliance with the License.
78474SJose.Borrego@Sun.COM  *
88474SJose.Borrego@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
98474SJose.Borrego@Sun.COM  * or http://www.opensolaris.org/os/licensing.
108474SJose.Borrego@Sun.COM  * See the License for the specific language governing permissions
118474SJose.Borrego@Sun.COM  * and limitations under the License.
128474SJose.Borrego@Sun.COM  *
138474SJose.Borrego@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
148474SJose.Borrego@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
158474SJose.Borrego@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
168474SJose.Borrego@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
178474SJose.Borrego@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
188474SJose.Borrego@Sun.COM  *
198474SJose.Borrego@Sun.COM  * CDDL HEADER END
208474SJose.Borrego@Sun.COM  */
218474SJose.Borrego@Sun.COM /*
228474SJose.Borrego@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
238474SJose.Borrego@Sun.COM  * Use is subject to license terms.
248474SJose.Borrego@Sun.COM  */
258474SJose.Borrego@Sun.COM 
268474SJose.Borrego@Sun.COM #include <synch.h>
278474SJose.Borrego@Sun.COM #include <pthread.h>
288474SJose.Borrego@Sun.COM #include <unistd.h>
298474SJose.Borrego@Sun.COM #include <string.h>
308474SJose.Borrego@Sun.COM #include <strings.h>
318474SJose.Borrego@Sun.COM #include <sys/errno.h>
328871Samw@Sun.COM #include <libzfs.h>
338474SJose.Borrego@Sun.COM 
348474SJose.Borrego@Sun.COM #include <smbsrv/libsmb.h>
358474SJose.Borrego@Sun.COM #include <smbsrv/libsmbrdr.h>
368474SJose.Borrego@Sun.COM #include <smbsrv/libsmbns.h>
378474SJose.Borrego@Sun.COM #include <smbsrv/libmlsvc.h>
388474SJose.Borrego@Sun.COM #include <smbsrv/smbinfo.h>
398474SJose.Borrego@Sun.COM #include <smbsrv/ntstatus.h>
408474SJose.Borrego@Sun.COM #include "smbd.h"
418474SJose.Borrego@Sun.COM 
428474SJose.Borrego@Sun.COM /*
438474SJose.Borrego@Sun.COM  * This file supports three basic functions that all use the
448474SJose.Borrego@Sun.COM  * the zfs_iter_snapshots function to get the snapshot info
458474SJose.Borrego@Sun.COM  * from ZFS.  If the filesystem is not ZFS, the an error is sent
468474SJose.Borrego@Sun.COM  * to the caller (door functions in this case) with the count of
478474SJose.Borrego@Sun.COM  * zero in the case of smbd_vss_get_count.  Each function
488474SJose.Borrego@Sun.COM  * is expecting a path that is the root of the dataset.
498474SJose.Borrego@Sun.COM  * The basic idea is to define a structure for the data and
508474SJose.Borrego@Sun.COM  * an iterator function that will be called for every snapshot
518474SJose.Borrego@Sun.COM  * in the dataset that was opened.  The iterator function gets
528474SJose.Borrego@Sun.COM  * a zfs_handle_t(that needs to be closed) for the snapshot
538474SJose.Borrego@Sun.COM  * and a pointer to the structure of data defined passed to it.
548474SJose.Borrego@Sun.COM  * If the iterator function returns a non-zero value, no more
558474SJose.Borrego@Sun.COM  * snapshots will be processed.  There is no guarantee in the
568474SJose.Borrego@Sun.COM  * order in which the snapshots are processed.
578474SJose.Borrego@Sun.COM  *
588474SJose.Borrego@Sun.COM  * The structure of this file is:
598474SJose.Borrego@Sun.COM  * Three structures that are used between the iterator functions
608474SJose.Borrego@Sun.COM  * and "main" functions
618474SJose.Borrego@Sun.COM  * The 3 "main" functions
628474SJose.Borrego@Sun.COM  * Support functions
638474SJose.Borrego@Sun.COM  * The 3 iterator functions
648474SJose.Borrego@Sun.COM  */
658474SJose.Borrego@Sun.COM 
66*9231SAfshin.Ardakani@Sun.COM /*
67*9231SAfshin.Ardakani@Sun.COM  * The maximum number of snapshots returned per request.
68*9231SAfshin.Ardakani@Sun.COM  */
69*9231SAfshin.Ardakani@Sun.COM #define	SMBD_VSS_SNAPSHOT_MAX	725
70*9231SAfshin.Ardakani@Sun.COM 
718474SJose.Borrego@Sun.COM static void smbd_vss_time2gmttoken(time_t time, char *gmttoken);
728474SJose.Borrego@Sun.COM static int smbd_vss_cmp_time(const void *a, const void *b);
738474SJose.Borrego@Sun.COM static int smbd_vss_iterate_count(zfs_handle_t *zhp, void *data);
748474SJose.Borrego@Sun.COM static int smbd_vss_iterate_get_uint64_date(zfs_handle_t *zhp, void *data);
758474SJose.Borrego@Sun.COM static int smbd_vss_iterate_map_gmttoken(zfs_handle_t *zhp, void *data);
768474SJose.Borrego@Sun.COM 
778474SJose.Borrego@Sun.COM typedef struct smbd_vss_count {
788474SJose.Borrego@Sun.COM 	int vc_count;
798474SJose.Borrego@Sun.COM } smbd_vss_count_t;
808474SJose.Borrego@Sun.COM 
818474SJose.Borrego@Sun.COM /*
828474SJose.Borrego@Sun.COM  * gd_count how many @GMT tokens are expected
838474SJose.Borrego@Sun.COM  * gd_return_count how many @GMT tokens are being returned
848474SJose.Borrego@Sun.COM  * gd_gmt_array array of the @GMT token with max size of gd_count
858474SJose.Borrego@Sun.COM  */
868474SJose.Borrego@Sun.COM typedef struct smbd_vss_get_uint64_date {
878474SJose.Borrego@Sun.COM 	int gd_count;
888474SJose.Borrego@Sun.COM 	int gd_return_count;
898474SJose.Borrego@Sun.COM 	uint64_t *gd_gmt_array;
908474SJose.Borrego@Sun.COM } smbd_vss_get_uint64_date_t;
918474SJose.Borrego@Sun.COM 
928474SJose.Borrego@Sun.COM typedef struct smbd_vss_map_gmttoken {
938474SJose.Borrego@Sun.COM 	char *mg_gmttoken;
948474SJose.Borrego@Sun.COM 	char *mg_snapname;
958474SJose.Borrego@Sun.COM } smbd_vss_map_gmttoken_t;
968474SJose.Borrego@Sun.COM 
978474SJose.Borrego@Sun.COM 
988474SJose.Borrego@Sun.COM /*
998474SJose.Borrego@Sun.COM  * path - path of the dataset
1008474SJose.Borrego@Sun.COM  * count - return value of the number of snapshots for the dataset
1018474SJose.Borrego@Sun.COM  */
1028474SJose.Borrego@Sun.COM int
1038871Samw@Sun.COM smbd_vss_get_count(const char *path, uint32_t *count)
1048474SJose.Borrego@Sun.COM {
1058871Samw@Sun.COM 	char dataset[MAXPATHLEN];
1068871Samw@Sun.COM 	libzfs_handle_t *libhd;
1078871Samw@Sun.COM 	zfs_handle_t *zfshd;
1088474SJose.Borrego@Sun.COM 	smbd_vss_count_t vss_count;
1098474SJose.Borrego@Sun.COM 
1108474SJose.Borrego@Sun.COM 	bzero(&vss_count, sizeof (smbd_vss_count_t));
1118474SJose.Borrego@Sun.COM 	*count = 0;
1128474SJose.Borrego@Sun.COM 
1138871Samw@Sun.COM 	if (smb_getdataset(path, dataset, MAXPATHLEN) != 0)
1148871Samw@Sun.COM 		return (-1);
1158474SJose.Borrego@Sun.COM 
1168871Samw@Sun.COM 	if ((libhd = libzfs_init()) == NULL)
1178871Samw@Sun.COM 		return (-1);
1188474SJose.Borrego@Sun.COM 
1198871Samw@Sun.COM 	if ((zfshd = zfs_open(libhd, dataset, ZFS_TYPE_DATASET)) == NULL) {
1208871Samw@Sun.COM 		libzfs_fini(libhd);
1218474SJose.Borrego@Sun.COM 		return (-1);
1228474SJose.Borrego@Sun.COM 	}
1238474SJose.Borrego@Sun.COM 
1248871Samw@Sun.COM 	(void) zfs_iter_snapshots(zfshd, smbd_vss_iterate_count,
1258474SJose.Borrego@Sun.COM 	    (void *)&vss_count);
1268474SJose.Borrego@Sun.COM 
127*9231SAfshin.Ardakani@Sun.COM 	if (vss_count.vc_count > SMBD_VSS_SNAPSHOT_MAX)
128*9231SAfshin.Ardakani@Sun.COM 		vss_count.vc_count = SMBD_VSS_SNAPSHOT_MAX;
129*9231SAfshin.Ardakani@Sun.COM 
1308474SJose.Borrego@Sun.COM 	*count = vss_count.vc_count;
1318871Samw@Sun.COM 	zfs_close(zfshd);
1328871Samw@Sun.COM 	libzfs_fini(libhd);
1338474SJose.Borrego@Sun.COM 	return (0);
1348474SJose.Borrego@Sun.COM }
1358474SJose.Borrego@Sun.COM 
1368474SJose.Borrego@Sun.COM /*
1378474SJose.Borrego@Sun.COM  * path - is the path of the dataset
1388474SJose.Borrego@Sun.COM  * count - is the maxium number of GMT tokens allowed to be returned
1398474SJose.Borrego@Sun.COM  * return_count - is how many should be returned
1408474SJose.Borrego@Sun.COM  * num_gmttokens - how many gmttokens in gmttokenp (0 if error)
1418474SJose.Borrego@Sun.COM  * gmttokenp - array of @GMT tokens (even if zero, elements still need
1428474SJose.Borrego@Sun.COM  * to be freed)
1438474SJose.Borrego@Sun.COM  */
1448474SJose.Borrego@Sun.COM 
1458474SJose.Borrego@Sun.COM void
1468871Samw@Sun.COM smbd_vss_get_snapshots(const char *path, uint32_t count,
1478871Samw@Sun.COM     uint32_t *return_count, uint32_t *num_gmttokens, char **gmttokenp)
1488474SJose.Borrego@Sun.COM {
1498871Samw@Sun.COM 	char dataset[MAXPATHLEN];
1508871Samw@Sun.COM 	libzfs_handle_t *libhd;
1518871Samw@Sun.COM 	zfs_handle_t *zfshd;
1528474SJose.Borrego@Sun.COM 	smbd_vss_get_uint64_date_t vss_uint64_date;
1538474SJose.Borrego@Sun.COM 	int i;
1548474SJose.Borrego@Sun.COM 	uint64_t *timep;
1558474SJose.Borrego@Sun.COM 
1568474SJose.Borrego@Sun.COM 	*return_count = 0;
1578474SJose.Borrego@Sun.COM 	*num_gmttokens = 0;
1588474SJose.Borrego@Sun.COM 
159*9231SAfshin.Ardakani@Sun.COM 	if (count == 0)
1608871Samw@Sun.COM 		return;
1618474SJose.Borrego@Sun.COM 
162*9231SAfshin.Ardakani@Sun.COM 	if (count > SMBD_VSS_SNAPSHOT_MAX)
163*9231SAfshin.Ardakani@Sun.COM 		count = SMBD_VSS_SNAPSHOT_MAX;
1648474SJose.Borrego@Sun.COM 
1658474SJose.Borrego@Sun.COM 	vss_uint64_date.gd_count = count;
1668474SJose.Borrego@Sun.COM 	vss_uint64_date.gd_return_count = 0;
1678474SJose.Borrego@Sun.COM 	vss_uint64_date.gd_gmt_array = malloc(count * sizeof (uint64_t));
168*9231SAfshin.Ardakani@Sun.COM 	if (vss_uint64_date.gd_gmt_array == NULL)
169*9231SAfshin.Ardakani@Sun.COM 		return;
1708474SJose.Borrego@Sun.COM 
171*9231SAfshin.Ardakani@Sun.COM 	if (smb_getdataset(path, dataset, MAXPATHLEN) != 0) {
172*9231SAfshin.Ardakani@Sun.COM 		free(vss_uint64_date.gd_gmt_array);
173*9231SAfshin.Ardakani@Sun.COM 		return;
174*9231SAfshin.Ardakani@Sun.COM 	}
1758474SJose.Borrego@Sun.COM 
176*9231SAfshin.Ardakani@Sun.COM 	if ((libhd = libzfs_init()) == NULL) {
177*9231SAfshin.Ardakani@Sun.COM 		free(vss_uint64_date.gd_gmt_array);
178*9231SAfshin.Ardakani@Sun.COM 		return;
179*9231SAfshin.Ardakani@Sun.COM 	}
1808474SJose.Borrego@Sun.COM 
181*9231SAfshin.Ardakani@Sun.COM 	if ((zfshd = zfs_open(libhd, dataset, ZFS_TYPE_DATASET)) == NULL) {
1828474SJose.Borrego@Sun.COM 		free(vss_uint64_date.gd_gmt_array);
183*9231SAfshin.Ardakani@Sun.COM 		libzfs_fini(libhd);
184*9231SAfshin.Ardakani@Sun.COM 		return;
1858474SJose.Borrego@Sun.COM 	}
1868474SJose.Borrego@Sun.COM 
187*9231SAfshin.Ardakani@Sun.COM 	(void) zfs_iter_snapshots(zfshd, smbd_vss_iterate_get_uint64_date,
188*9231SAfshin.Ardakani@Sun.COM 	    (void *)&vss_uint64_date);
189*9231SAfshin.Ardakani@Sun.COM 
190*9231SAfshin.Ardakani@Sun.COM 	*num_gmttokens = vss_uint64_date.gd_return_count;
191*9231SAfshin.Ardakani@Sun.COM 	*return_count = vss_uint64_date.gd_return_count;
192*9231SAfshin.Ardakani@Sun.COM 
193*9231SAfshin.Ardakani@Sun.COM 	/*
194*9231SAfshin.Ardakani@Sun.COM 	 * Sort the list since neither zfs nor the client sorts it.
195*9231SAfshin.Ardakani@Sun.COM 	 */
196*9231SAfshin.Ardakani@Sun.COM 	qsort((char *)vss_uint64_date.gd_gmt_array,
197*9231SAfshin.Ardakani@Sun.COM 	    vss_uint64_date.gd_return_count,
198*9231SAfshin.Ardakani@Sun.COM 	    sizeof (uint64_t), smbd_vss_cmp_time);
199*9231SAfshin.Ardakani@Sun.COM 
200*9231SAfshin.Ardakani@Sun.COM 	timep = vss_uint64_date.gd_gmt_array;
201*9231SAfshin.Ardakani@Sun.COM 
202*9231SAfshin.Ardakani@Sun.COM 	for (i = 0; i < vss_uint64_date.gd_return_count; i++) {
203*9231SAfshin.Ardakani@Sun.COM 		*gmttokenp = malloc(SMB_VSS_GMT_SIZE);
204*9231SAfshin.Ardakani@Sun.COM 
205*9231SAfshin.Ardakani@Sun.COM 		if (*gmttokenp)
206*9231SAfshin.Ardakani@Sun.COM 			smbd_vss_time2gmttoken(*timep, *gmttokenp);
207*9231SAfshin.Ardakani@Sun.COM 		else
208*9231SAfshin.Ardakani@Sun.COM 			vss_uint64_date.gd_return_count = 0;
209*9231SAfshin.Ardakani@Sun.COM 
210*9231SAfshin.Ardakani@Sun.COM 		timep++;
211*9231SAfshin.Ardakani@Sun.COM 		gmttokenp++;
212*9231SAfshin.Ardakani@Sun.COM 	}
213*9231SAfshin.Ardakani@Sun.COM 
214*9231SAfshin.Ardakani@Sun.COM 	free(vss_uint64_date.gd_gmt_array);
2158871Samw@Sun.COM 	zfs_close(zfshd);
2168871Samw@Sun.COM 	libzfs_fini(libhd);
2178474SJose.Borrego@Sun.COM }
2188474SJose.Borrego@Sun.COM 
2198474SJose.Borrego@Sun.COM /*
2208474SJose.Borrego@Sun.COM  * path - path of the dataset for the operation
2218474SJose.Borrego@Sun.COM  * gmttoken - the @GMT token to be looked up
2228474SJose.Borrego@Sun.COM  * snapname - the snapshot name to be returned
2238474SJose.Borrego@Sun.COM  *
2248474SJose.Borrego@Sun.COM  * Here we are going to get the snapshot name from the @GMT token
2258474SJose.Borrego@Sun.COM  * The snapname returned by ZFS is : <dataset name>@<snapshot name>
2268474SJose.Borrego@Sun.COM  * So we are going to make sure there is the @ symbol in
2278474SJose.Borrego@Sun.COM  * the right place and then just return the snapshot name
2288474SJose.Borrego@Sun.COM  */
2298474SJose.Borrego@Sun.COM int
2308871Samw@Sun.COM smbd_vss_map_gmttoken(const char *path, char *gmttoken, char *snapname)
2318474SJose.Borrego@Sun.COM {
2328871Samw@Sun.COM 	char dataset[MAXPATHLEN];
2338871Samw@Sun.COM 	libzfs_handle_t *libhd;
2348871Samw@Sun.COM 	zfs_handle_t *zfshd;
2358474SJose.Borrego@Sun.COM 	smbd_vss_map_gmttoken_t vss_map_gmttoken;
2368871Samw@Sun.COM 	char *zsnap;
2378871Samw@Sun.COM 	const char *lsnap;
2388474SJose.Borrego@Sun.COM 
2398474SJose.Borrego@Sun.COM 	vss_map_gmttoken.mg_gmttoken = gmttoken;
2408474SJose.Borrego@Sun.COM 	vss_map_gmttoken.mg_snapname = snapname;
2418474SJose.Borrego@Sun.COM 	*snapname = '\0';
2428474SJose.Borrego@Sun.COM 
2438871Samw@Sun.COM 	if (smb_getdataset(path, dataset, MAXPATHLEN) != 0)
2448871Samw@Sun.COM 		return (-1);
2458474SJose.Borrego@Sun.COM 
2468871Samw@Sun.COM 	if ((libhd = libzfs_init()) == NULL)
2478871Samw@Sun.COM 		return (-1);
2488474SJose.Borrego@Sun.COM 
2498871Samw@Sun.COM 	if ((zfshd = zfs_open(libhd, dataset, ZFS_TYPE_DATASET)) == NULL) {
2508871Samw@Sun.COM 		libzfs_fini(libhd);
2518474SJose.Borrego@Sun.COM 		return (-1);
2528474SJose.Borrego@Sun.COM 	}
2538474SJose.Borrego@Sun.COM 
2548871Samw@Sun.COM 	(void) zfs_iter_snapshots(zfshd, smbd_vss_iterate_map_gmttoken,
2558474SJose.Borrego@Sun.COM 	    (void *)&vss_map_gmttoken);
2568474SJose.Borrego@Sun.COM 
2578474SJose.Borrego@Sun.COM 	/* compare the zfs snapshot name and the local snap name */
2588474SJose.Borrego@Sun.COM 	zsnap = snapname;
2598871Samw@Sun.COM 	lsnap = dataset;
2608474SJose.Borrego@Sun.COM 	while ((*lsnap != '\0') && (*zsnap != '\0') && (*lsnap == *zsnap)) {
2618474SJose.Borrego@Sun.COM 		zsnap++;
2628474SJose.Borrego@Sun.COM 		lsnap++;
2638474SJose.Borrego@Sun.COM 	}
2648474SJose.Borrego@Sun.COM 
2658474SJose.Borrego@Sun.COM 	/* Now we should be passed the dataset name */
2668474SJose.Borrego@Sun.COM 	if ((*zsnap == '@') && (*lsnap == '\0')) {
2678474SJose.Borrego@Sun.COM 		zsnap++;
2688474SJose.Borrego@Sun.COM 		(void) strlcpy(snapname, zsnap, MAXPATHLEN);
2698474SJose.Borrego@Sun.COM 	} else {
2708474SJose.Borrego@Sun.COM 		*snapname = '\0';
2718474SJose.Borrego@Sun.COM 	}
2728474SJose.Borrego@Sun.COM 
2738871Samw@Sun.COM 	zfs_close(zfshd);
2748871Samw@Sun.COM 	libzfs_fini(libhd);
2758474SJose.Borrego@Sun.COM 	return (0);
2768474SJose.Borrego@Sun.COM }
2778474SJose.Borrego@Sun.COM 
2788474SJose.Borrego@Sun.COM static void
2798474SJose.Borrego@Sun.COM smbd_vss_time2gmttoken(time_t time, char *gmttoken)
2808474SJose.Borrego@Sun.COM {
2818474SJose.Borrego@Sun.COM 	struct tm t;
2828474SJose.Borrego@Sun.COM 
2838474SJose.Borrego@Sun.COM 	(void) gmtime_r(&time, &t);
2848474SJose.Borrego@Sun.COM 
2858474SJose.Borrego@Sun.COM 	(void) strftime(gmttoken, SMB_VSS_GMT_SIZE,
2868474SJose.Borrego@Sun.COM 	    "@GMT-%Y.%m.%d-%H.%M.%S", &t);
2878474SJose.Borrego@Sun.COM }
2888474SJose.Borrego@Sun.COM 
2898474SJose.Borrego@Sun.COM static int
2908474SJose.Borrego@Sun.COM smbd_vss_cmp_time(const void *a, const void *b)
2918474SJose.Borrego@Sun.COM {
2928474SJose.Borrego@Sun.COM 	if (*(uint64_t *)a < *(uint64_t *)b)
2938474SJose.Borrego@Sun.COM 		return (1);
2948474SJose.Borrego@Sun.COM 	if (*(uint64_t *)a == *(uint64_t *)b)
2958474SJose.Borrego@Sun.COM 		return (0);
2968474SJose.Borrego@Sun.COM 	return (-1);
2978474SJose.Borrego@Sun.COM }
2988474SJose.Borrego@Sun.COM 
299*9231SAfshin.Ardakani@Sun.COM /*
300*9231SAfshin.Ardakani@Sun.COM  * ZFS snapshot iterator to count snapshots.
301*9231SAfshin.Ardakani@Sun.COM  * Note: libzfs expects us to close the handle.
302*9231SAfshin.Ardakani@Sun.COM  * Return 0 to continue iterating or non-zreo to terminate the iteration.
303*9231SAfshin.Ardakani@Sun.COM  */
3048474SJose.Borrego@Sun.COM static int
3058474SJose.Borrego@Sun.COM smbd_vss_iterate_count(zfs_handle_t *zhp, void *data)
3068474SJose.Borrego@Sun.COM {
307*9231SAfshin.Ardakani@Sun.COM 	smbd_vss_count_t *vss_data = data;
308*9231SAfshin.Ardakani@Sun.COM 
309*9231SAfshin.Ardakani@Sun.COM 	if (vss_data->vc_count < SMBD_VSS_SNAPSHOT_MAX) {
310*9231SAfshin.Ardakani@Sun.COM 		vss_data->vc_count++;
311*9231SAfshin.Ardakani@Sun.COM 		zfs_close(zhp);
312*9231SAfshin.Ardakani@Sun.COM 		return (0);
313*9231SAfshin.Ardakani@Sun.COM 	}
314*9231SAfshin.Ardakani@Sun.COM 
3158474SJose.Borrego@Sun.COM 	zfs_close(zhp);
316*9231SAfshin.Ardakani@Sun.COM 	return (-1);
3178474SJose.Borrego@Sun.COM }
3188474SJose.Borrego@Sun.COM 
319*9231SAfshin.Ardakani@Sun.COM /*
320*9231SAfshin.Ardakani@Sun.COM  * ZFS snapshot iterator to get snapshot creation time.
321*9231SAfshin.Ardakani@Sun.COM  * Note: libzfs expects us to close the handle.
322*9231SAfshin.Ardakani@Sun.COM  * Return 0 to continue iterating or non-zreo to terminate the iteration.
323*9231SAfshin.Ardakani@Sun.COM  */
3248474SJose.Borrego@Sun.COM static int
3258474SJose.Borrego@Sun.COM smbd_vss_iterate_get_uint64_date(zfs_handle_t *zhp, void *data)
3268474SJose.Borrego@Sun.COM {
327*9231SAfshin.Ardakani@Sun.COM 	smbd_vss_get_uint64_date_t *vss_data = data;
328*9231SAfshin.Ardakani@Sun.COM 	int count;
3298474SJose.Borrego@Sun.COM 
330*9231SAfshin.Ardakani@Sun.COM 	count = vss_data->gd_return_count;
3318474SJose.Borrego@Sun.COM 
332*9231SAfshin.Ardakani@Sun.COM 	if (count < vss_data->gd_count) {
333*9231SAfshin.Ardakani@Sun.COM 		vss_data->gd_gmt_array[count] =
3348474SJose.Borrego@Sun.COM 		    zfs_prop_get_int(zhp, ZFS_PROP_CREATION);
335*9231SAfshin.Ardakani@Sun.COM 		vss_data->gd_return_count++;
336*9231SAfshin.Ardakani@Sun.COM 		zfs_close(zhp);
337*9231SAfshin.Ardakani@Sun.COM 		return (0);
3388474SJose.Borrego@Sun.COM 	}
3398474SJose.Borrego@Sun.COM 
3408474SJose.Borrego@Sun.COM 	zfs_close(zhp);
341*9231SAfshin.Ardakani@Sun.COM 	return (-1);
3428474SJose.Borrego@Sun.COM }
3438474SJose.Borrego@Sun.COM 
344*9231SAfshin.Ardakani@Sun.COM /*
345*9231SAfshin.Ardakani@Sun.COM  * ZFS snapshot iterator to map a snapshot creation time to a token.
346*9231SAfshin.Ardakani@Sun.COM  * Note: libzfs expects us to close the handle.
347*9231SAfshin.Ardakani@Sun.COM  * Return 0 to continue iterating or non-zreo to terminate the iteration.
348*9231SAfshin.Ardakani@Sun.COM  */
3498474SJose.Borrego@Sun.COM static int
3508474SJose.Borrego@Sun.COM smbd_vss_iterate_map_gmttoken(zfs_handle_t *zhp, void *data)
3518474SJose.Borrego@Sun.COM {
352*9231SAfshin.Ardakani@Sun.COM 	smbd_vss_map_gmttoken_t *vss_data = data;
3538474SJose.Borrego@Sun.COM 	time_t time;
3548474SJose.Borrego@Sun.COM 	char gmttoken[SMB_VSS_GMT_SIZE];
3558474SJose.Borrego@Sun.COM 
3568474SJose.Borrego@Sun.COM 	time = (time_t)zfs_prop_get_int(zhp, ZFS_PROP_CREATION);
3578474SJose.Borrego@Sun.COM 	smbd_vss_time2gmttoken(time, gmttoken);
3588474SJose.Borrego@Sun.COM 
3598871Samw@Sun.COM 	if (strncmp(gmttoken, vss_data->mg_gmttoken, SMB_VSS_GMT_SIZE) == 0) {
3608474SJose.Borrego@Sun.COM 		(void) strlcpy(vss_data->mg_snapname, zfs_get_name(zhp),
3618474SJose.Borrego@Sun.COM 		    MAXPATHLEN);
3628474SJose.Borrego@Sun.COM 
363*9231SAfshin.Ardakani@Sun.COM 		/* we found a match, do not process anymore snapshots */
3648474SJose.Borrego@Sun.COM 		zfs_close(zhp);
3658474SJose.Borrego@Sun.COM 		return (-1);
3668474SJose.Borrego@Sun.COM 	}
3678474SJose.Borrego@Sun.COM 
3688474SJose.Borrego@Sun.COM 	zfs_close(zhp);
3698474SJose.Borrego@Sun.COM 	return (0);
3708474SJose.Borrego@Sun.COM }
371