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 */
21*12508Samw@Sun.COM
228474SJose.Borrego@Sun.COM /*
23*12508Samw@Sun.COM * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
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/libsmbns.h>
368474SJose.Borrego@Sun.COM #include <smbsrv/libmlsvc.h>
378474SJose.Borrego@Sun.COM #include <smbsrv/smbinfo.h>
388474SJose.Borrego@Sun.COM #include "smbd.h"
398474SJose.Borrego@Sun.COM
408474SJose.Borrego@Sun.COM /*
418474SJose.Borrego@Sun.COM * This file supports three basic functions that all use the
428474SJose.Borrego@Sun.COM * the zfs_iter_snapshots function to get the snapshot info
438474SJose.Borrego@Sun.COM * from ZFS. If the filesystem is not ZFS, the an error is sent
448474SJose.Borrego@Sun.COM * to the caller (door functions in this case) with the count of
458474SJose.Borrego@Sun.COM * zero in the case of smbd_vss_get_count. Each function
468474SJose.Borrego@Sun.COM * is expecting a path that is the root of the dataset.
478474SJose.Borrego@Sun.COM * The basic idea is to define a structure for the data and
488474SJose.Borrego@Sun.COM * an iterator function that will be called for every snapshot
498474SJose.Borrego@Sun.COM * in the dataset that was opened. The iterator function gets
508474SJose.Borrego@Sun.COM * a zfs_handle_t(that needs to be closed) for the snapshot
518474SJose.Borrego@Sun.COM * and a pointer to the structure of data defined passed to it.
528474SJose.Borrego@Sun.COM * If the iterator function returns a non-zero value, no more
538474SJose.Borrego@Sun.COM * snapshots will be processed. There is no guarantee in the
548474SJose.Borrego@Sun.COM * order in which the snapshots are processed.
558474SJose.Borrego@Sun.COM *
568474SJose.Borrego@Sun.COM * The structure of this file is:
578474SJose.Borrego@Sun.COM * Three structures that are used between the iterator functions
588474SJose.Borrego@Sun.COM * and "main" functions
598474SJose.Borrego@Sun.COM * The 3 "main" functions
608474SJose.Borrego@Sun.COM * Support functions
618474SJose.Borrego@Sun.COM * The 3 iterator functions
628474SJose.Borrego@Sun.COM */
638474SJose.Borrego@Sun.COM
649231SAfshin.Ardakani@Sun.COM /*
659231SAfshin.Ardakani@Sun.COM * The maximum number of snapshots returned per request.
669231SAfshin.Ardakani@Sun.COM */
679231SAfshin.Ardakani@Sun.COM #define SMBD_VSS_SNAPSHOT_MAX 725
689231SAfshin.Ardakani@Sun.COM
698474SJose.Borrego@Sun.COM static void smbd_vss_time2gmttoken(time_t time, char *gmttoken);
708474SJose.Borrego@Sun.COM static int smbd_vss_cmp_time(const void *a, const void *b);
718474SJose.Borrego@Sun.COM static int smbd_vss_iterate_count(zfs_handle_t *zhp, void *data);
728474SJose.Borrego@Sun.COM static int smbd_vss_iterate_get_uint64_date(zfs_handle_t *zhp, void *data);
738474SJose.Borrego@Sun.COM static int smbd_vss_iterate_map_gmttoken(zfs_handle_t *zhp, void *data);
748474SJose.Borrego@Sun.COM
758474SJose.Borrego@Sun.COM typedef struct smbd_vss_count {
768474SJose.Borrego@Sun.COM int vc_count;
778474SJose.Borrego@Sun.COM } smbd_vss_count_t;
788474SJose.Borrego@Sun.COM
798474SJose.Borrego@Sun.COM /*
808474SJose.Borrego@Sun.COM * gd_count how many @GMT tokens are expected
818474SJose.Borrego@Sun.COM * gd_return_count how many @GMT tokens are being returned
828474SJose.Borrego@Sun.COM * gd_gmt_array array of the @GMT token with max size of gd_count
838474SJose.Borrego@Sun.COM */
848474SJose.Borrego@Sun.COM typedef struct smbd_vss_get_uint64_date {
858474SJose.Borrego@Sun.COM int gd_count;
868474SJose.Borrego@Sun.COM int gd_return_count;
878474SJose.Borrego@Sun.COM uint64_t *gd_gmt_array;
888474SJose.Borrego@Sun.COM } smbd_vss_get_uint64_date_t;
898474SJose.Borrego@Sun.COM
908474SJose.Borrego@Sun.COM typedef struct smbd_vss_map_gmttoken {
918474SJose.Borrego@Sun.COM char *mg_gmttoken;
928474SJose.Borrego@Sun.COM char *mg_snapname;
938474SJose.Borrego@Sun.COM } smbd_vss_map_gmttoken_t;
948474SJose.Borrego@Sun.COM
958474SJose.Borrego@Sun.COM
968474SJose.Borrego@Sun.COM /*
978474SJose.Borrego@Sun.COM * path - path of the dataset
988474SJose.Borrego@Sun.COM * count - return value of the number of snapshots for the dataset
998474SJose.Borrego@Sun.COM */
1008474SJose.Borrego@Sun.COM int
smbd_vss_get_count(const char * path,uint32_t * count)1018871Samw@Sun.COM smbd_vss_get_count(const char *path, uint32_t *count)
1028474SJose.Borrego@Sun.COM {
1038871Samw@Sun.COM char dataset[MAXPATHLEN];
1048871Samw@Sun.COM libzfs_handle_t *libhd;
1058871Samw@Sun.COM zfs_handle_t *zfshd;
1068474SJose.Borrego@Sun.COM smbd_vss_count_t vss_count;
1078474SJose.Borrego@Sun.COM
1088474SJose.Borrego@Sun.COM bzero(&vss_count, sizeof (smbd_vss_count_t));
1098474SJose.Borrego@Sun.COM *count = 0;
1108474SJose.Borrego@Sun.COM
1118871Samw@Sun.COM if (smb_getdataset(path, dataset, MAXPATHLEN) != 0)
1128871Samw@Sun.COM return (-1);
1138474SJose.Borrego@Sun.COM
1148871Samw@Sun.COM if ((libhd = libzfs_init()) == NULL)
1158871Samw@Sun.COM return (-1);
1168474SJose.Borrego@Sun.COM
1178871Samw@Sun.COM if ((zfshd = zfs_open(libhd, dataset, ZFS_TYPE_DATASET)) == NULL) {
1188871Samw@Sun.COM libzfs_fini(libhd);
1198474SJose.Borrego@Sun.COM return (-1);
1208474SJose.Borrego@Sun.COM }
1218474SJose.Borrego@Sun.COM
1228871Samw@Sun.COM (void) zfs_iter_snapshots(zfshd, smbd_vss_iterate_count,
1238474SJose.Borrego@Sun.COM (void *)&vss_count);
1248474SJose.Borrego@Sun.COM
1259231SAfshin.Ardakani@Sun.COM if (vss_count.vc_count > SMBD_VSS_SNAPSHOT_MAX)
1269231SAfshin.Ardakani@Sun.COM vss_count.vc_count = SMBD_VSS_SNAPSHOT_MAX;
1279231SAfshin.Ardakani@Sun.COM
1288474SJose.Borrego@Sun.COM *count = vss_count.vc_count;
1298871Samw@Sun.COM zfs_close(zfshd);
1308871Samw@Sun.COM libzfs_fini(libhd);
1318474SJose.Borrego@Sun.COM return (0);
1328474SJose.Borrego@Sun.COM }
1338474SJose.Borrego@Sun.COM
1348474SJose.Borrego@Sun.COM /*
1358474SJose.Borrego@Sun.COM * path - is the path of the dataset
1368474SJose.Borrego@Sun.COM * count - is the maxium number of GMT tokens allowed to be returned
1378474SJose.Borrego@Sun.COM * return_count - is how many should be returned
1388474SJose.Borrego@Sun.COM * num_gmttokens - how many gmttokens in gmttokenp (0 if error)
1398474SJose.Borrego@Sun.COM * gmttokenp - array of @GMT tokens (even if zero, elements still need
1408474SJose.Borrego@Sun.COM * to be freed)
1418474SJose.Borrego@Sun.COM */
1428474SJose.Borrego@Sun.COM
1438474SJose.Borrego@Sun.COM void
smbd_vss_get_snapshots(const char * path,uint32_t count,uint32_t * return_count,uint32_t * num_gmttokens,char ** gmttokenp)1448871Samw@Sun.COM smbd_vss_get_snapshots(const char *path, uint32_t count,
1458871Samw@Sun.COM uint32_t *return_count, uint32_t *num_gmttokens, char **gmttokenp)
1468474SJose.Borrego@Sun.COM {
1478871Samw@Sun.COM char dataset[MAXPATHLEN];
1488871Samw@Sun.COM libzfs_handle_t *libhd;
1498871Samw@Sun.COM zfs_handle_t *zfshd;
1508474SJose.Borrego@Sun.COM smbd_vss_get_uint64_date_t vss_uint64_date;
1518474SJose.Borrego@Sun.COM int i;
1528474SJose.Borrego@Sun.COM uint64_t *timep;
1538474SJose.Borrego@Sun.COM
1548474SJose.Borrego@Sun.COM *return_count = 0;
1558474SJose.Borrego@Sun.COM *num_gmttokens = 0;
1568474SJose.Borrego@Sun.COM
1579231SAfshin.Ardakani@Sun.COM if (count == 0)
1588871Samw@Sun.COM return;
1598474SJose.Borrego@Sun.COM
1609231SAfshin.Ardakani@Sun.COM if (count > SMBD_VSS_SNAPSHOT_MAX)
1619231SAfshin.Ardakani@Sun.COM count = SMBD_VSS_SNAPSHOT_MAX;
1628474SJose.Borrego@Sun.COM
1638474SJose.Borrego@Sun.COM vss_uint64_date.gd_count = count;
1648474SJose.Borrego@Sun.COM vss_uint64_date.gd_return_count = 0;
1658474SJose.Borrego@Sun.COM vss_uint64_date.gd_gmt_array = malloc(count * sizeof (uint64_t));
1669231SAfshin.Ardakani@Sun.COM if (vss_uint64_date.gd_gmt_array == NULL)
1679231SAfshin.Ardakani@Sun.COM return;
1688474SJose.Borrego@Sun.COM
1699231SAfshin.Ardakani@Sun.COM if (smb_getdataset(path, dataset, MAXPATHLEN) != 0) {
1709231SAfshin.Ardakani@Sun.COM free(vss_uint64_date.gd_gmt_array);
1719231SAfshin.Ardakani@Sun.COM return;
1729231SAfshin.Ardakani@Sun.COM }
1738474SJose.Borrego@Sun.COM
1749231SAfshin.Ardakani@Sun.COM if ((libhd = libzfs_init()) == NULL) {
1759231SAfshin.Ardakani@Sun.COM free(vss_uint64_date.gd_gmt_array);
1769231SAfshin.Ardakani@Sun.COM return;
1779231SAfshin.Ardakani@Sun.COM }
1788474SJose.Borrego@Sun.COM
1799231SAfshin.Ardakani@Sun.COM if ((zfshd = zfs_open(libhd, dataset, ZFS_TYPE_DATASET)) == NULL) {
1808474SJose.Borrego@Sun.COM free(vss_uint64_date.gd_gmt_array);
1819231SAfshin.Ardakani@Sun.COM libzfs_fini(libhd);
1829231SAfshin.Ardakani@Sun.COM return;
1838474SJose.Borrego@Sun.COM }
1848474SJose.Borrego@Sun.COM
1859231SAfshin.Ardakani@Sun.COM (void) zfs_iter_snapshots(zfshd, smbd_vss_iterate_get_uint64_date,
1869231SAfshin.Ardakani@Sun.COM (void *)&vss_uint64_date);
1879231SAfshin.Ardakani@Sun.COM
1889231SAfshin.Ardakani@Sun.COM *num_gmttokens = vss_uint64_date.gd_return_count;
1899231SAfshin.Ardakani@Sun.COM *return_count = vss_uint64_date.gd_return_count;
1909231SAfshin.Ardakani@Sun.COM
1919231SAfshin.Ardakani@Sun.COM /*
1929231SAfshin.Ardakani@Sun.COM * Sort the list since neither zfs nor the client sorts it.
1939231SAfshin.Ardakani@Sun.COM */
1949231SAfshin.Ardakani@Sun.COM qsort((char *)vss_uint64_date.gd_gmt_array,
1959231SAfshin.Ardakani@Sun.COM vss_uint64_date.gd_return_count,
1969231SAfshin.Ardakani@Sun.COM sizeof (uint64_t), smbd_vss_cmp_time);
1979231SAfshin.Ardakani@Sun.COM
1989231SAfshin.Ardakani@Sun.COM timep = vss_uint64_date.gd_gmt_array;
1999231SAfshin.Ardakani@Sun.COM
2009231SAfshin.Ardakani@Sun.COM for (i = 0; i < vss_uint64_date.gd_return_count; i++) {
2019231SAfshin.Ardakani@Sun.COM *gmttokenp = malloc(SMB_VSS_GMT_SIZE);
2029231SAfshin.Ardakani@Sun.COM
2039231SAfshin.Ardakani@Sun.COM if (*gmttokenp)
2049231SAfshin.Ardakani@Sun.COM smbd_vss_time2gmttoken(*timep, *gmttokenp);
2059231SAfshin.Ardakani@Sun.COM else
2069231SAfshin.Ardakani@Sun.COM vss_uint64_date.gd_return_count = 0;
2079231SAfshin.Ardakani@Sun.COM
2089231SAfshin.Ardakani@Sun.COM timep++;
2099231SAfshin.Ardakani@Sun.COM gmttokenp++;
2109231SAfshin.Ardakani@Sun.COM }
2119231SAfshin.Ardakani@Sun.COM
2129231SAfshin.Ardakani@Sun.COM free(vss_uint64_date.gd_gmt_array);
2138871Samw@Sun.COM zfs_close(zfshd);
2148871Samw@Sun.COM libzfs_fini(libhd);
2158474SJose.Borrego@Sun.COM }
2168474SJose.Borrego@Sun.COM
2178474SJose.Borrego@Sun.COM /*
2188474SJose.Borrego@Sun.COM * path - path of the dataset for the operation
2198474SJose.Borrego@Sun.COM * gmttoken - the @GMT token to be looked up
2208474SJose.Borrego@Sun.COM * snapname - the snapshot name to be returned
2218474SJose.Borrego@Sun.COM *
2228474SJose.Borrego@Sun.COM * Here we are going to get the snapshot name from the @GMT token
2238474SJose.Borrego@Sun.COM * The snapname returned by ZFS is : <dataset name>@<snapshot name>
2248474SJose.Borrego@Sun.COM * So we are going to make sure there is the @ symbol in
2258474SJose.Borrego@Sun.COM * the right place and then just return the snapshot name
2268474SJose.Borrego@Sun.COM */
2278474SJose.Borrego@Sun.COM int
smbd_vss_map_gmttoken(const char * path,char * gmttoken,char * snapname)2288871Samw@Sun.COM smbd_vss_map_gmttoken(const char *path, char *gmttoken, char *snapname)
2298474SJose.Borrego@Sun.COM {
2308871Samw@Sun.COM char dataset[MAXPATHLEN];
2318871Samw@Sun.COM libzfs_handle_t *libhd;
2328871Samw@Sun.COM zfs_handle_t *zfshd;
2338474SJose.Borrego@Sun.COM smbd_vss_map_gmttoken_t vss_map_gmttoken;
2348871Samw@Sun.COM char *zsnap;
2358871Samw@Sun.COM const char *lsnap;
2368474SJose.Borrego@Sun.COM
2378474SJose.Borrego@Sun.COM vss_map_gmttoken.mg_gmttoken = gmttoken;
2388474SJose.Borrego@Sun.COM vss_map_gmttoken.mg_snapname = snapname;
2398474SJose.Borrego@Sun.COM *snapname = '\0';
2408474SJose.Borrego@Sun.COM
2418871Samw@Sun.COM if (smb_getdataset(path, dataset, MAXPATHLEN) != 0)
2428871Samw@Sun.COM return (-1);
2438474SJose.Borrego@Sun.COM
2448871Samw@Sun.COM if ((libhd = libzfs_init()) == NULL)
2458871Samw@Sun.COM return (-1);
2468474SJose.Borrego@Sun.COM
2478871Samw@Sun.COM if ((zfshd = zfs_open(libhd, dataset, ZFS_TYPE_DATASET)) == NULL) {
2488871Samw@Sun.COM libzfs_fini(libhd);
2498474SJose.Borrego@Sun.COM return (-1);
2508474SJose.Borrego@Sun.COM }
2518474SJose.Borrego@Sun.COM
2528871Samw@Sun.COM (void) zfs_iter_snapshots(zfshd, smbd_vss_iterate_map_gmttoken,
2538474SJose.Borrego@Sun.COM (void *)&vss_map_gmttoken);
2548474SJose.Borrego@Sun.COM
2558474SJose.Borrego@Sun.COM /* compare the zfs snapshot name and the local snap name */
2568474SJose.Borrego@Sun.COM zsnap = snapname;
2578871Samw@Sun.COM lsnap = dataset;
2588474SJose.Borrego@Sun.COM while ((*lsnap != '\0') && (*zsnap != '\0') && (*lsnap == *zsnap)) {
2598474SJose.Borrego@Sun.COM zsnap++;
2608474SJose.Borrego@Sun.COM lsnap++;
2618474SJose.Borrego@Sun.COM }
2628474SJose.Borrego@Sun.COM
2638474SJose.Borrego@Sun.COM /* Now we should be passed the dataset name */
2648474SJose.Borrego@Sun.COM if ((*zsnap == '@') && (*lsnap == '\0')) {
2658474SJose.Borrego@Sun.COM zsnap++;
2668474SJose.Borrego@Sun.COM (void) strlcpy(snapname, zsnap, MAXPATHLEN);
2678474SJose.Borrego@Sun.COM } else {
2688474SJose.Borrego@Sun.COM *snapname = '\0';
2698474SJose.Borrego@Sun.COM }
2708474SJose.Borrego@Sun.COM
2718871Samw@Sun.COM zfs_close(zfshd);
2728871Samw@Sun.COM libzfs_fini(libhd);
2738474SJose.Borrego@Sun.COM return (0);
2748474SJose.Borrego@Sun.COM }
2758474SJose.Borrego@Sun.COM
2768474SJose.Borrego@Sun.COM static void
smbd_vss_time2gmttoken(time_t time,char * gmttoken)2778474SJose.Borrego@Sun.COM smbd_vss_time2gmttoken(time_t time, char *gmttoken)
2788474SJose.Borrego@Sun.COM {
2798474SJose.Borrego@Sun.COM struct tm t;
2808474SJose.Borrego@Sun.COM
2818474SJose.Borrego@Sun.COM (void) gmtime_r(&time, &t);
2828474SJose.Borrego@Sun.COM
2838474SJose.Borrego@Sun.COM (void) strftime(gmttoken, SMB_VSS_GMT_SIZE,
2848474SJose.Borrego@Sun.COM "@GMT-%Y.%m.%d-%H.%M.%S", &t);
2858474SJose.Borrego@Sun.COM }
2868474SJose.Borrego@Sun.COM
2878474SJose.Borrego@Sun.COM static int
smbd_vss_cmp_time(const void * a,const void * b)2888474SJose.Borrego@Sun.COM smbd_vss_cmp_time(const void *a, const void *b)
2898474SJose.Borrego@Sun.COM {
2908474SJose.Borrego@Sun.COM if (*(uint64_t *)a < *(uint64_t *)b)
2918474SJose.Borrego@Sun.COM return (1);
2928474SJose.Borrego@Sun.COM if (*(uint64_t *)a == *(uint64_t *)b)
2938474SJose.Borrego@Sun.COM return (0);
2948474SJose.Borrego@Sun.COM return (-1);
2958474SJose.Borrego@Sun.COM }
2968474SJose.Borrego@Sun.COM
2979231SAfshin.Ardakani@Sun.COM /*
2989231SAfshin.Ardakani@Sun.COM * ZFS snapshot iterator to count snapshots.
2999231SAfshin.Ardakani@Sun.COM * Note: libzfs expects us to close the handle.
3009231SAfshin.Ardakani@Sun.COM * Return 0 to continue iterating or non-zreo to terminate the iteration.
3019231SAfshin.Ardakani@Sun.COM */
3028474SJose.Borrego@Sun.COM static int
smbd_vss_iterate_count(zfs_handle_t * zhp,void * data)3038474SJose.Borrego@Sun.COM smbd_vss_iterate_count(zfs_handle_t *zhp, void *data)
3048474SJose.Borrego@Sun.COM {
3059231SAfshin.Ardakani@Sun.COM smbd_vss_count_t *vss_data = data;
3069231SAfshin.Ardakani@Sun.COM
3079231SAfshin.Ardakani@Sun.COM if (vss_data->vc_count < SMBD_VSS_SNAPSHOT_MAX) {
3089231SAfshin.Ardakani@Sun.COM vss_data->vc_count++;
3099231SAfshin.Ardakani@Sun.COM zfs_close(zhp);
3109231SAfshin.Ardakani@Sun.COM return (0);
3119231SAfshin.Ardakani@Sun.COM }
3129231SAfshin.Ardakani@Sun.COM
3138474SJose.Borrego@Sun.COM zfs_close(zhp);
3149231SAfshin.Ardakani@Sun.COM return (-1);
3158474SJose.Borrego@Sun.COM }
3168474SJose.Borrego@Sun.COM
3179231SAfshin.Ardakani@Sun.COM /*
3189231SAfshin.Ardakani@Sun.COM * ZFS snapshot iterator to get snapshot creation time.
3199231SAfshin.Ardakani@Sun.COM * Note: libzfs expects us to close the handle.
3209231SAfshin.Ardakani@Sun.COM * Return 0 to continue iterating or non-zreo to terminate the iteration.
3219231SAfshin.Ardakani@Sun.COM */
3228474SJose.Borrego@Sun.COM static int
smbd_vss_iterate_get_uint64_date(zfs_handle_t * zhp,void * data)3238474SJose.Borrego@Sun.COM smbd_vss_iterate_get_uint64_date(zfs_handle_t *zhp, void *data)
3248474SJose.Borrego@Sun.COM {
3259231SAfshin.Ardakani@Sun.COM smbd_vss_get_uint64_date_t *vss_data = data;
3269231SAfshin.Ardakani@Sun.COM int count;
3278474SJose.Borrego@Sun.COM
3289231SAfshin.Ardakani@Sun.COM count = vss_data->gd_return_count;
3298474SJose.Borrego@Sun.COM
3309231SAfshin.Ardakani@Sun.COM if (count < vss_data->gd_count) {
3319231SAfshin.Ardakani@Sun.COM vss_data->gd_gmt_array[count] =
3328474SJose.Borrego@Sun.COM zfs_prop_get_int(zhp, ZFS_PROP_CREATION);
3339231SAfshin.Ardakani@Sun.COM vss_data->gd_return_count++;
3349231SAfshin.Ardakani@Sun.COM zfs_close(zhp);
3359231SAfshin.Ardakani@Sun.COM return (0);
3368474SJose.Borrego@Sun.COM }
3378474SJose.Borrego@Sun.COM
3388474SJose.Borrego@Sun.COM zfs_close(zhp);
3399231SAfshin.Ardakani@Sun.COM return (-1);
3408474SJose.Borrego@Sun.COM }
3418474SJose.Borrego@Sun.COM
3429231SAfshin.Ardakani@Sun.COM /*
3439231SAfshin.Ardakani@Sun.COM * ZFS snapshot iterator to map a snapshot creation time to a token.
3449231SAfshin.Ardakani@Sun.COM * Note: libzfs expects us to close the handle.
3459231SAfshin.Ardakani@Sun.COM * Return 0 to continue iterating or non-zreo to terminate the iteration.
3469231SAfshin.Ardakani@Sun.COM */
3478474SJose.Borrego@Sun.COM static int
smbd_vss_iterate_map_gmttoken(zfs_handle_t * zhp,void * data)3488474SJose.Borrego@Sun.COM smbd_vss_iterate_map_gmttoken(zfs_handle_t *zhp, void *data)
3498474SJose.Borrego@Sun.COM {
3509231SAfshin.Ardakani@Sun.COM smbd_vss_map_gmttoken_t *vss_data = data;
3518474SJose.Borrego@Sun.COM time_t time;
3528474SJose.Borrego@Sun.COM char gmttoken[SMB_VSS_GMT_SIZE];
3538474SJose.Borrego@Sun.COM
3548474SJose.Borrego@Sun.COM time = (time_t)zfs_prop_get_int(zhp, ZFS_PROP_CREATION);
3558474SJose.Borrego@Sun.COM smbd_vss_time2gmttoken(time, gmttoken);
3568474SJose.Borrego@Sun.COM
3578871Samw@Sun.COM if (strncmp(gmttoken, vss_data->mg_gmttoken, SMB_VSS_GMT_SIZE) == 0) {
3588474SJose.Borrego@Sun.COM (void) strlcpy(vss_data->mg_snapname, zfs_get_name(zhp),
3598474SJose.Borrego@Sun.COM MAXPATHLEN);
3608474SJose.Borrego@Sun.COM
3619231SAfshin.Ardakani@Sun.COM /* we found a match, do not process anymore snapshots */
3628474SJose.Borrego@Sun.COM zfs_close(zhp);
3638474SJose.Borrego@Sun.COM return (-1);
3648474SJose.Borrego@Sun.COM }
3658474SJose.Borrego@Sun.COM
3668474SJose.Borrego@Sun.COM zfs_close(zhp);
3678474SJose.Borrego@Sun.COM return (0);
3688474SJose.Borrego@Sun.COM }
369