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