1*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
2*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * CDDL HEADER START
3*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
4*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * The contents of this file are subject to the terms of the
5*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Common Development and Distribution License (the "License").
6*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * You may not use this file except in compliance with the License.
7*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
8*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * or http://www.opensolaris.org/os/licensing.
10*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * See the License for the specific language governing permissions
11*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * and limitations under the License.
12*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
13*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * When distributing Covered Code, include this CDDL HEADER in each
14*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * If applicable, add the following below this CDDL HEADER, with the
16*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * fields enclosed by brackets "[]" replaced with your own identifying
17*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * information: Portions Copyright [yyyy] [name of copyright owner]
18*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
19*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * CDDL HEADER END
20*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
21*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
22*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Use is subject to license terms.
24*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
25*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
26*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <assert.h>
27*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <sys/avl.h>
28*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <smbsrv/libsmb.h>
29*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
30*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
31*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Cache lock modes
32*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
33*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #define	SMB_CACHE_RDLOCK	0
34*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #define	SMB_CACHE_WRLOCK	1
35*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
36*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #define	SMB_CACHE_STATE_NOCACHE		0
37*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #define	SMB_CACHE_STATE_READY		1
38*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #define	SMB_CACHE_STATE_REFRESHING	2
39*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #define	SMB_CACHE_STATE_DESTROYING	3
40*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
41*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static int smb_cache_lock(smb_cache_t *, int);
42*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static int smb_cache_rdlock(smb_cache_t *);
43*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static int smb_cache_wrlock(smb_cache_t *);
44*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void smb_cache_unlock(smb_cache_t *);
45*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static boolean_t smb_cache_wait(smb_cache_t *);
46*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void smb_cache_destroy_nodes(smb_cache_t *);
47*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
48*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
49*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Creates an AVL tree and initializes the given cache handle.
50*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Transfers the cache to READY state.
51*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
52*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function does not populate the cache.
53*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
54*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * chandle	pointer to a smb_cache_t structure
55*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * waittime	see smb_cache_refreshing() comments
56*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * cmpfn	compare function used by AVL tree
57*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * freefn	if set, it will be used to free any allocated
58*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * 		memory for the node data stored in the cache when
59*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * 		that node is removed.
60*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * copyfn	this function has to be set and it is used
61*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * 		to provide a copy of the node data stored in the
62*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * 		cache to the caller of smb_cache_iterate or any other
63*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * 		function that is used to access nodes data.
64*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * 		This can typically be 'bcopy' if data is fixed size.
65*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * datasz	Size of data stored in the cache if it's fixed size.
66*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * 		This size will be passed to the copy function.
67*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
68*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
smb_cache_create(smb_cache_t * chandle,uint32_t waittime,int (* cmpfn)(const void *,const void *),void (* freefn)(void *),void (* copyfn)(const void *,void *,size_t),size_t datasz)69*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_cache_create(smb_cache_t *chandle, uint32_t waittime,
70*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     int (*cmpfn) (const void *, const void *),
71*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     void (*freefn)(void *),
72*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     void (*copyfn)(const void *, void *, size_t),
73*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     size_t datasz)
74*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
75*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	assert(chandle);
76*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	assert(copyfn);
77*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
78*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_lock(&chandle->ch_mtx);
79*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (chandle->ch_state != SMB_CACHE_STATE_NOCACHE) {
80*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) mutex_unlock(&chandle->ch_mtx);
81*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return;
82*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
83*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
84*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	avl_create(&chandle->ch_cache, cmpfn, sizeof (smb_cache_node_t),
85*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    offsetof(smb_cache_node_t, cn_link));
86*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
87*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	chandle->ch_state = SMB_CACHE_STATE_READY;
88*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	chandle->ch_nops = 0;
89*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	chandle->ch_wait = waittime;
90*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	chandle->ch_sequence = random();
91*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	chandle->ch_datasz = datasz;
92*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	chandle->ch_free = freefn;
93*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	chandle->ch_copy = copyfn;
94*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_unlock(&chandle->ch_mtx);
95*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
96*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
97*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
98*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Destroys the cache.
99*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
100*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Transfers the cache to DESTROYING state while it's waiting for
101*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * in-flight operation to finish, this will prevent any new operation
102*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * to start. When all entries are removed the cache is transferred to
103*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * NOCACHE state.
104*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
105*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
smb_cache_destroy(smb_cache_t * chandle)106*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_cache_destroy(smb_cache_t *chandle)
107*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
108*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_lock(&chandle->ch_mtx);
109*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	switch (chandle->ch_state) {
110*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_CACHE_STATE_NOCACHE:
111*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_CACHE_STATE_DESTROYING:
112*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) mutex_unlock(&chandle->ch_mtx);
113*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return;
114*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
115*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	default:
116*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
117*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
118*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
119*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	chandle->ch_state = SMB_CACHE_STATE_DESTROYING;
120*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
121*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	while (chandle->ch_nops > 0)
122*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) cond_wait(&chandle->ch_cv, &chandle->ch_mtx);
123*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
124*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_cache_destroy_nodes(chandle);
125*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
126*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	avl_destroy(&chandle->ch_cache);
127*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	chandle->ch_state = SMB_CACHE_STATE_NOCACHE;
128*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_unlock(&chandle->ch_mtx);
129*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
130*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
131*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
132*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Removes and frees all the cache entries without destroy
133*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * the cache itself.
134*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
135*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
smb_cache_flush(smb_cache_t * chandle)136*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_cache_flush(smb_cache_t *chandle)
137*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
138*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_cache_wrlock(chandle) == 0) {
139*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_cache_destroy_nodes(chandle);
140*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		chandle->ch_sequence++;
141*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_cache_unlock(chandle);
142*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
143*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
144*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
145*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
146*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Based on the specified flag either add or replace given
147*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * data. If ADD flag is specified and the item is already in
148*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * the cache EEXIST error code is returned.
149*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
150*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int
smb_cache_add(smb_cache_t * chandle,const void * data,int flags)151*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_cache_add(smb_cache_t *chandle, const void *data, int flags)
152*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
153*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_cache_node_t *newnode;
154*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_cache_node_t *node;
155*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	avl_index_t where;
156*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int rc = 0;
157*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
158*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	assert(data);
159*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
160*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((rc = smb_cache_wrlock(chandle)) != 0)
161*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (rc);
162*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
163*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((newnode = malloc(sizeof (smb_cache_node_t))) == NULL) {
164*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_cache_unlock(chandle);
165*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (ENOMEM);
166*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
167*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
168*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	newnode->cn_data = (void *)data;
169*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	node = avl_find(&chandle->ch_cache, newnode, &where);
170*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (node != NULL) {
171*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (flags & SMB_CACHE_REPLACE) {
172*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			avl_remove(&chandle->ch_cache, node);
173*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			if (chandle->ch_free)
174*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				chandle->ch_free(node->cn_data);
175*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			free(node);
176*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		} else {
177*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			free(newnode);
178*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			smb_cache_unlock(chandle);
179*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (EEXIST);
180*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
181*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
182*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
183*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	avl_insert(&chandle->ch_cache, newnode, where);
184*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	chandle->ch_sequence++;
185*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
186*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_cache_unlock(chandle);
187*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (rc);
188*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
189*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
190*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
191*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Uses the given 'data' as key to find a cache entry
192*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * and remove it. The memory allocated for the found node
193*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * and its data is freed.
194*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
195*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
smb_cache_remove(smb_cache_t * chandle,const void * data)196*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_cache_remove(smb_cache_t *chandle, const void *data)
197*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
198*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_cache_node_t keynode;
199*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_cache_node_t *node;
200*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
201*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	assert(data);
202*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
203*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_cache_wrlock(chandle) != 0)
204*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return;
205*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
206*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	keynode.cn_data = (void *)data;
207*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	node = avl_find(&chandle->ch_cache, &keynode, NULL);
208*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (node) {
209*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		chandle->ch_sequence++;
210*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		avl_remove(&chandle->ch_cache, node);
211*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (chandle->ch_free)
212*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			chandle->ch_free(node->cn_data);
213*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		free(node);
214*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
215*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
216*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_cache_unlock(chandle);
217*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
218*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
219*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
220*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Initializes the given cursor for iterating the cache
221*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
222*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
smb_cache_iterinit(smb_cache_t * chandle,smb_cache_cursor_t * cursor)223*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_cache_iterinit(smb_cache_t *chandle, smb_cache_cursor_t *cursor)
224*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
225*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	cursor->cc_sequence = chandle->ch_sequence;
226*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	cursor->cc_next = NULL;
227*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
228*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
229*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
230*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Iterate the cache using the given cursor.
231*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
232*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Data is copied to the given buffer ('data') using the copy function
233*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * specified at cache creation time.
234*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
235*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * If the cache is modified while an iteration is in progress it causes
236*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * the iteration to finish prematurely. This is to avoid the need to lock
237*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * the whole cache while it is being iterated.
238*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
239*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States boolean_t
smb_cache_iterate(smb_cache_t * chandle,smb_cache_cursor_t * cursor,void * data)240*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_cache_iterate(smb_cache_t *chandle, smb_cache_cursor_t *cursor, void *data)
241*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
242*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_cache_node_t *node;
243*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
244*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	assert(data);
245*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
246*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_cache_rdlock(chandle) != 0)
247*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (B_FALSE);
248*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
249*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (cursor->cc_sequence != chandle->ch_sequence) {
250*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_cache_unlock(chandle);
251*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (B_FALSE);
252*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
253*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
254*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (cursor->cc_next == NULL)
255*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		node = avl_first(&chandle->ch_cache);
256*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	else
257*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		node = AVL_NEXT(&chandle->ch_cache, cursor->cc_next);
258*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
259*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (node != NULL)
260*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		chandle->ch_copy(node->cn_data, data, chandle->ch_datasz);
261*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
262*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	cursor->cc_next = node;
263*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_cache_unlock(chandle);
264*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
265*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (node != NULL);
266*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
267*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
268*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
269*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Returns the number of cache entries
270*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
271*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States uint32_t
smb_cache_num(smb_cache_t * chandle)272*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_cache_num(smb_cache_t *chandle)
273*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
274*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint32_t num = 0;
275*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
276*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_cache_rdlock(chandle) == 0) {
277*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		num = (uint32_t)avl_numnodes(&chandle->ch_cache);
278*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_cache_unlock(chandle);
279*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
280*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
281*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (num);
282*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
283*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
284*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
285*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Transfers the cache into REFRESHING state. This function needs
286*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * to be called when the whole cache is being populated or refereshed
287*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * and not for individual changes.
288*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
289*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Calling this function will ensure any read access to the cache will
290*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * be stalled until the update is finished, which is to avoid providing
291*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * incomplete, inconsistent or stale information. Read accesses will be
292*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * stalled for 'ch_wait' seconds (see smb_cache_lock), which is set at
293*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * the cache creation time.
294*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
295*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * If it is okay for the cache to be accessed while it's being populated
296*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * or refreshed, then there is no need to call this function.
297*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
298*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * If another thread is already updating the cache, other callers will wait
299*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * until cache is no longer in REFRESHING state. The return code is decided
300*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * based on the new state of the cache.
301*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
302*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function does NOT perform the actual refresh.
303*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
304*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int
smb_cache_refreshing(smb_cache_t * chandle)305*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_cache_refreshing(smb_cache_t *chandle)
306*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
307*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int rc = 0;
308*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
309*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_lock(&chandle->ch_mtx);
310*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	switch (chandle->ch_state) {
311*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_CACHE_STATE_READY:
312*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		chandle->ch_state = SMB_CACHE_STATE_REFRESHING;
313*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		rc = 0;
314*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
315*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
316*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_CACHE_STATE_REFRESHING:
317*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		while (chandle->ch_state == SMB_CACHE_STATE_REFRESHING)
318*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			(void) cond_wait(&chandle->ch_cv,
319*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			    &chandle->ch_mtx);
320*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
321*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (chandle->ch_state == SMB_CACHE_STATE_READY) {
322*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			chandle->ch_state = SMB_CACHE_STATE_REFRESHING;
323*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			rc = 0;
324*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		} else {
325*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			rc = ENODATA;
326*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
327*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
328*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
329*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_CACHE_STATE_NOCACHE:
330*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_CACHE_STATE_DESTROYING:
331*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		rc = ENODATA;
332*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
333*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
334*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	default:
335*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		assert(0);
336*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
337*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
338*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_unlock(&chandle->ch_mtx);
339*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (rc);
340*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
341*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
342*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
343*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Transfers the cache from REFRESHING to READY state.
344*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
345*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Nothing will happen if the cache is no longer available
346*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * or it is being destroyed.
347*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
348*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function should only be called if smb_cache_refreshing()
349*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * has already been invoked.
350*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
351*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
smb_cache_ready(smb_cache_t * chandle)352*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_cache_ready(smb_cache_t *chandle)
353*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
354*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_lock(&chandle->ch_mtx);
355*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	switch (chandle->ch_state) {
356*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_CACHE_STATE_REFRESHING:
357*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		chandle->ch_state = SMB_CACHE_STATE_READY;
358*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) cond_broadcast(&chandle->ch_cv);
359*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
360*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
361*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_CACHE_STATE_NOCACHE:
362*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_CACHE_STATE_DESTROYING:
363*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
364*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
365*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_CACHE_STATE_READY:
366*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	default:
367*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		assert(0);
368*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
369*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_unlock(&chandle->ch_mtx);
370*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
371*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
372*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
373*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Lock the cache with the specified mode.
374*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * If the cache is in updating state and a read lock is
375*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * requested, the lock won't be granted until either the
376*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * update is finished or SMB_CACHE_UPDATE_WAIT has passed.
377*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
378*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Whenever a lock is granted, the number of inflight cache
379*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * operations is incremented.
380*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
381*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static int
smb_cache_lock(smb_cache_t * chandle,int mode)382*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_cache_lock(smb_cache_t *chandle, int mode)
383*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
384*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_lock(&chandle->ch_mtx);
385*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	switch (chandle->ch_state) {
386*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_CACHE_STATE_NOCACHE:
387*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_CACHE_STATE_DESTROYING:
388*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) mutex_unlock(&chandle->ch_mtx);
389*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (ENODATA);
390*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
391*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_CACHE_STATE_REFRESHING:
392*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		/*
393*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		 * Read operations should wait until the update
394*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		 * is completed.
395*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		 */
396*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (mode == SMB_CACHE_RDLOCK) {
397*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			if (!smb_cache_wait(chandle)) {
398*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				(void) mutex_unlock(&chandle->ch_mtx);
399*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				return (ETIME);
400*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			}
401*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
402*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	/* FALLTHROUGH */
403*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_CACHE_STATE_READY:
404*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		chandle->ch_nops++;
405*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
406*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
407*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	default:
408*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		assert(0);
409*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
410*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_unlock(&chandle->ch_mtx);
411*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
412*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	/*
413*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	 * Lock has to be taken outside the mutex otherwise
414*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	 * there could be a deadlock
415*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	 */
416*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (mode == SMB_CACHE_RDLOCK)
417*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) rw_rdlock(&chandle->ch_cache_lck);
418*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	else
419*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) rw_wrlock(&chandle->ch_cache_lck);
420*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
421*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (0);
422*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
423*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
424*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
425*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Lock the cache for reading
426*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
427*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static int
smb_cache_rdlock(smb_cache_t * chandle)428*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_cache_rdlock(smb_cache_t *chandle)
429*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
430*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (smb_cache_lock(chandle, SMB_CACHE_RDLOCK));
431*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
432*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
433*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
434*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Lock the cache for modification
435*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
436*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static int
smb_cache_wrlock(smb_cache_t * chandle)437*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_cache_wrlock(smb_cache_t *chandle)
438*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
439*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (smb_cache_lock(chandle, SMB_CACHE_WRLOCK));
440*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
441*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
442*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
443*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Unlock the cache
444*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
445*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void
smb_cache_unlock(smb_cache_t * chandle)446*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_cache_unlock(smb_cache_t *chandle)
447*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
448*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_lock(&chandle->ch_mtx);
449*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	assert(chandle->ch_nops > 0);
450*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	chandle->ch_nops--;
451*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) cond_broadcast(&chandle->ch_cv);
452*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_unlock(&chandle->ch_mtx);
453*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
454*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) rw_unlock(&chandle->ch_cache_lck);
455*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
456*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
457*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
458*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
459*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Waits for ch_wait seconds if cache is in UPDATING state.
460*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Upon wake up returns true if cache is ready to be used,
461*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * otherwise it returns false.
462*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
463*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static boolean_t
smb_cache_wait(smb_cache_t * chandle)464*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_cache_wait(smb_cache_t *chandle)
465*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
466*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	timestruc_t to;
467*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int err;
468*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
469*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (chandle->ch_wait == 0)
470*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (B_TRUE);
471*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
472*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	to.tv_sec = chandle->ch_wait;
473*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	to.tv_nsec = 0;
474*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	while (chandle->ch_state == SMB_CACHE_STATE_REFRESHING) {
475*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		err = cond_reltimedwait(&chandle->ch_cv,
476*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    &chandle->ch_mtx, &to);
477*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (err == ETIME)
478*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			break;
479*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
480*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
481*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (chandle->ch_state == SMB_CACHE_STATE_READY);
482*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
483*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
484*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
485*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Removes and frees all the cache entries
486*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
487*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void
smb_cache_destroy_nodes(smb_cache_t * chandle)488*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_cache_destroy_nodes(smb_cache_t *chandle)
489*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
490*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	void *cookie = NULL;
491*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_cache_node_t *cnode;
492*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	avl_tree_t *cache;
493*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
494*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	cache = &chandle->ch_cache;
495*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	while ((cnode = avl_destroy_nodes(cache, &cookie)) != NULL) {
496*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (chandle->ch_free)
497*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			chandle->ch_free(cnode->cn_data);
498*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		free(cnode);
499*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
500*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
501