xref: /illumos-gate/usr/src/uts/common/fs/smbsrv/smb_kutil.c (revision 2cf6b79f28bc1e3f5631e49f3995194cc93991d4)
19fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
29fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * CDDL HEADER START
39fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
49fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * The contents of this file are subject to the terms of the
59fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Common Development and Distribution License (the "License").
69fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * You may not use this file except in compliance with the License.
79fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
89fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * or http://www.opensolaris.org/os/licensing.
109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * See the License for the specific language governing permissions
119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * and limitations under the License.
129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * When distributing Covered Code, include this CDDL HEADER in each
149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * If applicable, add the following below this CDDL HEADER, with the
169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * fields enclosed by brackets "[]" replaced with your own identifying
179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * information: Portions Copyright [yyyy] [name of copyright owner]
189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * CDDL HEADER END
209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
21c13be35aSGordon Ross 
229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
23c5866007SKeyur Desai  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24811599a4SMatt Barden  * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
25*2cf6b79fSGordon Ross  * Copyright 2022 RackTop Systems, Inc.
269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <sys/param.h>
299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <sys/types.h>
309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <sys/tzfile.h>
319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <sys/atomic.h>
329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <sys/time.h>
33148c5f43SAlan Wright #include <sys/spl.h>
34148c5f43SAlan Wright #include <sys/random.h>
359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <smbsrv/smb_kproto.h>
369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <smbsrv/smb_fsops.h>
379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <smbsrv/smbinfo.h>
389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <smbsrv/smb_xdr.h>
399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <smbsrv/smb_vops.h>
409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <smbsrv/smb_idmap.h>
419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <sys/sid.h>
439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <sys/priv_names.h>
44811599a4SMatt Barden #include <sys/bitmap.h>
459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
468622ec45SGordon Ross static kmem_cache_t	*smb_dtor_cache = NULL;
479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
48148c5f43SAlan Wright static boolean_t smb_avl_hold(smb_avl_t *);
49148c5f43SAlan Wright static void smb_avl_rele(smb_avl_t *);
50148c5f43SAlan Wright 
519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States time_t tzh_leapcnt = 0;
529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States struct tm
549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States *smb_gmtime_r(time_t *clock, struct tm *result);
559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States time_t
579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_timegm(struct tm *tm);
589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States struct	tm {
609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int	tm_sec;
619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int	tm_min;
629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int	tm_hour;
639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int	tm_mday;
649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int	tm_mon;
659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int	tm_year;
669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int	tm_wday;
679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int	tm_yday;
689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int	tm_isdst;
699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States };
709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
718622ec45SGordon Ross static const int days_in_month[] = {
729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States };
749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
7507a6ae61SGordon Ross /*
7607a6ae61SGordon Ross  * Given a UTF-8 string (our internal form everywhere)
7707a6ae61SGordon Ross  * return either the Unicode (UTF-16) length in bytes,
7807a6ae61SGordon Ross  * or the OEM length in bytes.  Which we return is
7907a6ae61SGordon Ross  * determined by whether the client supports Unicode.
8007a6ae61SGordon Ross  * This length does NOT include the null.
8107a6ae61SGordon Ross  */
829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int
839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_ascii_or_unicode_strlen(struct smb_request *sr, char *str)
849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
85a90cf9f2SGordon Ross 	if (sr->session->dialect >= SMB_VERS_2_BASE ||
86a90cf9f2SGordon Ross 	    (sr->smb_flg2 & SMB_FLAGS2_UNICODE) != 0)
879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (smb_wcequiv_strlen(str));
8807a6ae61SGordon Ross 	return (smb_sbequiv_strlen(str));
899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9107a6ae61SGordon Ross /*
9207a6ae61SGordon Ross  * Given a UTF-8 string (our internal form everywhere)
9307a6ae61SGordon Ross  * return either the Unicode (UTF-16) length in bytes,
9407a6ae61SGordon Ross  * or the OEM length in bytes.  Which we return is
9507a6ae61SGordon Ross  * determined by whether the client supports Unicode.
9607a6ae61SGordon Ross  * This length DOES include the null.
9707a6ae61SGordon Ross  */
989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int
999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_ascii_or_unicode_strlen_null(struct smb_request *sr, char *str)
1009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
101a90cf9f2SGordon Ross 	if (sr->session->dialect >= SMB_VERS_2_BASE ||
102a90cf9f2SGordon Ross 	    (sr->smb_flg2 & SMB_FLAGS2_UNICODE) != 0)
1039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (smb_wcequiv_strlen(str) + 2);
10407a6ae61SGordon Ross 	return (smb_sbequiv_strlen(str) + 1);
1059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
1069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int
1089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_ascii_or_unicode_null_len(struct smb_request *sr)
1099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
110a90cf9f2SGordon Ross 	if (sr->session->dialect >= SMB_VERS_2_BASE ||
111a90cf9f2SGordon Ross 	    (sr->smb_flg2 & SMB_FLAGS2_UNICODE) != 0)
1129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (2);
1139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (1);
1149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
1159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
1179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
118c13be35aSGordon Ross  * Convert old-style (DOS, LanMan) wildcard strings to NT style.
119c13be35aSGordon Ross  * This should ONLY happen to patterns that come from old clients,
120c13be35aSGordon Ross  * meaning dialect LANMAN2_1 etc. (dialect < NT_LM_0_12).
1219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
1229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *	? is converted to >
1239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *	* is converted to < if it is followed by .
124c13be35aSGordon Ross  *	. is converted to " if it is followed by ? or * or end of pattern
1259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
126c13be35aSGordon Ross  * Note: modifies pattern in place.
1279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
1289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
1299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_convert_wildcards(char *pattern)
1309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
1319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	char	*p;
1329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
133c13be35aSGordon Ross 	for (p = pattern; *p != '\0'; p++) {
1349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		switch (*p) {
135c13be35aSGordon Ross 		case '?':
136c13be35aSGordon Ross 			*p = '>';
1379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			break;
138c13be35aSGordon Ross 		case '*':
139c13be35aSGordon Ross 			if (p[1] == '.')
140c13be35aSGordon Ross 				*p = '<';
1419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			break;
142c13be35aSGordon Ross 		case '.':
143c13be35aSGordon Ross 			if (p[1] == '?' || p[1] == '*' || p[1] == '\0')
144c13be35aSGordon Ross 				*p = '\"';
1459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			break;
1469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
1479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
1489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
1499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
1519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_sattr_check
1529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
1539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Check file attributes against a search attribute (sattr) mask.
1549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
1559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Normal files, which includes READONLY and ARCHIVE, always pass
1569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * this check.  If the DIRECTORY, HIDDEN or SYSTEM special attributes
1579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * are set then they must appear in the search mask.  The special
1589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * attributes are inclusive, i.e. all special attributes that appear
1599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * in sattr must also appear in the file attributes for the check to
1609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * pass.
1619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
1629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * The following examples show how this works:
1639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
1649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *		fileA:	READONLY
1659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *		fileB:	0 (no attributes = normal file)
1669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *		fileC:	READONLY, ARCHIVE
1679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *		fileD:	HIDDEN
1689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *		fileE:	READONLY, HIDDEN, SYSTEM
1699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *		dirA:	DIRECTORY
1709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
1719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * search attribute: 0
1729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *		Returns: fileA, fileB and fileC.
1739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * search attribute: HIDDEN
1749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *		Returns: fileA, fileB, fileC and fileD.
1759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * search attribute: SYSTEM
1769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *		Returns: fileA, fileB and fileC.
1779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * search attribute: DIRECTORY
1789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *		Returns: fileA, fileB, fileC and dirA.
1799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * search attribute: HIDDEN and SYSTEM
1809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *		Returns: fileA, fileB, fileC, fileD and fileE.
1819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
1829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Returns true if the file and sattr match; otherwise, returns false.
1839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
1849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States boolean_t
1859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_sattr_check(uint16_t dosattr, uint16_t sattr)
1869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
1879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((dosattr & FILE_ATTRIBUTE_DIRECTORY) &&
1889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    !(sattr & FILE_ATTRIBUTE_DIRECTORY))
1899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (B_FALSE);
1909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((dosattr & FILE_ATTRIBUTE_HIDDEN) &&
1929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    !(sattr & FILE_ATTRIBUTE_HIDDEN))
1939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (B_FALSE);
1949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((dosattr & FILE_ATTRIBUTE_SYSTEM) &&
1969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    !(sattr & FILE_ATTRIBUTE_SYSTEM))
1979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (B_FALSE);
1989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (B_TRUE);
2009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
2019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
202a90cf9f2SGordon Ross time_t
203a90cf9f2SGordon Ross smb_get_boottime(void)
2049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
205a90cf9f2SGordon Ross 	extern time_t	boot_time;
206a90cf9f2SGordon Ross 	zone_t *z = curzone;
2079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
208a90cf9f2SGordon Ross 	/* Unfortunately, the GZ doesn't set zone_boot_time. */
209a90cf9f2SGordon Ross 	if (z->zone_id == GLOBAL_ZONEID)
210a90cf9f2SGordon Ross 		return (boot_time);
211a90cf9f2SGordon Ross 
212a90cf9f2SGordon Ross 	return (z->zone_boot_time);
2139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
2149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
2169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_idpool_increment
2179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
2189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function increments the ID pool by doubling the current size. This
2199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * function assumes the caller entered the mutex of the pool.
2209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
2219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static int
2229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_idpool_increment(
2239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_idpool_t	*pool)
2249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
2259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint8_t		*new_pool;
2269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint32_t	new_size;
2279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(pool->id_magic == SMB_IDPOOL_MAGIC);
2299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	new_size = pool->id_size * 2;
2319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (new_size <= SMB_IDPOOL_MAX_SIZE) {
2329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		new_pool = kmem_alloc(new_size / 8, KM_NOSLEEP);
2339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (new_pool) {
2349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			bzero(new_pool, new_size / 8);
2359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			bcopy(pool->id_pool, new_pool, pool->id_size / 8);
2369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			kmem_free(pool->id_pool, pool->id_size / 8);
2379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			pool->id_pool = new_pool;
2389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			pool->id_free_counter += new_size - pool->id_size;
2399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			pool->id_max_free_counter += new_size - pool->id_size;
2409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			pool->id_size = new_size;
2419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			pool->id_idx_msk = (new_size / 8) - 1;
2429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			if (new_size >= SMB_IDPOOL_MAX_SIZE) {
2439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				/* id -1 made unavailable */
2449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				pool->id_pool[pool->id_idx_msk] = 0x80;
2459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				pool->id_free_counter--;
2469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				pool->id_max_free_counter--;
2479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			}
2489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (0);
2499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
2509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
2519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (-1);
2529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
2539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
2559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_idpool_constructor
2569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
2579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function initializes the pool structure provided.
2589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
2599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int
2609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_idpool_constructor(
2619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_idpool_t	*pool)
2629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
2639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(pool->id_magic != SMB_IDPOOL_MAGIC);
2659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	pool->id_size = SMB_IDPOOL_MIN_SIZE;
2679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	pool->id_idx_msk = (SMB_IDPOOL_MIN_SIZE / 8) - 1;
2689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	pool->id_free_counter = SMB_IDPOOL_MIN_SIZE - 1;
2699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	pool->id_max_free_counter = SMB_IDPOOL_MIN_SIZE - 1;
2709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	pool->id_bit = 0x02;
2719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	pool->id_bit_idx = 1;
2729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	pool->id_idx = 0;
2739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	pool->id_pool = (uint8_t *)kmem_alloc((SMB_IDPOOL_MIN_SIZE / 8),
2749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    KM_SLEEP);
2759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	bzero(pool->id_pool, (SMB_IDPOOL_MIN_SIZE / 8));
2769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	/* -1 id made unavailable */
2779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	pool->id_pool[0] = 0x01;		/* id 0 made unavailable */
2789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_init(&pool->id_mutex, NULL, MUTEX_DEFAULT, NULL);
2799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	pool->id_magic = SMB_IDPOOL_MAGIC;
2809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (0);
2819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
2829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
2849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_idpool_destructor
2859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
2869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function tears down and frees the resources associated with the
2879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * pool provided.
2889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
2899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
2909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_idpool_destructor(
2919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_idpool_t	*pool)
2929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
2939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(pool->id_magic == SMB_IDPOOL_MAGIC);
2949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(pool->id_free_counter == pool->id_max_free_counter);
2959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	pool->id_magic = (uint32_t)~SMB_IDPOOL_MAGIC;
2969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_destroy(&pool->id_mutex);
2979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	kmem_free(pool->id_pool, (size_t)(pool->id_size / 8));
2989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
2999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
3019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_idpool_alloc
3029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
3039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function allocates an ID from the pool provided.
3049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
3059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int
3069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_idpool_alloc(
3079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_idpool_t	*pool,
3089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     uint16_t		*id)
3099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
3109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint32_t	i;
3119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint8_t		bit;
3129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint8_t		bit_idx;
3139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint8_t		byte;
3149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(pool->id_magic == SMB_IDPOOL_MAGIC);
3169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&pool->id_mutex);
3189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((pool->id_free_counter == 0) && smb_idpool_increment(pool)) {
3199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		mutex_exit(&pool->id_mutex);
3209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (-1);
3219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
3229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	i = pool->id_size;
3249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	while (i) {
3259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		bit = pool->id_bit;
3269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		bit_idx = pool->id_bit_idx;
3279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		byte = pool->id_pool[pool->id_idx];
3289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		while (bit) {
3299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			if (byte & bit) {
3309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				bit = bit << 1;
3319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				bit_idx++;
3329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				continue;
3339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			}
3349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			pool->id_pool[pool->id_idx] |= bit;
3359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			*id = (uint16_t)(pool->id_idx * 8 + (uint32_t)bit_idx);
3369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			pool->id_free_counter--;
337811599a4SMatt Barden 			/*
338811599a4SMatt Barden 			 * Leave position at next bit to allocate,
339811599a4SMatt Barden 			 * so we don't keep re-using the last in an
340811599a4SMatt Barden 			 * alloc/free/alloc/free sequence.  Doing
341811599a4SMatt Barden 			 * that can confuse some SMB clients.
342811599a4SMatt Barden 			 */
343811599a4SMatt Barden 			if (bit & 0x80) {
344811599a4SMatt Barden 				pool->id_bit = 1;
345811599a4SMatt Barden 				pool->id_bit_idx = 0;
346811599a4SMatt Barden 				pool->id_idx++;
347811599a4SMatt Barden 				pool->id_idx &= pool->id_idx_msk;
348811599a4SMatt Barden 			} else {
349811599a4SMatt Barden 				pool->id_bit = (bit << 1);
350811599a4SMatt Barden 				pool->id_bit_idx = bit_idx + 1;
351811599a4SMatt Barden 				/* keep id_idx */
352811599a4SMatt Barden 			}
3539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			mutex_exit(&pool->id_mutex);
3549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (0);
3559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
3569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		pool->id_bit = 1;
3579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		pool->id_bit_idx = 0;
3589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		pool->id_idx++;
3599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		pool->id_idx &= pool->id_idx_msk;
3609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		--i;
3619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
3629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	/*
3639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	 * This section of code shouldn't be reached. If there are IDs
3649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	 * available and none could be found there's a problem.
3659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	 */
3669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(0);
3679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&pool->id_mutex);
3689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (-1);
3699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
3709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
3729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_idpool_free
3739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
3749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function frees the ID provided.
3759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
3769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
3779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_idpool_free(
3789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_idpool_t	*pool,
3799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     uint16_t		id)
3809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
3819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(pool->id_magic == SMB_IDPOOL_MAGIC);
3829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(id != 0);
3839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(id != 0xFFFF);
3849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&pool->id_mutex);
3869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (pool->id_pool[id >> 3] & (1 << (id & 7))) {
3879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		pool->id_pool[id >> 3] &= ~(1 << (id & 7));
3889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		pool->id_free_counter++;
3899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		ASSERT(pool->id_free_counter <= pool->id_max_free_counter);
3909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		mutex_exit(&pool->id_mutex);
3919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return;
3929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
3939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	/* Freeing a free ID. */
3949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(0);
3959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&pool->id_mutex);
3969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
3979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
399*2cf6b79fSGordon Ross  * smb_lavl_constructor
400*2cf6b79fSGordon Ross  *
401*2cf6b79fSGordon Ross  * This function initializes a locked avl.
402*2cf6b79fSGordon Ross  */
403*2cf6b79fSGordon Ross void
404*2cf6b79fSGordon Ross smb_lavl_constructor(
405*2cf6b79fSGordon Ross     smb_lavl_t	*la,
406*2cf6b79fSGordon Ross     int (*compar) (const void *, const void *),
407*2cf6b79fSGordon Ross     size_t	size,
408*2cf6b79fSGordon Ross     size_t	offset)
409*2cf6b79fSGordon Ross {
410*2cf6b79fSGordon Ross 	rw_init(&la->la_lock, NULL, RW_DEFAULT, NULL);
411*2cf6b79fSGordon Ross 	mutex_init(&la->la_mutex, NULL, MUTEX_DEFAULT, NULL);
412*2cf6b79fSGordon Ross 	avl_create(&la->la_tree, compar, size, offset);
413*2cf6b79fSGordon Ross 	list_create(&la->la_deleteq, sizeof (smb_dtor_t),
414*2cf6b79fSGordon Ross 	    offsetof(smb_dtor_t, dt_lnd));
415*2cf6b79fSGordon Ross 	la->la_wrop = 0;
416*2cf6b79fSGordon Ross 	la->la_deleteq_count = 0;
417*2cf6b79fSGordon Ross 	la->la_flushing = B_FALSE;
418*2cf6b79fSGordon Ross }
419*2cf6b79fSGordon Ross 
420*2cf6b79fSGordon Ross /*
421*2cf6b79fSGordon Ross  * Flush the delete queue and destroy a locked avl.
422*2cf6b79fSGordon Ross  */
423*2cf6b79fSGordon Ross void
424*2cf6b79fSGordon Ross smb_lavl_destructor(
425*2cf6b79fSGordon Ross     smb_lavl_t	*la)
426*2cf6b79fSGordon Ross {
427*2cf6b79fSGordon Ross 	smb_lavl_flush(la);
428*2cf6b79fSGordon Ross 
429*2cf6b79fSGordon Ross 	ASSERT(la->la_deleteq_count == 0);
430*2cf6b79fSGordon Ross 	ASSERT0(avl_numnodes(&la->la_tree));
431*2cf6b79fSGordon Ross 
432*2cf6b79fSGordon Ross 	rw_destroy(&la->la_lock);
433*2cf6b79fSGordon Ross 	avl_destroy(&la->la_tree);
434*2cf6b79fSGordon Ross 	list_destroy(&la->la_deleteq);
435*2cf6b79fSGordon Ross 	mutex_destroy(&la->la_mutex);
436*2cf6b79fSGordon Ross }
437*2cf6b79fSGordon Ross 
438*2cf6b79fSGordon Ross /*
439*2cf6b79fSGordon Ross  * smb_lavl_enter
440*2cf6b79fSGordon Ross  * Not a macro so dtrace smbsrv:* can see it.
441*2cf6b79fSGordon Ross  */
442*2cf6b79fSGordon Ross void
443*2cf6b79fSGordon Ross smb_lavl_enter(smb_lavl_t *la, krw_t mode)
444*2cf6b79fSGordon Ross {
445*2cf6b79fSGordon Ross 	rw_enter(&la->la_lock, mode);
446*2cf6b79fSGordon Ross }
447*2cf6b79fSGordon Ross 
448*2cf6b79fSGordon Ross /*
449*2cf6b79fSGordon Ross  * Post an object to the delete queue.  The delete queue will be processed
450*2cf6b79fSGordon Ross  * during smb_lavl_exit or lavl destruction.  Objects are often posted for
451*2cf6b79fSGordon Ross  * deletion during avl iteration (while the lavl is locked) but that is
452*2cf6b79fSGordon Ross  * not required, and an object can be posted at any time.
453*2cf6b79fSGordon Ross  */
454*2cf6b79fSGordon Ross void
455*2cf6b79fSGordon Ross smb_lavl_post(smb_lavl_t *la, void *object, smb_dtorproc_t dtorproc)
456*2cf6b79fSGordon Ross {
457*2cf6b79fSGordon Ross 	smb_dtor_t	*dtor;
458*2cf6b79fSGordon Ross 
459*2cf6b79fSGordon Ross 	ASSERT((object != NULL) && (dtorproc != NULL));
460*2cf6b79fSGordon Ross 
461*2cf6b79fSGordon Ross 	dtor = kmem_cache_alloc(smb_dtor_cache, KM_SLEEP);
462*2cf6b79fSGordon Ross 	bzero(dtor, sizeof (smb_dtor_t));
463*2cf6b79fSGordon Ross 	dtor->dt_magic = SMB_DTOR_MAGIC;
464*2cf6b79fSGordon Ross 	dtor->dt_object = object;
465*2cf6b79fSGordon Ross 	dtor->dt_proc = dtorproc;
466*2cf6b79fSGordon Ross 
467*2cf6b79fSGordon Ross 	mutex_enter(&la->la_mutex);
468*2cf6b79fSGordon Ross 	list_insert_tail(&la->la_deleteq, dtor);
469*2cf6b79fSGordon Ross 	++la->la_deleteq_count;
470*2cf6b79fSGordon Ross 	mutex_exit(&la->la_mutex);
471*2cf6b79fSGordon Ross }
472*2cf6b79fSGordon Ross 
473*2cf6b79fSGordon Ross /*
474*2cf6b79fSGordon Ross  * Exit the lavl lock and process the delete queue.
475*2cf6b79fSGordon Ross  */
476*2cf6b79fSGordon Ross void
477*2cf6b79fSGordon Ross smb_lavl_exit(smb_lavl_t *la)
478*2cf6b79fSGordon Ross {
479*2cf6b79fSGordon Ross 	rw_exit(&la->la_lock);
480*2cf6b79fSGordon Ross 	smb_lavl_flush(la);
481*2cf6b79fSGordon Ross }
482*2cf6b79fSGordon Ross 
483*2cf6b79fSGordon Ross /*
484*2cf6b79fSGordon Ross  * Flush the lavl delete queue.  The mutex is dropped across the destructor
485*2cf6b79fSGordon Ross  * call in case this leads to additional objects being posted to the delete
486*2cf6b79fSGordon Ross  * queue.
487*2cf6b79fSGordon Ross  */
488*2cf6b79fSGordon Ross void
489*2cf6b79fSGordon Ross smb_lavl_flush(smb_lavl_t *la)
490*2cf6b79fSGordon Ross {
491*2cf6b79fSGordon Ross 	smb_dtor_t    *dtor;
492*2cf6b79fSGordon Ross 
493*2cf6b79fSGordon Ross 	mutex_enter(&la->la_mutex);
494*2cf6b79fSGordon Ross 	if (la->la_flushing) {
495*2cf6b79fSGordon Ross 		mutex_exit(&la->la_mutex);
496*2cf6b79fSGordon Ross 		return;
497*2cf6b79fSGordon Ross 	}
498*2cf6b79fSGordon Ross 	la->la_flushing = B_TRUE;
499*2cf6b79fSGordon Ross 
500*2cf6b79fSGordon Ross 	dtor = list_head(&la->la_deleteq);
501*2cf6b79fSGordon Ross 	while (dtor != NULL) {
502*2cf6b79fSGordon Ross 		SMB_DTOR_VALID(dtor);
503*2cf6b79fSGordon Ross 		ASSERT((dtor->dt_object != NULL) && (dtor->dt_proc != NULL));
504*2cf6b79fSGordon Ross 		list_remove(&la->la_deleteq, dtor);
505*2cf6b79fSGordon Ross 		--la->la_deleteq_count;
506*2cf6b79fSGordon Ross 		mutex_exit(&la->la_mutex);
507*2cf6b79fSGordon Ross 
508*2cf6b79fSGordon Ross 		dtor->dt_proc(dtor->dt_object);
509*2cf6b79fSGordon Ross 
510*2cf6b79fSGordon Ross 		dtor->dt_magic = (uint32_t)~SMB_DTOR_MAGIC;
511*2cf6b79fSGordon Ross 		kmem_cache_free(smb_dtor_cache, dtor);
512*2cf6b79fSGordon Ross 		mutex_enter(&la->la_mutex);
513*2cf6b79fSGordon Ross 		dtor = list_head(&la->la_deleteq);
514*2cf6b79fSGordon Ross 	}
515*2cf6b79fSGordon Ross 	la->la_flushing = B_FALSE;
516*2cf6b79fSGordon Ross 
517*2cf6b79fSGordon Ross 	mutex_exit(&la->la_mutex);
518*2cf6b79fSGordon Ross }
519*2cf6b79fSGordon Ross 
520*2cf6b79fSGordon Ross /*
521*2cf6b79fSGordon Ross  * smb_lavl_upgrade
522*2cf6b79fSGordon Ross  *
523*2cf6b79fSGordon Ross  * This function tries to upgrade the lock of the locked avl. It assumes the
524*2cf6b79fSGordon Ross  * locked has already been entered in RW_READER mode. It first tries using the
525*2cf6b79fSGordon Ross  * Solaris function rw_tryupgrade(). If that call fails the lock is released
526*2cf6b79fSGordon Ross  * and reentered in RW_WRITER mode. In that last case a window is opened during
527*2cf6b79fSGordon Ross  * which the contents of the avl may have changed. The return code indicates
528*2cf6b79fSGordon Ross  * whether or not the avl was modified when the lock was exited.
529*2cf6b79fSGordon Ross  */
530*2cf6b79fSGordon Ross int smb_lavl_upgrade(
531*2cf6b79fSGordon Ross     smb_lavl_t *la)
532*2cf6b79fSGordon Ross {
533*2cf6b79fSGordon Ross 	uint64_t	wrop;
534*2cf6b79fSGordon Ross 
535*2cf6b79fSGordon Ross 	if (rw_tryupgrade(&la->la_lock) != 0) {
536*2cf6b79fSGordon Ross 		return (0);
537*2cf6b79fSGordon Ross 	}
538*2cf6b79fSGordon Ross 	wrop = la->la_wrop;
539*2cf6b79fSGordon Ross 	rw_exit(&la->la_lock);
540*2cf6b79fSGordon Ross 	rw_enter(&la->la_lock, RW_WRITER);
541*2cf6b79fSGordon Ross 	return (wrop != la->la_wrop);
542*2cf6b79fSGordon Ross }
543*2cf6b79fSGordon Ross 
544*2cf6b79fSGordon Ross /*
545*2cf6b79fSGordon Ross  * smb_lavl_insert
546*2cf6b79fSGordon Ross  *
547*2cf6b79fSGordon Ross  * This function inserts the object passed into the tree
548*2cf6b79fSGordon Ross  * at the position determined by the AVL comparator.
549*2cf6b79fSGordon Ross  */
550*2cf6b79fSGordon Ross void
551*2cf6b79fSGordon Ross smb_lavl_insert(
552*2cf6b79fSGordon Ross     smb_lavl_t	*la,
553*2cf6b79fSGordon Ross     void	*obj)
554*2cf6b79fSGordon Ross {
555*2cf6b79fSGordon Ross 	avl_add(&la->la_tree, obj);
556*2cf6b79fSGordon Ross 	++la->la_wrop;
557*2cf6b79fSGordon Ross }
558*2cf6b79fSGordon Ross 
559*2cf6b79fSGordon Ross /*
560*2cf6b79fSGordon Ross  * smb_lavl_remove
561*2cf6b79fSGordon Ross  *
562*2cf6b79fSGordon Ross  * This function removes the object passed from the lavl. This function
563*2cf6b79fSGordon Ross  * assumes the lock of the lavl has already been entered.
564*2cf6b79fSGordon Ross  */
565*2cf6b79fSGordon Ross void
566*2cf6b79fSGordon Ross smb_lavl_remove(
567*2cf6b79fSGordon Ross     smb_lavl_t	*la,
568*2cf6b79fSGordon Ross     void	*obj)
569*2cf6b79fSGordon Ross {
570*2cf6b79fSGordon Ross 	avl_remove(&la->la_tree, obj);
571*2cf6b79fSGordon Ross 	++la->la_wrop;
572*2cf6b79fSGordon Ross }
573*2cf6b79fSGordon Ross 
574*2cf6b79fSGordon Ross /*
575*2cf6b79fSGordon Ross  * smb_lavl_get_count
576*2cf6b79fSGordon Ross  *
577*2cf6b79fSGordon Ross  * This function returns the number of elements in the specified avl.
578*2cf6b79fSGordon Ross  */
579*2cf6b79fSGordon Ross uint32_t
580*2cf6b79fSGordon Ross smb_lavl_get_count(
581*2cf6b79fSGordon Ross     smb_lavl_t *la)
582*2cf6b79fSGordon Ross {
583*2cf6b79fSGordon Ross 	return ((uint32_t)avl_numnodes(&la->la_tree));
584*2cf6b79fSGordon Ross }
585*2cf6b79fSGordon Ross 
586*2cf6b79fSGordon Ross /*
5879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Initialize the llist delete queue object cache.
5889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
5899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
5909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_init(void)
5919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
5928622ec45SGordon Ross 	if (smb_dtor_cache != NULL)
5939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return;
5949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
5959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_dtor_cache = kmem_cache_create("smb_dtor_cache",
5969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    sizeof (smb_dtor_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
5979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
5989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
5999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
6009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Destroy the llist delete queue object cache.
6019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
6029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
6039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_fini(void)
6049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
6058622ec45SGordon Ross 	if (smb_dtor_cache != NULL) {
6069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		kmem_cache_destroy(smb_dtor_cache);
6078622ec45SGordon Ross 		smb_dtor_cache = NULL;
6088622ec45SGordon Ross 	}
6099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
6109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
6129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_llist_constructor
6139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
6149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function initializes a locked list.
6159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
6169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
6179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_constructor(
6189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_llist_t	*ll,
6199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     size_t	size,
6209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     size_t	offset)
6219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
6229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	rw_init(&ll->ll_lock, NULL, RW_DEFAULT, NULL);
6239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_init(&ll->ll_mutex, NULL, MUTEX_DEFAULT, NULL);
6249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	list_create(&ll->ll_list, size, offset);
6259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	list_create(&ll->ll_deleteq, sizeof (smb_dtor_t),
6269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    offsetof(smb_dtor_t, dt_lnd));
6279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ll->ll_count = 0;
6289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ll->ll_wrop = 0;
6299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ll->ll_deleteq_count = 0;
630cb174861Sjoyce mcintosh 	ll->ll_flushing = B_FALSE;
6319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
6329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
6349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Flush the delete queue and destroy a locked list.
6359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
6369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
6379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_destructor(
6389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_llist_t	*ll)
6399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
6409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_llist_flush(ll);
6419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(ll->ll_count == 0);
6439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(ll->ll_deleteq_count == 0);
6449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	rw_destroy(&ll->ll_lock);
6469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	list_destroy(&ll->ll_list);
6479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	list_destroy(&ll->ll_deleteq);
6489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_destroy(&ll->ll_mutex);
6499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
6509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
652811599a4SMatt Barden  * smb_llist_enter
653811599a4SMatt Barden  * Not a macro so dtrace smbsrv:* can see it.
654811599a4SMatt Barden  */
655811599a4SMatt Barden void
656811599a4SMatt Barden smb_llist_enter(smb_llist_t *ll, krw_t mode)
657811599a4SMatt Barden {
658811599a4SMatt Barden 	rw_enter(&ll->ll_lock, mode);
659811599a4SMatt Barden }
660811599a4SMatt Barden 
661811599a4SMatt Barden /*
6629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Post an object to the delete queue.  The delete queue will be processed
6639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * during list exit or list destruction.  Objects are often posted for
6649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * deletion during list iteration (while the list is locked) but that is
6659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * not required, and an object can be posted at any time.
6669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
6679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
6689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_post(smb_llist_t *ll, void *object, smb_dtorproc_t dtorproc)
6699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
6709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_dtor_t	*dtor;
6719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT((object != NULL) && (dtorproc != NULL));
6739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	dtor = kmem_cache_alloc(smb_dtor_cache, KM_SLEEP);
6759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	bzero(dtor, sizeof (smb_dtor_t));
6769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	dtor->dt_magic = SMB_DTOR_MAGIC;
6779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	dtor->dt_object = object;
6789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	dtor->dt_proc = dtorproc;
6799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&ll->ll_mutex);
6819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	list_insert_tail(&ll->ll_deleteq, dtor);
6829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	++ll->ll_deleteq_count;
6839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&ll->ll_mutex);
6849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
6859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
6879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Exit the list lock and process the delete queue.
6889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
6899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
6909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_exit(smb_llist_t *ll)
6919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
6929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	rw_exit(&ll->ll_lock);
6939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_llist_flush(ll);
6949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
6959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
6979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Flush the list delete queue.  The mutex is dropped across the destructor
6989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * call in case this leads to additional objects being posted to the delete
6999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * queue.
7009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
701c5866007SKeyur Desai void
7029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_flush(smb_llist_t *ll)
7039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
7049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_dtor_t    *dtor;
7059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
7069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&ll->ll_mutex);
707cb174861Sjoyce mcintosh 	if (ll->ll_flushing) {
708cb174861Sjoyce mcintosh 		mutex_exit(&ll->ll_mutex);
709cb174861Sjoyce mcintosh 		return;
710cb174861Sjoyce mcintosh 	}
711cb174861Sjoyce mcintosh 	ll->ll_flushing = B_TRUE;
7129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
7139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	dtor = list_head(&ll->ll_deleteq);
7149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	while (dtor != NULL) {
7159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		SMB_DTOR_VALID(dtor);
7169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		ASSERT((dtor->dt_object != NULL) && (dtor->dt_proc != NULL));
7179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		list_remove(&ll->ll_deleteq, dtor);
7189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		--ll->ll_deleteq_count;
7199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		mutex_exit(&ll->ll_mutex);
7209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
7219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		dtor->dt_proc(dtor->dt_object);
7229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
7239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		dtor->dt_magic = (uint32_t)~SMB_DTOR_MAGIC;
7249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		kmem_cache_free(smb_dtor_cache, dtor);
7259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		mutex_enter(&ll->ll_mutex);
7269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		dtor = list_head(&ll->ll_deleteq);
7279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
728cb174861Sjoyce mcintosh 	ll->ll_flushing = B_FALSE;
7299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
7309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&ll->ll_mutex);
7319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
7329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
7339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
7349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_llist_upgrade
7359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
7369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function tries to upgrade the lock of the locked list. It assumes the
7379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * locked has already been entered in RW_READER mode. It first tries using the
7389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Solaris function rw_tryupgrade(). If that call fails the lock is released
7399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * and reentered in RW_WRITER mode. In that last case a window is opened during
7409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * which the contents of the list may have changed. The return code indicates
7419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * whether or not the list was modified when the lock was exited.
7429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
7439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int smb_llist_upgrade(
7449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_llist_t *ll)
7459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
7469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint64_t	wrop;
7479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
7489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (rw_tryupgrade(&ll->ll_lock) != 0) {
7499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (0);
7509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
7519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	wrop = ll->ll_wrop;
7529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	rw_exit(&ll->ll_lock);
7539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	rw_enter(&ll->ll_lock, RW_WRITER);
7549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (wrop != ll->ll_wrop);
7559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
7569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
7579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
7589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_llist_insert_head
7599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
7609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function inserts the object passed a the beginning of the list. This
7619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * function assumes the lock of the list has already been entered.
7629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
7639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
7649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_insert_head(
7659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_llist_t	*ll,
7669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     void	*obj)
7679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
7689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	list_insert_head(&ll->ll_list, obj);
7699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	++ll->ll_wrop;
7709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	++ll->ll_count;
7719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
7729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
7739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
7749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_llist_insert_tail
7759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
7769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function appends to the object passed to the list. This function assumes
7779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * the lock of the list has already been entered.
7789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
7799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
7809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
7819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_insert_tail(
7829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_llist_t	*ll,
7839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     void	*obj)
7849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
7859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	list_insert_tail(&ll->ll_list, obj);
7869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	++ll->ll_wrop;
7879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	++ll->ll_count;
7889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
7899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
7909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
7919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_llist_remove
7929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
7939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function removes the object passed from the list. This function assumes
7949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * the lock of the list has already been entered.
7959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
7969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
7979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_remove(
7989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_llist_t	*ll,
7999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     void	*obj)
8009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
8019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	list_remove(&ll->ll_list, obj);
8029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	++ll->ll_wrop;
8039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	--ll->ll_count;
8049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
8059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
8069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
8079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_llist_get_count
8089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
8099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function returns the number of elements in the specified list.
8109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
8119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States uint32_t
8129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_get_count(
8139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_llist_t *ll)
8149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
8159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (ll->ll_count);
8169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
8179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
8189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
8199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_slist_constructor
8209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
8219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Synchronized list constructor.
8229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
8239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
8249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_slist_constructor(
8259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_slist_t	*sl,
8269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     size_t	size,
8279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     size_t	offset)
8289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
8299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_init(&sl->sl_mutex, NULL, MUTEX_DEFAULT, NULL);
8309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	cv_init(&sl->sl_cv, NULL, CV_DEFAULT, NULL);
8319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	list_create(&sl->sl_list, size, offset);
8329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	sl->sl_count = 0;
8339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	sl->sl_waiting = B_FALSE;
8349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
8359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
8369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
8379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_slist_destructor
8389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
8399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Synchronized list destructor.
8409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
8419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
8429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_slist_destructor(
8439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_slist_t	*sl)
8449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
845148c5f43SAlan Wright 	VERIFY(sl->sl_count == 0);
8469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
8479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_destroy(&sl->sl_mutex);
8489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	cv_destroy(&sl->sl_cv);
8499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	list_destroy(&sl->sl_list);
8509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
8519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
8529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
853811599a4SMatt Barden  * smb_slist_enter
854811599a4SMatt Barden  * Not a macro so dtrace smbsrv:* can see it.
855811599a4SMatt Barden  */
856811599a4SMatt Barden void
857811599a4SMatt Barden smb_slist_enter(smb_slist_t *sl)
858811599a4SMatt Barden {
859811599a4SMatt Barden 	mutex_enter(&(sl)->sl_mutex);
860811599a4SMatt Barden }
861811599a4SMatt Barden 
862811599a4SMatt Barden /*
8639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_slist_insert_head
8649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
8659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function inserts the object passed a the beginning of the list.
8669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
8679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
8689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_slist_insert_head(
8699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_slist_t	*sl,
8709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     void	*obj)
8719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
8729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&sl->sl_mutex);
8739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	list_insert_head(&sl->sl_list, obj);
8749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	++sl->sl_count;
8759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&sl->sl_mutex);
8769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
8779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
8789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
8799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_slist_insert_tail
8809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
8819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function appends the object passed to the list.
8829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
8839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
8849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_slist_insert_tail(
8859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_slist_t	*sl,
8869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     void	*obj)
8879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
8889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&sl->sl_mutex);
8899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	list_insert_tail(&sl->sl_list, obj);
8909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	++sl->sl_count;
8919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&sl->sl_mutex);
8929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
8939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
8949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
8959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_llist_remove
8969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
8979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function removes the object passed by the caller from the list.
8989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
8999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
9009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_slist_remove(
9019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_slist_t	*sl,
9029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     void	*obj)
9039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
9049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&sl->sl_mutex);
9059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	list_remove(&sl->sl_list, obj);
9069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((--sl->sl_count == 0) && (sl->sl_waiting)) {
9079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sl->sl_waiting = B_FALSE;
9089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		cv_broadcast(&sl->sl_cv);
9099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
9109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&sl->sl_mutex);
9119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
9129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
9149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_slist_move_tail
9159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
9169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function transfers all the contents of the synchronized list to the
9179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * list_t provided. It returns the number of objects transferred.
9189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
9199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States uint32_t
9209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_slist_move_tail(
9219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     list_t	*lst,
9229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_slist_t	*sl)
9239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
9249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint32_t	rv;
9259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&sl->sl_mutex);
9279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	rv = sl->sl_count;
9289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (sl->sl_count) {
9299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		list_move_tail(lst, &sl->sl_list);
9309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sl->sl_count = 0;
9319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (sl->sl_waiting) {
9329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			sl->sl_waiting = B_FALSE;
9339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			cv_broadcast(&sl->sl_cv);
9349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
9359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
9369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&sl->sl_mutex);
9379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (rv);
9389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
9399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
9419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_slist_obj_move
9429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
9439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function moves an object from one list to the end of the other list. It
9449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * assumes the mutex of each list has been entered.
9459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
9469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
9479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_slist_obj_move(
9489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_slist_t	*dst,
9499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_slist_t	*src,
9509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     void	*obj)
9519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
9529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(dst->sl_list.list_offset == src->sl_list.list_offset);
9539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(dst->sl_list.list_size == src->sl_list.list_size);
9549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	list_remove(&src->sl_list, obj);
9569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	list_insert_tail(&dst->sl_list, obj);
9579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	dst->sl_count++;
9589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	src->sl_count--;
9599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((src->sl_count == 0) && (src->sl_waiting)) {
9609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		src->sl_waiting = B_FALSE;
9619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		cv_broadcast(&src->sl_cv);
9629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
9639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
9649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
9669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_slist_wait_for_empty
9679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
9689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function waits for a list to be emptied.
9699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
9709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
9719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_slist_wait_for_empty(
9729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_slist_t	*sl)
9739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
9749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&sl->sl_mutex);
9759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	while (sl->sl_count) {
9769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sl->sl_waiting = B_TRUE;
9779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		cv_wait(&sl->sl_cv, &sl->sl_mutex);
9789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
9799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&sl->sl_mutex);
9809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
9819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
9839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_slist_exit
9849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
9859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function exits the muetx of the list and signal the condition variable
9869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * if the list is empty.
9879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
9889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
9899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_slist_exit(smb_slist_t *sl)
9909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
9919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((sl->sl_count == 0) && (sl->sl_waiting)) {
9929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sl->sl_waiting = B_FALSE;
9939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		cv_broadcast(&sl->sl_cv);
9949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
9959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&sl->sl_mutex);
9969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
9979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
998b819cea2SGordon Ross /* smb_thread_... moved to smb_thread.c */
9999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
10009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
10019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_rwx_init
10029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
10039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
10049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_rwx_init(
10059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_rwx_t	*rwx)
10069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
10079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	bzero(rwx, sizeof (smb_rwx_t));
10089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	cv_init(&rwx->rwx_cv, NULL, CV_DEFAULT, NULL);
10099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_init(&rwx->rwx_mutex, NULL, MUTEX_DEFAULT, NULL);
10109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	rw_init(&rwx->rwx_lock, NULL, RW_DEFAULT, NULL);
10119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
10129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
10139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
10149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_rwx_destroy
10159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
10169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
10179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_rwx_destroy(
10189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_rwx_t	*rwx)
10199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
10209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_destroy(&rwx->rwx_mutex);
10219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	cv_destroy(&rwx->rwx_cv);
10229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	rw_destroy(&rwx->rwx_lock);
10239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
10249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
10259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
1026811599a4SMatt Barden  * smb_rwx_rwenter
1027811599a4SMatt Barden  */
1028811599a4SMatt Barden void
1029811599a4SMatt Barden smb_rwx_rwenter(smb_rwx_t *rwx, krw_t mode)
1030811599a4SMatt Barden {
1031811599a4SMatt Barden 	rw_enter(&rwx->rwx_lock, mode);
1032811599a4SMatt Barden }
1033811599a4SMatt Barden 
1034811599a4SMatt Barden /*
10359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_rwx_rwexit
10369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
10379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
10389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_rwx_rwexit(
10399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_rwx_t	*rwx)
10409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
10419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	rw_exit(&rwx->rwx_lock);
10429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
10439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
10449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
10459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
1046811599a4SMatt Barden  * smb_rwx_cvwait
10479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
1048811599a4SMatt Barden  * Wait on rwx->rw_cv, dropping the rw lock and retake after wakeup.
1049811599a4SMatt Barden  * Assumes the smb_rwx lock was entered in RW_READER or RW_WRITER
10509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * mode. It will:
10519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
10529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *	1) release the lock and save its current mode.
1053811599a4SMatt Barden  *	2) wait until the condition variable is signaled.
10549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *	3) re-acquire the lock in the mode saved in (1).
1055811599a4SMatt Barden  *
1056811599a4SMatt Barden  * Lock order: rwlock, mutex
10579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
10589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int
1059811599a4SMatt Barden smb_rwx_cvwait(
10609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_rwx_t	*rwx,
10619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     clock_t	timeout)
10629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
10639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	krw_t	mode;
1064b819cea2SGordon Ross 	int	rc = 1;
10659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
10669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (rw_write_held(&rwx->rwx_lock)) {
10679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		ASSERT(rw_owner(&rwx->rwx_lock) == curthread);
10689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		mode = RW_WRITER;
10699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	} else {
10709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		ASSERT(rw_read_held(&rwx->rwx_lock));
10719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		mode = RW_READER;
10729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
10739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
10749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&rwx->rwx_mutex);
1075811599a4SMatt Barden 	rw_exit(&rwx->rwx_lock);
1076811599a4SMatt Barden 
1077811599a4SMatt Barden 	rwx->rwx_waiting = B_TRUE;
10789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (timeout == -1) {
10799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		cv_wait(&rwx->rwx_cv, &rwx->rwx_mutex);
10809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	} else {
10819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		rc = cv_reltimedwait(&rwx->rwx_cv, &rwx->rwx_mutex,
10829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    timeout, TR_CLOCK_TICK);
10839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
10849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&rwx->rwx_mutex);
10859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
10869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	rw_enter(&rwx->rwx_lock, mode);
10879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (rc);
10889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
10899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1090811599a4SMatt Barden /*
1091811599a4SMatt Barden  * smb_rwx_cvbcast
1092811599a4SMatt Barden  *
1093811599a4SMatt Barden  * Wake up threads waiting on rx_cv
1094811599a4SMatt Barden  * The rw lock may or may not be held.
1095811599a4SMatt Barden  * The mutex MUST NOT be held.
1096811599a4SMatt Barden  */
1097811599a4SMatt Barden void
1098811599a4SMatt Barden smb_rwx_cvbcast(smb_rwx_t *rwx)
1099811599a4SMatt Barden {
1100811599a4SMatt Barden 	mutex_enter(&rwx->rwx_mutex);
1101811599a4SMatt Barden 	if (rwx->rwx_waiting) {
1102811599a4SMatt Barden 		rwx->rwx_waiting = B_FALSE;
1103811599a4SMatt Barden 		cv_broadcast(&rwx->rwx_cv);
1104811599a4SMatt Barden 	}
1105811599a4SMatt Barden 	mutex_exit(&rwx->rwx_mutex);
1106811599a4SMatt Barden }
1107811599a4SMatt Barden 
1108b819cea2SGordon Ross /* smb_idmap_... moved to smb_idmap.c */
11099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States uint64_t
11119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_time_unix_to_nt(timestruc_t *unix_time)
11129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
11139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint64_t nt_time;
11149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((unix_time->tv_sec == 0) && (unix_time->tv_nsec == 0))
11169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (0);
11179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	nt_time = unix_time->tv_sec;
11199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	nt_time *= 10000000;  /* seconds to 100ns */
11209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	nt_time += unix_time->tv_nsec / 100;
11219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (nt_time + NT_TIME_BIAS);
11229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
11239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
11259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_time_nt_to_unix(uint64_t nt_time, timestruc_t *unix_time)
11269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
11279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint32_t seconds;
11289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(unix_time);
11309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((nt_time == 0) || (nt_time == -1)) {
11329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		unix_time->tv_sec = 0;
11339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		unix_time->tv_nsec = 0;
11349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return;
11359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
11369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1137b6f078edSGordon Ross 	/*
1138b6f078edSGordon Ross 	 * Can't represent times less than or equal NT_TIME_BIAS,
1139b6f078edSGordon Ross 	 * so convert them to the oldest date we can store.
1140b6f078edSGordon Ross 	 * Note that time zero is "special" being converted
1141b6f078edSGordon Ross 	 * both directions as 0:0 (unix-to-nt, nt-to-unix).
1142b6f078edSGordon Ross 	 */
1143b6f078edSGordon Ross 	if (nt_time <= NT_TIME_BIAS) {
1144b6f078edSGordon Ross 		unix_time->tv_sec = 0;
1145b6f078edSGordon Ross 		unix_time->tv_nsec = 100;
1146b6f078edSGordon Ross 		return;
1147b6f078edSGordon Ross 	}
1148b6f078edSGordon Ross 
11499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	nt_time -= NT_TIME_BIAS;
11509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	seconds = nt_time / 10000000;
11519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	unix_time->tv_sec = seconds;
11529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	unix_time->tv_nsec = (nt_time  % 10000000) * 100;
11539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
11549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
11569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_time_gmt_to_local, smb_time_local_to_gmt
11579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
11589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Apply the gmt offset to convert between local time and gmt
11599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
11609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int32_t
11619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_time_gmt_to_local(smb_request_t *sr, int32_t gmt)
11629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
11639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((gmt == 0) || (gmt == -1))
11649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (0);
11659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (gmt - sr->sr_gmtoff);
11679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
11689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int32_t
11709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_time_local_to_gmt(smb_request_t *sr, int32_t local)
11719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
11729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((local == 0) || (local == -1))
11739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (0);
11749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (local + sr->sr_gmtoff);
11769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
11779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
11809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_time_dos_to_unix
11819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
11829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Convert SMB_DATE & SMB_TIME values to a unix timestamp.
11839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
11849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * A date/time field of 0 means that that server file system
11859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * assigned value need not be changed. The behaviour when the
11869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * date/time field is set to -1 is not documented but is
11879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * generally treated like 0.
11889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * If date or time is 0 or -1 the unix time is returned as 0
11899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * so that the caller can identify and handle this special case.
11909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
11919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int32_t
11929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_time_dos_to_unix(int16_t date, int16_t time)
11939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
11949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	struct tm	atm;
11959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (((date == 0) || (time == 0)) ||
11979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    ((date == -1) || (time == -1))) {
11989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (0);
11999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
12009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	atm.tm_year = ((date >>  9) & 0x3F) + 80;
12029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	atm.tm_mon  = ((date >>  5) & 0x0F) - 1;
12039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	atm.tm_mday = ((date >>  0) & 0x1F);
12049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	atm.tm_hour = ((time >> 11) & 0x1F);
12059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	atm.tm_min  = ((time >>  5) & 0x3F);
12069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	atm.tm_sec  = ((time >>  0) & 0x1F) << 1;
12079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (smb_timegm(&atm));
12099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
12109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
12129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_time_unix_to_dos(int32_t ux_time, int16_t *date_p, int16_t *time_p)
12139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
12149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	struct tm	atm;
12159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int		i;
12169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	time_t		tmp_time;
12179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (ux_time == 0) {
12199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		*date_p = 0;
12209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		*time_p = 0;
12219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return;
12229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
12239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	tmp_time = (time_t)ux_time;
12259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) smb_gmtime_r(&tmp_time, &atm);
12269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (date_p) {
12289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		i = 0;
12299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		i += atm.tm_year - 80;
12309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		i <<= 4;
12319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		i += atm.tm_mon + 1;
12329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		i <<= 5;
12339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		i += atm.tm_mday;
12349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		*date_p = (short)i;
12369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
12379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (time_p) {
12389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		i = 0;
12399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		i += atm.tm_hour;
12409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		i <<= 6;
12419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		i += atm.tm_min;
12429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		i <<= 5;
12439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		i += atm.tm_sec >> 1;
12449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		*time_p = (short)i;
12469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
12479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
12489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
12519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_gmtime_r
12529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
12539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Thread-safe version of smb_gmtime. Returns a null pointer if either
12549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * input parameter is a null pointer. Otherwise returns a pointer
12559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * to result.
12569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
12579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Day of the week calculation: the Epoch was a thursday.
12589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
12599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * There are no timezone corrections so tm_isdst and tm_gmtoff are
12609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * always zero, and the zone is always WET.
12619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
12629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States struct tm *
12639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_gmtime_r(time_t *clock, struct tm *result)
12649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
12659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	time_t tsec;
12669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int year;
12679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int month;
12689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int sec_per_month;
12699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (clock == 0 || result == 0)
12719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (0);
12729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	bzero(result, sizeof (struct tm));
12749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	tsec = *clock;
12759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	tsec -= tzh_leapcnt;
12769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	result->tm_wday = tsec / SECSPERDAY;
12789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	result->tm_wday = (result->tm_wday + TM_THURSDAY) % DAYSPERWEEK;
12799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	year = EPOCH_YEAR;
12819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	while (tsec >= (isleap(year) ? (SECSPERDAY * DAYSPERLYEAR) :
12829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    (SECSPERDAY * DAYSPERNYEAR))) {
12839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (isleap(year))
12849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			tsec -= SECSPERDAY * DAYSPERLYEAR;
12859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		else
12869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			tsec -= SECSPERDAY * DAYSPERNYEAR;
12879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		++year;
12899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
12909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	result->tm_year = year - TM_YEAR_BASE;
12929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	result->tm_yday = tsec / SECSPERDAY;
12939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	for (month = TM_JANUARY; month <= TM_DECEMBER; ++month) {
12959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sec_per_month = days_in_month[month] * SECSPERDAY;
12969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (month == TM_FEBRUARY && isleap(year))
12989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			sec_per_month += SECSPERDAY;
12999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (tsec < sec_per_month)
13019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			break;
13029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		tsec -= sec_per_month;
13049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
13059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	result->tm_mon = month;
13079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	result->tm_mday = (tsec / SECSPERDAY) + 1;
13089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	tsec %= SECSPERDAY;
13099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	result->tm_sec = tsec % 60;
13109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	tsec /= 60;
13119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	result->tm_min = tsec % 60;
13129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	tsec /= 60;
13139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	result->tm_hour = (int)tsec;
13149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (result);
13169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
13179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
13209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_timegm
13219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
13229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Converts the broken-down time in tm to a time value, i.e. the number
13239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * of seconds since the Epoch (00:00:00 UTC, January 1, 1970). This is
13249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * not a POSIX or ANSI function. Per the man page, the input values of
13259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * tm_wday and tm_yday are ignored and, as the input data is assumed to
13269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * represent GMT, we force tm_isdst and tm_gmtoff to 0.
13279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
13289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Before returning the clock time, we use smb_gmtime_r to set up tm_wday
13299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * and tm_yday, and bring the other fields within normal range. I don't
13309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * think this is really how it should be done but it's convenient for
13319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * now.
13329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
13339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States time_t
13349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_timegm(struct tm *tm)
13359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
13369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	time_t tsec;
13379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int dd;
13389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int mm;
13399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int yy;
13409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int year;
13419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (tm == 0)
13439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (-1);
13449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	year = tm->tm_year + TM_YEAR_BASE;
13469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	tsec = tzh_leapcnt;
13479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	for (yy = EPOCH_YEAR; yy < year; ++yy) {
13499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (isleap(yy))
13509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			tsec += SECSPERDAY * DAYSPERLYEAR;
13519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		else
13529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			tsec += SECSPERDAY * DAYSPERNYEAR;
13539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
13549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	for (mm = TM_JANUARY; mm < tm->tm_mon; ++mm) {
13569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		dd = days_in_month[mm] * SECSPERDAY;
13579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (mm == TM_FEBRUARY && isleap(year))
13599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			dd += SECSPERDAY;
13609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		tsec += dd;
13629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
13639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	tsec += (tm->tm_mday - 1) * SECSPERDAY;
13659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	tsec += tm->tm_sec;
13669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	tsec += tm->tm_min * SECSPERMIN;
13679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	tsec += tm->tm_hour * SECSPERHOUR;
13689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	tm->tm_isdst = 0;
13709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) smb_gmtime_r(&tsec, tm);
13719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (tsec);
13729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
13739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
13759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_pad_align
13769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
13779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Returns the number of bytes required to pad an offset to the
13789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * specified alignment.
13799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
13809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States uint32_t
13819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_pad_align(uint32_t offset, uint32_t align)
13829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
13839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint32_t pad = offset % align;
13849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (pad != 0)
13869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		pad = align - pad;
13879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (pad);
13899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
13909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
13929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_panic
13939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
13949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Logs the file name, function name and line number passed in and panics the
13959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * system.
13969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
13979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
13989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_panic(char *file, const char *func, int line)
13999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
14009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	cmn_err(CE_PANIC, "%s:%s:%d\n", file, func, line);
14019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
1402148c5f43SAlan Wright 
1403148c5f43SAlan Wright /*
1404148c5f43SAlan Wright  * Creates an AVL tree and initializes the given smb_avl_t
1405148c5f43SAlan Wright  * structure using the passed args
1406148c5f43SAlan Wright  */
1407148c5f43SAlan Wright void
14088622ec45SGordon Ross smb_avl_create(smb_avl_t *avl, size_t size, size_t offset,
14098622ec45SGordon Ross     const smb_avl_nops_t *ops)
1410148c5f43SAlan Wright {
1411148c5f43SAlan Wright 	ASSERT(avl);
1412148c5f43SAlan Wright 	ASSERT(ops);
1413148c5f43SAlan Wright 
1414148c5f43SAlan Wright 	rw_init(&avl->avl_lock, NULL, RW_DEFAULT, NULL);
1415148c5f43SAlan Wright 	mutex_init(&avl->avl_mutex, NULL, MUTEX_DEFAULT, NULL);
1416148c5f43SAlan Wright 
1417148c5f43SAlan Wright 	avl->avl_nops = ops;
1418148c5f43SAlan Wright 	avl->avl_state = SMB_AVL_STATE_READY;
1419148c5f43SAlan Wright 	avl->avl_refcnt = 0;
1420148c5f43SAlan Wright 	(void) random_get_pseudo_bytes((uint8_t *)&avl->avl_sequence,
1421148c5f43SAlan Wright 	    sizeof (uint32_t));
1422148c5f43SAlan Wright 
1423148c5f43SAlan Wright 	avl_create(&avl->avl_tree, ops->avln_cmp, size, offset);
1424148c5f43SAlan Wright }
1425148c5f43SAlan Wright 
1426148c5f43SAlan Wright /*
1427148c5f43SAlan Wright  * Destroys the specified AVL tree.
1428148c5f43SAlan Wright  * It waits for all the in-flight operations to finish
1429148c5f43SAlan Wright  * before destroying the AVL.
1430148c5f43SAlan Wright  */
1431148c5f43SAlan Wright void
1432148c5f43SAlan Wright smb_avl_destroy(smb_avl_t *avl)
1433148c5f43SAlan Wright {
1434148c5f43SAlan Wright 	void *cookie = NULL;
1435148c5f43SAlan Wright 	void *node;
1436148c5f43SAlan Wright 
1437148c5f43SAlan Wright 	ASSERT(avl);
1438148c5f43SAlan Wright 
1439148c5f43SAlan Wright 	mutex_enter(&avl->avl_mutex);
1440148c5f43SAlan Wright 	if (avl->avl_state != SMB_AVL_STATE_READY) {
1441148c5f43SAlan Wright 		mutex_exit(&avl->avl_mutex);
1442148c5f43SAlan Wright 		return;
1443148c5f43SAlan Wright 	}
1444148c5f43SAlan Wright 
1445148c5f43SAlan Wright 	avl->avl_state = SMB_AVL_STATE_DESTROYING;
1446148c5f43SAlan Wright 
1447148c5f43SAlan Wright 	while (avl->avl_refcnt > 0)
1448148c5f43SAlan Wright 		(void) cv_wait(&avl->avl_cv, &avl->avl_mutex);
1449148c5f43SAlan Wright 	mutex_exit(&avl->avl_mutex);
1450148c5f43SAlan Wright 
1451148c5f43SAlan Wright 	rw_enter(&avl->avl_lock, RW_WRITER);
1452148c5f43SAlan Wright 	while ((node = avl_destroy_nodes(&avl->avl_tree, &cookie)) != NULL)
1453148c5f43SAlan Wright 		avl->avl_nops->avln_destroy(node);
1454148c5f43SAlan Wright 
1455148c5f43SAlan Wright 	avl_destroy(&avl->avl_tree);
1456148c5f43SAlan Wright 	rw_exit(&avl->avl_lock);
1457148c5f43SAlan Wright 
1458148c5f43SAlan Wright 	rw_destroy(&avl->avl_lock);
1459148c5f43SAlan Wright 
1460148c5f43SAlan Wright 	mutex_destroy(&avl->avl_mutex);
1461148c5f43SAlan Wright 	bzero(avl, sizeof (smb_avl_t));
1462148c5f43SAlan Wright }
1463148c5f43SAlan Wright 
1464148c5f43SAlan Wright /*
1465148c5f43SAlan Wright  * Adds the given item to the AVL if it's
1466148c5f43SAlan Wright  * not already there.
1467148c5f43SAlan Wright  *
1468148c5f43SAlan Wright  * Returns:
1469148c5f43SAlan Wright  *
1470148c5f43SAlan Wright  *	ENOTACTIVE	AVL is not in READY state
1471148c5f43SAlan Wright  *	EEXIST		The item is already in AVL
1472148c5f43SAlan Wright  */
1473148c5f43SAlan Wright int
1474148c5f43SAlan Wright smb_avl_add(smb_avl_t *avl, void *item)
1475148c5f43SAlan Wright {
1476148c5f43SAlan Wright 	avl_index_t where;
1477148c5f43SAlan Wright 
1478148c5f43SAlan Wright 	ASSERT(avl);
1479148c5f43SAlan Wright 	ASSERT(item);
1480148c5f43SAlan Wright 
1481148c5f43SAlan Wright 	if (!smb_avl_hold(avl))
1482148c5f43SAlan Wright 		return (ENOTACTIVE);
1483148c5f43SAlan Wright 
1484148c5f43SAlan Wright 	rw_enter(&avl->avl_lock, RW_WRITER);
1485148c5f43SAlan Wright 	if (avl_find(&avl->avl_tree, item, &where) != NULL) {
1486148c5f43SAlan Wright 		rw_exit(&avl->avl_lock);
1487148c5f43SAlan Wright 		smb_avl_rele(avl);
1488148c5f43SAlan Wright 		return (EEXIST);
1489148c5f43SAlan Wright 	}
1490148c5f43SAlan Wright 
1491148c5f43SAlan Wright 	avl_insert(&avl->avl_tree, item, where);
1492148c5f43SAlan Wright 	avl->avl_sequence++;
1493148c5f43SAlan Wright 	rw_exit(&avl->avl_lock);
1494148c5f43SAlan Wright 
1495148c5f43SAlan Wright 	smb_avl_rele(avl);
1496148c5f43SAlan Wright 	return (0);
1497148c5f43SAlan Wright }
1498148c5f43SAlan Wright 
1499148c5f43SAlan Wright /*
1500148c5f43SAlan Wright  * Removes the given item from the AVL.
1501148c5f43SAlan Wright  * If no reference is left on the item
1502148c5f43SAlan Wright  * it will also be destroyed by calling the
1503148c5f43SAlan Wright  * registered destroy operation.
1504148c5f43SAlan Wright  */
1505148c5f43SAlan Wright void
1506148c5f43SAlan Wright smb_avl_remove(smb_avl_t *avl, void *item)
1507148c5f43SAlan Wright {
1508148c5f43SAlan Wright 	avl_index_t where;
1509148c5f43SAlan Wright 	void *rm_item;
1510148c5f43SAlan Wright 
1511148c5f43SAlan Wright 	ASSERT(avl);
1512148c5f43SAlan Wright 	ASSERT(item);
1513148c5f43SAlan Wright 
1514148c5f43SAlan Wright 	if (!smb_avl_hold(avl))
1515148c5f43SAlan Wright 		return;
1516148c5f43SAlan Wright 
1517148c5f43SAlan Wright 	rw_enter(&avl->avl_lock, RW_WRITER);
1518148c5f43SAlan Wright 	if ((rm_item = avl_find(&avl->avl_tree, item, &where)) == NULL) {
1519148c5f43SAlan Wright 		rw_exit(&avl->avl_lock);
1520148c5f43SAlan Wright 		smb_avl_rele(avl);
1521148c5f43SAlan Wright 		return;
1522148c5f43SAlan Wright 	}
1523148c5f43SAlan Wright 
1524148c5f43SAlan Wright 	avl_remove(&avl->avl_tree, rm_item);
1525148c5f43SAlan Wright 	if (avl->avl_nops->avln_rele(rm_item))
1526148c5f43SAlan Wright 		avl->avl_nops->avln_destroy(rm_item);
1527148c5f43SAlan Wright 	avl->avl_sequence++;
1528148c5f43SAlan Wright 	rw_exit(&avl->avl_lock);
1529148c5f43SAlan Wright 
1530148c5f43SAlan Wright 	smb_avl_rele(avl);
1531148c5f43SAlan Wright }
1532148c5f43SAlan Wright 
1533148c5f43SAlan Wright /*
1534148c5f43SAlan Wright  * Looks up the AVL for the given item.
1535148c5f43SAlan Wright  * If the item is found a hold on the object
1536148c5f43SAlan Wright  * is taken before the pointer to it is
1537148c5f43SAlan Wright  * returned to the caller. The caller MUST
1538148c5f43SAlan Wright  * always call smb_avl_release() after it's done
1539148c5f43SAlan Wright  * using the returned object to release the hold
1540148c5f43SAlan Wright  * taken on the object.
1541148c5f43SAlan Wright  */
1542148c5f43SAlan Wright void *
1543148c5f43SAlan Wright smb_avl_lookup(smb_avl_t *avl, void *item)
1544148c5f43SAlan Wright {
1545148c5f43SAlan Wright 	void *node = NULL;
1546148c5f43SAlan Wright 
1547148c5f43SAlan Wright 	ASSERT(avl);
1548148c5f43SAlan Wright 	ASSERT(item);
1549148c5f43SAlan Wright 
1550148c5f43SAlan Wright 	if (!smb_avl_hold(avl))
1551148c5f43SAlan Wright 		return (NULL);
1552148c5f43SAlan Wright 
1553148c5f43SAlan Wright 	rw_enter(&avl->avl_lock, RW_READER);
1554148c5f43SAlan Wright 	node = avl_find(&avl->avl_tree, item, NULL);
1555148c5f43SAlan Wright 	if (node != NULL)
1556148c5f43SAlan Wright 		avl->avl_nops->avln_hold(node);
1557148c5f43SAlan Wright 	rw_exit(&avl->avl_lock);
1558148c5f43SAlan Wright 
1559148c5f43SAlan Wright 	if (node == NULL)
1560148c5f43SAlan Wright 		smb_avl_rele(avl);
1561148c5f43SAlan Wright 
1562148c5f43SAlan Wright 	return (node);
1563148c5f43SAlan Wright }
1564148c5f43SAlan Wright 
1565148c5f43SAlan Wright /*
1566148c5f43SAlan Wright  * The hold on the given object is released.
1567148c5f43SAlan Wright  * This function MUST always be called after
1568148c5f43SAlan Wright  * smb_avl_lookup() and smb_avl_iterate() for
1569148c5f43SAlan Wright  * the returned object.
1570148c5f43SAlan Wright  *
1571148c5f43SAlan Wright  * If AVL is in DESTROYING state, the destroying
1572148c5f43SAlan Wright  * thread will be notified.
1573148c5f43SAlan Wright  */
1574148c5f43SAlan Wright void
1575148c5f43SAlan Wright smb_avl_release(smb_avl_t *avl, void *item)
1576148c5f43SAlan Wright {
1577148c5f43SAlan Wright 	ASSERT(avl);
1578148c5f43SAlan Wright 	ASSERT(item);
1579148c5f43SAlan Wright 
1580148c5f43SAlan Wright 	if (avl->avl_nops->avln_rele(item))
1581148c5f43SAlan Wright 		avl->avl_nops->avln_destroy(item);
1582148c5f43SAlan Wright 
1583148c5f43SAlan Wright 	smb_avl_rele(avl);
1584148c5f43SAlan Wright }
1585148c5f43SAlan Wright 
1586148c5f43SAlan Wright /*
1587148c5f43SAlan Wright  * Initializes the given cursor for the AVL.
1588148c5f43SAlan Wright  * The cursor will be used to iterate through the AVL
1589148c5f43SAlan Wright  */
1590148c5f43SAlan Wright void
1591148c5f43SAlan Wright smb_avl_iterinit(smb_avl_t *avl, smb_avl_cursor_t *cursor)
1592148c5f43SAlan Wright {
1593148c5f43SAlan Wright 	ASSERT(avl);
1594148c5f43SAlan Wright 	ASSERT(cursor);
1595148c5f43SAlan Wright 
1596148c5f43SAlan Wright 	cursor->avlc_next = NULL;
1597148c5f43SAlan Wright 	cursor->avlc_sequence = avl->avl_sequence;
1598148c5f43SAlan Wright }
1599148c5f43SAlan Wright 
1600148c5f43SAlan Wright /*
1601148c5f43SAlan Wright  * Iterates through the AVL using the given cursor.
1602148c5f43SAlan Wright  * It always starts at the beginning and then returns
1603148c5f43SAlan Wright  * a pointer to the next object on each subsequent call.
1604148c5f43SAlan Wright  *
1605148c5f43SAlan Wright  * If a new object is added to or removed from the AVL
1606148c5f43SAlan Wright  * between two calls to this function, the iteration
1607148c5f43SAlan Wright  * will terminate prematurely.
1608148c5f43SAlan Wright  *
1609148c5f43SAlan Wright  * The caller MUST always call smb_avl_release() after it's
1610148c5f43SAlan Wright  * done using the returned object to release the hold taken
1611148c5f43SAlan Wright  * on the object.
1612148c5f43SAlan Wright  */
1613148c5f43SAlan Wright void *
1614148c5f43SAlan Wright smb_avl_iterate(smb_avl_t *avl, smb_avl_cursor_t *cursor)
1615148c5f43SAlan Wright {
1616148c5f43SAlan Wright 	void *node;
1617148c5f43SAlan Wright 
1618148c5f43SAlan Wright 	ASSERT(avl);
1619148c5f43SAlan Wright 	ASSERT(cursor);
1620148c5f43SAlan Wright 
1621148c5f43SAlan Wright 	if (!smb_avl_hold(avl))
1622148c5f43SAlan Wright 		return (NULL);
1623148c5f43SAlan Wright 
1624148c5f43SAlan Wright 	rw_enter(&avl->avl_lock, RW_READER);
1625148c5f43SAlan Wright 	if (cursor->avlc_sequence != avl->avl_sequence) {
1626148c5f43SAlan Wright 		rw_exit(&avl->avl_lock);
1627148c5f43SAlan Wright 		smb_avl_rele(avl);
1628148c5f43SAlan Wright 		return (NULL);
1629148c5f43SAlan Wright 	}
1630148c5f43SAlan Wright 
1631148c5f43SAlan Wright 	if (cursor->avlc_next == NULL)
1632148c5f43SAlan Wright 		node = avl_first(&avl->avl_tree);
1633148c5f43SAlan Wright 	else
1634148c5f43SAlan Wright 		node = AVL_NEXT(&avl->avl_tree, cursor->avlc_next);
1635148c5f43SAlan Wright 
1636148c5f43SAlan Wright 	if (node != NULL)
1637148c5f43SAlan Wright 		avl->avl_nops->avln_hold(node);
1638148c5f43SAlan Wright 
1639148c5f43SAlan Wright 	cursor->avlc_next = node;
1640148c5f43SAlan Wright 	rw_exit(&avl->avl_lock);
1641148c5f43SAlan Wright 
1642148c5f43SAlan Wright 	if (node == NULL)
1643148c5f43SAlan Wright 		smb_avl_rele(avl);
1644148c5f43SAlan Wright 
1645148c5f43SAlan Wright 	return (node);
1646148c5f43SAlan Wright }
1647148c5f43SAlan Wright 
1648148c5f43SAlan Wright /*
1649148c5f43SAlan Wright  * Increments the AVL reference count in order to
1650148c5f43SAlan Wright  * prevent the avl from being destroyed while it's
1651148c5f43SAlan Wright  * being accessed.
1652148c5f43SAlan Wright  */
1653148c5f43SAlan Wright static boolean_t
1654148c5f43SAlan Wright smb_avl_hold(smb_avl_t *avl)
1655148c5f43SAlan Wright {
1656148c5f43SAlan Wright 	mutex_enter(&avl->avl_mutex);
1657148c5f43SAlan Wright 	if (avl->avl_state != SMB_AVL_STATE_READY) {
1658148c5f43SAlan Wright 		mutex_exit(&avl->avl_mutex);
1659148c5f43SAlan Wright 		return (B_FALSE);
1660148c5f43SAlan Wright 	}
1661148c5f43SAlan Wright 	avl->avl_refcnt++;
1662148c5f43SAlan Wright 	mutex_exit(&avl->avl_mutex);
1663148c5f43SAlan Wright 
1664148c5f43SAlan Wright 	return (B_TRUE);
1665148c5f43SAlan Wright }
1666148c5f43SAlan Wright 
1667148c5f43SAlan Wright /*
1668148c5f43SAlan Wright  * Decrements the AVL reference count to release the
1669148c5f43SAlan Wright  * hold. If another thread is trying to destroy the
1670148c5f43SAlan Wright  * AVL and is waiting for the reference count to become
1671148c5f43SAlan Wright  * 0, it is signaled to wake up.
1672148c5f43SAlan Wright  */
1673148c5f43SAlan Wright static void
1674148c5f43SAlan Wright smb_avl_rele(smb_avl_t *avl)
1675148c5f43SAlan Wright {
1676148c5f43SAlan Wright 	mutex_enter(&avl->avl_mutex);
1677148c5f43SAlan Wright 	ASSERT(avl->avl_refcnt > 0);
1678148c5f43SAlan Wright 	avl->avl_refcnt--;
1679148c5f43SAlan Wright 	if (avl->avl_state == SMB_AVL_STATE_DESTROYING)
1680148c5f43SAlan Wright 		cv_broadcast(&avl->avl_cv);
1681148c5f43SAlan Wright 	mutex_exit(&avl->avl_mutex);
1682148c5f43SAlan Wright }
1683148c5f43SAlan Wright 
1684148c5f43SAlan Wright /*
1685148c5f43SAlan Wright  * smb_latency_init
1686148c5f43SAlan Wright  */
1687148c5f43SAlan Wright void
1688148c5f43SAlan Wright smb_latency_init(smb_latency_t *lat)
1689148c5f43SAlan Wright {
1690148c5f43SAlan Wright 	bzero(lat, sizeof (*lat));
1691148c5f43SAlan Wright 	mutex_init(&lat->ly_mutex, NULL, MUTEX_SPIN, (void *)ipltospl(SPL7));
1692148c5f43SAlan Wright }
1693148c5f43SAlan Wright 
1694148c5f43SAlan Wright /*
1695148c5f43SAlan Wright  * smb_latency_destroy
1696148c5f43SAlan Wright  */
1697148c5f43SAlan Wright void
1698148c5f43SAlan Wright smb_latency_destroy(smb_latency_t *lat)
1699148c5f43SAlan Wright {
1700148c5f43SAlan Wright 	mutex_destroy(&lat->ly_mutex);
1701148c5f43SAlan Wright }
1702148c5f43SAlan Wright 
1703148c5f43SAlan Wright /*
1704148c5f43SAlan Wright  * smb_latency_add_sample
1705148c5f43SAlan Wright  *
1706148c5f43SAlan Wright  * Uses the new sample to calculate the new mean and standard deviation. The
1707148c5f43SAlan Wright  * sample must be a scaled value.
1708148c5f43SAlan Wright  */
1709148c5f43SAlan Wright void
1710148c5f43SAlan Wright smb_latency_add_sample(smb_latency_t *lat, hrtime_t sample)
1711148c5f43SAlan Wright {
1712148c5f43SAlan Wright 	hrtime_t	a_mean;
1713148c5f43SAlan Wright 	hrtime_t	d_mean;
1714148c5f43SAlan Wright 
1715148c5f43SAlan Wright 	mutex_enter(&lat->ly_mutex);
1716148c5f43SAlan Wright 	lat->ly_a_nreq++;
1717148c5f43SAlan Wright 	lat->ly_a_sum += sample;
1718148c5f43SAlan Wright 	if (lat->ly_a_nreq != 0) {
1719148c5f43SAlan Wright 		a_mean = lat->ly_a_sum / lat->ly_a_nreq;
1720148c5f43SAlan Wright 		lat->ly_a_stddev =
1721148c5f43SAlan Wright 		    (sample - a_mean) * (sample - lat->ly_a_mean);
1722148c5f43SAlan Wright 		lat->ly_a_mean = a_mean;
1723148c5f43SAlan Wright 	}
1724148c5f43SAlan Wright 	lat->ly_d_nreq++;
1725148c5f43SAlan Wright 	lat->ly_d_sum += sample;
1726148c5f43SAlan Wright 	if (lat->ly_d_nreq != 0) {
1727148c5f43SAlan Wright 		d_mean = lat->ly_d_sum / lat->ly_d_nreq;
1728148c5f43SAlan Wright 		lat->ly_d_stddev =
1729148c5f43SAlan Wright 		    (sample - d_mean) * (sample - lat->ly_d_mean);
1730148c5f43SAlan Wright 		lat->ly_d_mean = d_mean;
1731148c5f43SAlan Wright 	}
1732148c5f43SAlan Wright 	mutex_exit(&lat->ly_mutex);
1733148c5f43SAlan Wright }
1734148c5f43SAlan Wright 
1735148c5f43SAlan Wright /*
1736148c5f43SAlan Wright  * smb_srqueue_init
1737148c5f43SAlan Wright  */
1738148c5f43SAlan Wright void
1739148c5f43SAlan Wright smb_srqueue_init(smb_srqueue_t *srq)
1740148c5f43SAlan Wright {
1741148c5f43SAlan Wright 	bzero(srq, sizeof (*srq));
1742148c5f43SAlan Wright 	mutex_init(&srq->srq_mutex, NULL, MUTEX_SPIN, (void *)ipltospl(SPL7));
1743148c5f43SAlan Wright 	srq->srq_wlastupdate = srq->srq_rlastupdate = gethrtime_unscaled();
1744148c5f43SAlan Wright }
1745148c5f43SAlan Wright 
1746148c5f43SAlan Wright /*
1747148c5f43SAlan Wright  * smb_srqueue_destroy
1748148c5f43SAlan Wright  */
1749148c5f43SAlan Wright void
1750148c5f43SAlan Wright smb_srqueue_destroy(smb_srqueue_t *srq)
1751148c5f43SAlan Wright {
1752148c5f43SAlan Wright 	mutex_destroy(&srq->srq_mutex);
1753148c5f43SAlan Wright }
1754148c5f43SAlan Wright 
1755148c5f43SAlan Wright /*
1756148c5f43SAlan Wright  * smb_srqueue_waitq_enter
1757148c5f43SAlan Wright  */
1758148c5f43SAlan Wright void
1759148c5f43SAlan Wright smb_srqueue_waitq_enter(smb_srqueue_t *srq)
1760148c5f43SAlan Wright {
1761148c5f43SAlan Wright 	hrtime_t	new;
1762148c5f43SAlan Wright 	hrtime_t	delta;
1763148c5f43SAlan Wright 	uint32_t	wcnt;
1764148c5f43SAlan Wright 
1765148c5f43SAlan Wright 	mutex_enter(&srq->srq_mutex);
1766148c5f43SAlan Wright 	new = gethrtime_unscaled();
1767148c5f43SAlan Wright 	delta = new - srq->srq_wlastupdate;
1768148c5f43SAlan Wright 	srq->srq_wlastupdate = new;
1769148c5f43SAlan Wright 	wcnt = srq->srq_wcnt++;
1770148c5f43SAlan Wright 	if (wcnt != 0) {
1771148c5f43SAlan Wright 		srq->srq_wlentime += delta * wcnt;
1772148c5f43SAlan Wright 		srq->srq_wtime += delta;
1773148c5f43SAlan Wright 	}
1774148c5f43SAlan Wright 	mutex_exit(&srq->srq_mutex);
1775148c5f43SAlan Wright }
1776148c5f43SAlan Wright 
1777148c5f43SAlan Wright /*
1778148c5f43SAlan Wright  * smb_srqueue_runq_exit
1779148c5f43SAlan Wright  */
1780148c5f43SAlan Wright void
1781148c5f43SAlan Wright smb_srqueue_runq_exit(smb_srqueue_t *srq)
1782148c5f43SAlan Wright {
1783148c5f43SAlan Wright 	hrtime_t	new;
1784148c5f43SAlan Wright 	hrtime_t	delta;
1785148c5f43SAlan Wright 	uint32_t	rcnt;
1786148c5f43SAlan Wright 
1787148c5f43SAlan Wright 	mutex_enter(&srq->srq_mutex);
1788148c5f43SAlan Wright 	new = gethrtime_unscaled();
1789148c5f43SAlan Wright 	delta = new - srq->srq_rlastupdate;
1790148c5f43SAlan Wright 	srq->srq_rlastupdate = new;
1791148c5f43SAlan Wright 	rcnt = srq->srq_rcnt--;
1792148c5f43SAlan Wright 	ASSERT(rcnt > 0);
1793148c5f43SAlan Wright 	srq->srq_rlentime += delta * rcnt;
1794148c5f43SAlan Wright 	srq->srq_rtime += delta;
1795148c5f43SAlan Wright 	mutex_exit(&srq->srq_mutex);
1796148c5f43SAlan Wright }
1797148c5f43SAlan Wright 
1798148c5f43SAlan Wright /*
1799148c5f43SAlan Wright  * smb_srqueue_waitq_to_runq
1800148c5f43SAlan Wright  */
1801148c5f43SAlan Wright void
1802148c5f43SAlan Wright smb_srqueue_waitq_to_runq(smb_srqueue_t *srq)
1803148c5f43SAlan Wright {
1804148c5f43SAlan Wright 	hrtime_t	new;
1805148c5f43SAlan Wright 	hrtime_t	delta;
1806148c5f43SAlan Wright 	uint32_t	wcnt;
1807148c5f43SAlan Wright 	uint32_t	rcnt;
1808148c5f43SAlan Wright 
1809148c5f43SAlan Wright 	mutex_enter(&srq->srq_mutex);
1810148c5f43SAlan Wright 	new = gethrtime_unscaled();
1811148c5f43SAlan Wright 	delta = new - srq->srq_wlastupdate;
1812148c5f43SAlan Wright 	srq->srq_wlastupdate = new;
1813148c5f43SAlan Wright 	wcnt = srq->srq_wcnt--;
1814148c5f43SAlan Wright 	ASSERT(wcnt > 0);
1815148c5f43SAlan Wright 	srq->srq_wlentime += delta * wcnt;
1816148c5f43SAlan Wright 	srq->srq_wtime += delta;
1817148c5f43SAlan Wright 	delta = new - srq->srq_rlastupdate;
1818148c5f43SAlan Wright 	srq->srq_rlastupdate = new;
1819148c5f43SAlan Wright 	rcnt = srq->srq_rcnt++;
1820148c5f43SAlan Wright 	if (rcnt != 0) {
1821148c5f43SAlan Wright 		srq->srq_rlentime += delta * rcnt;
1822148c5f43SAlan Wright 		srq->srq_rtime += delta;
1823148c5f43SAlan Wright 	}
1824148c5f43SAlan Wright 	mutex_exit(&srq->srq_mutex);
1825148c5f43SAlan Wright }
1826148c5f43SAlan Wright 
1827148c5f43SAlan Wright /*
1828148c5f43SAlan Wright  * smb_srqueue_update
1829148c5f43SAlan Wright  *
1830148c5f43SAlan Wright  * Takes a snapshot of the smb_sr_stat_t structure passed in.
1831148c5f43SAlan Wright  */
1832148c5f43SAlan Wright void
1833148c5f43SAlan Wright smb_srqueue_update(smb_srqueue_t *srq, smb_kstat_utilization_t *kd)
1834148c5f43SAlan Wright {
1835148c5f43SAlan Wright 	hrtime_t	delta;
1836148c5f43SAlan Wright 	hrtime_t	snaptime;
1837148c5f43SAlan Wright 
1838148c5f43SAlan Wright 	mutex_enter(&srq->srq_mutex);
1839148c5f43SAlan Wright 	snaptime = gethrtime_unscaled();
1840148c5f43SAlan Wright 	delta = snaptime - srq->srq_wlastupdate;
1841148c5f43SAlan Wright 	srq->srq_wlastupdate = snaptime;
1842148c5f43SAlan Wright 	if (srq->srq_wcnt != 0) {
1843148c5f43SAlan Wright 		srq->srq_wlentime += delta * srq->srq_wcnt;
1844148c5f43SAlan Wright 		srq->srq_wtime += delta;
1845148c5f43SAlan Wright 	}
1846148c5f43SAlan Wright 	delta = snaptime - srq->srq_rlastupdate;
1847148c5f43SAlan Wright 	srq->srq_rlastupdate = snaptime;
1848148c5f43SAlan Wright 	if (srq->srq_rcnt != 0) {
1849148c5f43SAlan Wright 		srq->srq_rlentime += delta * srq->srq_rcnt;
1850148c5f43SAlan Wright 		srq->srq_rtime += delta;
1851148c5f43SAlan Wright 	}
1852148c5f43SAlan Wright 	kd->ku_rlentime = srq->srq_rlentime;
1853148c5f43SAlan Wright 	kd->ku_rtime = srq->srq_rtime;
1854148c5f43SAlan Wright 	kd->ku_wlentime = srq->srq_wlentime;
1855148c5f43SAlan Wright 	kd->ku_wtime = srq->srq_wtime;
1856148c5f43SAlan Wright 	mutex_exit(&srq->srq_mutex);
1857148c5f43SAlan Wright 	scalehrtime(&kd->ku_rlentime);
1858148c5f43SAlan Wright 	scalehrtime(&kd->ku_rtime);
1859148c5f43SAlan Wright 	scalehrtime(&kd->ku_wlentime);
1860148c5f43SAlan Wright 	scalehrtime(&kd->ku_wtime);
1861148c5f43SAlan Wright }
1862cb174861Sjoyce mcintosh 
1863cb174861Sjoyce mcintosh void
1864856399cfSGordon Ross smb_threshold_init(smb_cmd_threshold_t *ct, char *cmd,
1865856399cfSGordon Ross     uint_t threshold, uint_t timeout)
1866cb174861Sjoyce mcintosh {
1867cb174861Sjoyce mcintosh 	bzero(ct, sizeof (smb_cmd_threshold_t));
1868cb174861Sjoyce mcintosh 	mutex_init(&ct->ct_mutex, NULL, MUTEX_DEFAULT, NULL);
1869856399cfSGordon Ross 	cv_init(&ct->ct_cond, NULL, CV_DEFAULT, NULL);
1870856399cfSGordon Ross 
1871cb174861Sjoyce mcintosh 	ct->ct_cmd = cmd;
1872cb174861Sjoyce mcintosh 	ct->ct_threshold = threshold;
1873856399cfSGordon Ross 	ct->ct_timeout = timeout;
1874cb174861Sjoyce mcintosh }
1875cb174861Sjoyce mcintosh 
1876cb174861Sjoyce mcintosh void
1877cb174861Sjoyce mcintosh smb_threshold_fini(smb_cmd_threshold_t *ct)
1878cb174861Sjoyce mcintosh {
1879856399cfSGordon Ross 	cv_destroy(&ct->ct_cond);
1880cb174861Sjoyce mcintosh 	mutex_destroy(&ct->ct_mutex);
1881cb174861Sjoyce mcintosh }
1882cb174861Sjoyce mcintosh 
1883cb174861Sjoyce mcintosh /*
1884856399cfSGordon Ross  * This threshold mechanism is used to limit the number of simultaneous
1885856399cfSGordon Ross  * named pipe connections, concurrent authentication conversations, etc.
1886856399cfSGordon Ross  * Requests that would take us over the threshold wait until either the
1887856399cfSGordon Ross  * resources are available (return zero) or timeout (return error).
1888cb174861Sjoyce mcintosh  */
1889cb174861Sjoyce mcintosh int
1890cb174861Sjoyce mcintosh smb_threshold_enter(smb_cmd_threshold_t *ct)
1891cb174861Sjoyce mcintosh {
1892856399cfSGordon Ross 	clock_t	time, rem;
1893cb174861Sjoyce mcintosh 
1894856399cfSGordon Ross 	time = MSEC_TO_TICK(ct->ct_timeout) + ddi_get_lbolt();
1895cb174861Sjoyce mcintosh 	mutex_enter(&ct->ct_mutex);
1896cb174861Sjoyce mcintosh 
1897856399cfSGordon Ross 	while (ct->ct_threshold != 0 &&
1898856399cfSGordon Ross 	    ct->ct_threshold <= ct->ct_active_cnt) {
1899856399cfSGordon Ross 		ct->ct_blocked_cnt++;
1900856399cfSGordon Ross 		rem = cv_timedwait(&ct->ct_cond, &ct->ct_mutex, time);
1901856399cfSGordon Ross 		ct->ct_blocked_cnt--;
1902856399cfSGordon Ross 		if (rem < 0) {
1903cb174861Sjoyce mcintosh 			mutex_exit(&ct->ct_mutex);
1904856399cfSGordon Ross 			return (ETIME);
1905cb174861Sjoyce mcintosh 		}
1906856399cfSGordon Ross 	}
1907856399cfSGordon Ross 	if (ct->ct_threshold == 0) {
1908cb174861Sjoyce mcintosh 		mutex_exit(&ct->ct_mutex);
1909856399cfSGordon Ross 		return (ECANCELED);
1910cb174861Sjoyce mcintosh 	}
1911cb174861Sjoyce mcintosh 
1912856399cfSGordon Ross 	ASSERT3U(ct->ct_active_cnt, <, ct->ct_threshold);
1913856399cfSGordon Ross 	ct->ct_active_cnt++;
1914cb174861Sjoyce mcintosh 
1915cb174861Sjoyce mcintosh 	mutex_exit(&ct->ct_mutex);
1916cb174861Sjoyce mcintosh 	return (0);
1917cb174861Sjoyce mcintosh }
1918cb174861Sjoyce mcintosh 
1919cb174861Sjoyce mcintosh void
1920856399cfSGordon Ross smb_threshold_exit(smb_cmd_threshold_t *ct)
1921cb174861Sjoyce mcintosh {
1922cb174861Sjoyce mcintosh 	mutex_enter(&ct->ct_mutex);
1923856399cfSGordon Ross 	ASSERT3U(ct->ct_active_cnt, >, 0);
1924856399cfSGordon Ross 	ct->ct_active_cnt--;
1925856399cfSGordon Ross 	if (ct->ct_blocked_cnt)
1926856399cfSGordon Ross 		cv_signal(&ct->ct_cond);
1927cb174861Sjoyce mcintosh 	mutex_exit(&ct->ct_mutex);
1928856399cfSGordon Ross }
1929856399cfSGordon Ross 
1930856399cfSGordon Ross void
1931856399cfSGordon Ross smb_threshold_wake_all(smb_cmd_threshold_t *ct)
1932856399cfSGordon Ross {
1933856399cfSGordon Ross 	mutex_enter(&ct->ct_mutex);
1934856399cfSGordon Ross 	ct->ct_threshold = 0;
1935856399cfSGordon Ross 	cv_broadcast(&ct->ct_cond);
1936856399cfSGordon Ross 	mutex_exit(&ct->ct_mutex);
1937cb174861Sjoyce mcintosh }
1938811599a4SMatt Barden 
1939811599a4SMatt Barden /* taken from mod_hash_byptr */
1940811599a4SMatt Barden uint_t
1941811599a4SMatt Barden smb_hash_uint64(smb_hash_t *hash, uint64_t val)
1942811599a4SMatt Barden {
1943811599a4SMatt Barden 	uint64_t k = val >> hash->rshift;
1944811599a4SMatt Barden 	uint_t idx = ((uint_t)k) & (hash->num_buckets - 1);
1945811599a4SMatt Barden 
1946811599a4SMatt Barden 	return (idx);
1947811599a4SMatt Barden }
1948811599a4SMatt Barden 
1949811599a4SMatt Barden boolean_t
1950811599a4SMatt Barden smb_is_pow2(size_t n)
1951811599a4SMatt Barden {
1952811599a4SMatt Barden 	return ((n & (n - 1)) == 0);
1953811599a4SMatt Barden }
1954811599a4SMatt Barden 
1955811599a4SMatt Barden smb_hash_t *
1956811599a4SMatt Barden smb_hash_create(size_t elemsz, size_t link_offset,
1957811599a4SMatt Barden     uint32_t num_buckets)
1958811599a4SMatt Barden {
1959811599a4SMatt Barden 	smb_hash_t *hash = kmem_alloc(sizeof (*hash), KM_SLEEP);
1960811599a4SMatt Barden 	int i;
1961811599a4SMatt Barden 
1962811599a4SMatt Barden 	if (!smb_is_pow2(num_buckets))
1963811599a4SMatt Barden 		num_buckets = 1 << highbit(num_buckets);
1964811599a4SMatt Barden 
1965811599a4SMatt Barden 	hash->rshift = highbit(elemsz);
1966811599a4SMatt Barden 	hash->num_buckets = num_buckets;
1967811599a4SMatt Barden 	hash->buckets = kmem_zalloc(num_buckets * sizeof (smb_bucket_t),
1968811599a4SMatt Barden 	    KM_SLEEP);
1969811599a4SMatt Barden 	for (i = 0; i < num_buckets; i++)
1970811599a4SMatt Barden 		smb_llist_constructor(&hash->buckets[i].b_list, elemsz,
1971811599a4SMatt Barden 		    link_offset);
1972811599a4SMatt Barden 	return (hash);
1973811599a4SMatt Barden }
1974811599a4SMatt Barden 
1975811599a4SMatt Barden void
1976811599a4SMatt Barden smb_hash_destroy(smb_hash_t *hash)
1977811599a4SMatt Barden {
1978811599a4SMatt Barden 	int i;
1979811599a4SMatt Barden 
1980811599a4SMatt Barden 	for (i = 0; i < hash->num_buckets; i++)
1981811599a4SMatt Barden 		smb_llist_destructor(&hash->buckets[i].b_list);
1982811599a4SMatt Barden 
1983811599a4SMatt Barden 	kmem_free(hash->buckets, hash->num_buckets * sizeof (smb_bucket_t));
1984811599a4SMatt Barden 	kmem_free(hash, sizeof (*hash));
1985811599a4SMatt Barden }
1986