xref: /illumos-gate/usr/src/uts/common/fs/smbsrv/smb_kutil.c (revision 8622ec4569457733001d4982ef7f5b44427069be)
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.
24c13be35aSGordon Ross  * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <sys/param.h>
289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <sys/types.h>
299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <sys/tzfile.h>
309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <sys/atomic.h>
319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <sys/kidmap.h>
329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <sys/time.h>
33148c5f43SAlan Wright #include <sys/spl.h>
349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <sys/cpuvar.h>
35148c5f43SAlan Wright #include <sys/random.h>
369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <smbsrv/smb_kproto.h>
379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <smbsrv/smb_fsops.h>
389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <smbsrv/smbinfo.h>
399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <smbsrv/smb_xdr.h>
409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <smbsrv/smb_vops.h>
419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <smbsrv/smb_idmap.h>
429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <sys/sid.h>
449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <sys/priv_names.h>
459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
46*8622ec45SGordon Ross static kmem_cache_t	*smb_dtor_cache = NULL;
479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static boolean_t smb_thread_continue_timedwait_locked(smb_thread_t *, int);
499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
50148c5f43SAlan Wright static boolean_t smb_avl_hold(smb_avl_t *);
51148c5f43SAlan Wright static void smb_avl_rele(smb_avl_t *);
52148c5f43SAlan Wright 
539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States time_t tzh_leapcnt = 0;
549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States struct tm
569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States *smb_gmtime_r(time_t *clock, struct tm *result);
579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States time_t
599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_timegm(struct tm *tm);
609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States struct	tm {
629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int	tm_sec;
639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int	tm_min;
649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int	tm_hour;
659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int	tm_mday;
669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int	tm_mon;
679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int	tm_year;
689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int	tm_wday;
699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int	tm_yday;
709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int	tm_isdst;
719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States };
729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
73*8622ec45SGordon Ross static const int days_in_month[] = {
749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States };
769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int
789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_ascii_or_unicode_strlen(struct smb_request *sr, char *str)
799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (sr->smb_flg2 & SMB_FLAGS2_UNICODE)
819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (smb_wcequiv_strlen(str));
829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (strlen(str));
839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int
869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_ascii_or_unicode_strlen_null(struct smb_request *sr, char *str)
879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (sr->smb_flg2 & SMB_FLAGS2_UNICODE)
899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (smb_wcequiv_strlen(str) + 2);
909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (strlen(str) + 1);
919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int
949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_ascii_or_unicode_null_len(struct smb_request *sr)
959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (sr->smb_flg2 & SMB_FLAGS2_UNICODE)
979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (2);
989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (1);
999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
1009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
1029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
103c13be35aSGordon Ross  * Convert old-style (DOS, LanMan) wildcard strings to NT style.
104c13be35aSGordon Ross  * This should ONLY happen to patterns that come from old clients,
105c13be35aSGordon Ross  * meaning dialect LANMAN2_1 etc. (dialect < NT_LM_0_12).
1069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
1079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *	? is converted to >
1089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *	* is converted to < if it is followed by .
109c13be35aSGordon Ross  *	. is converted to " if it is followed by ? or * or end of pattern
1109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
111c13be35aSGordon Ross  * Note: modifies pattern in place.
1129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
1139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
1149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_convert_wildcards(char *pattern)
1159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
1169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	char	*p;
1179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
118c13be35aSGordon Ross 	for (p = pattern; *p != '\0'; p++) {
1199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		switch (*p) {
120c13be35aSGordon Ross 		case '?':
121c13be35aSGordon Ross 			*p = '>';
1229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			break;
123c13be35aSGordon Ross 		case '*':
124c13be35aSGordon Ross 			if (p[1] == '.')
125c13be35aSGordon Ross 				*p = '<';
1269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			break;
127c13be35aSGordon Ross 		case '.':
128c13be35aSGordon Ross 			if (p[1] == '?' || p[1] == '*' || p[1] == '\0')
129c13be35aSGordon Ross 				*p = '\"';
1309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			break;
1319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
1329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
1339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
1349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
1369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_sattr_check
1379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
1389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Check file attributes against a search attribute (sattr) mask.
1399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
1409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Normal files, which includes READONLY and ARCHIVE, always pass
1419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * this check.  If the DIRECTORY, HIDDEN or SYSTEM special attributes
1429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * are set then they must appear in the search mask.  The special
1439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * attributes are inclusive, i.e. all special attributes that appear
1449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * in sattr must also appear in the file attributes for the check to
1459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * pass.
1469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
1479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * The following examples show how this works:
1489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
1499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *		fileA:	READONLY
1509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *		fileB:	0 (no attributes = normal file)
1519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *		fileC:	READONLY, ARCHIVE
1529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *		fileD:	HIDDEN
1539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *		fileE:	READONLY, HIDDEN, SYSTEM
1549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *		dirA:	DIRECTORY
1559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
1569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * search attribute: 0
1579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *		Returns: fileA, fileB and fileC.
1589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * search attribute: HIDDEN
1599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *		Returns: fileA, fileB, fileC and fileD.
1609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * search attribute: SYSTEM
1619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *		Returns: fileA, fileB and fileC.
1629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * search attribute: DIRECTORY
1639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *		Returns: fileA, fileB, fileC and dirA.
1649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * search attribute: HIDDEN and SYSTEM
1659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *		Returns: fileA, fileB, fileC, fileD and fileE.
1669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
1679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Returns true if the file and sattr match; otherwise, returns false.
1689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
1699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States boolean_t
1709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_sattr_check(uint16_t dosattr, uint16_t sattr)
1719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
1729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((dosattr & FILE_ATTRIBUTE_DIRECTORY) &&
1739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    !(sattr & FILE_ATTRIBUTE_DIRECTORY))
1749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (B_FALSE);
1759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((dosattr & FILE_ATTRIBUTE_HIDDEN) &&
1779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    !(sattr & FILE_ATTRIBUTE_HIDDEN))
1789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (B_FALSE);
1799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((dosattr & FILE_ATTRIBUTE_SYSTEM) &&
1819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    !(sattr & FILE_ATTRIBUTE_SYSTEM))
1829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (B_FALSE);
1839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (B_TRUE);
1859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
1869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int
1889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States microtime(timestruc_t *tvp)
1899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
1909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	tvp->tv_sec = gethrestime_sec();
1919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	tvp->tv_nsec = 0;
1929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (0);
1939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
1949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int32_t
1969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States clock_get_milli_uptime()
1979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
1989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (TICK_TO_MSEC(ddi_get_lbolt()));
1999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
2009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
2029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_idpool_increment
2039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
2049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function increments the ID pool by doubling the current size. This
2059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * function assumes the caller entered the mutex of the pool.
2069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
2079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static int
2089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_idpool_increment(
2099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_idpool_t	*pool)
2109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
2119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint8_t		*new_pool;
2129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint32_t	new_size;
2139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(pool->id_magic == SMB_IDPOOL_MAGIC);
2159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	new_size = pool->id_size * 2;
2179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (new_size <= SMB_IDPOOL_MAX_SIZE) {
2189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		new_pool = kmem_alloc(new_size / 8, KM_NOSLEEP);
2199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (new_pool) {
2209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			bzero(new_pool, new_size / 8);
2219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			bcopy(pool->id_pool, new_pool, pool->id_size / 8);
2229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			kmem_free(pool->id_pool, pool->id_size / 8);
2239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			pool->id_pool = new_pool;
2249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			pool->id_free_counter += new_size - pool->id_size;
2259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			pool->id_max_free_counter += new_size - pool->id_size;
2269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			pool->id_size = new_size;
2279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			pool->id_idx_msk = (new_size / 8) - 1;
2289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			if (new_size >= SMB_IDPOOL_MAX_SIZE) {
2299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				/* id -1 made unavailable */
2309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				pool->id_pool[pool->id_idx_msk] = 0x80;
2319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				pool->id_free_counter--;
2329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				pool->id_max_free_counter--;
2339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			}
2349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (0);
2359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
2369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
2379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (-1);
2389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
2399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
2419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_idpool_constructor
2429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
2439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function initializes the pool structure provided.
2449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
2459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int
2469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_idpool_constructor(
2479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_idpool_t	*pool)
2489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
2499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(pool->id_magic != SMB_IDPOOL_MAGIC);
2519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	pool->id_size = SMB_IDPOOL_MIN_SIZE;
2539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	pool->id_idx_msk = (SMB_IDPOOL_MIN_SIZE / 8) - 1;
2549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	pool->id_free_counter = SMB_IDPOOL_MIN_SIZE - 1;
2559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	pool->id_max_free_counter = SMB_IDPOOL_MIN_SIZE - 1;
2569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	pool->id_bit = 0x02;
2579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	pool->id_bit_idx = 1;
2589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	pool->id_idx = 0;
2599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	pool->id_pool = (uint8_t *)kmem_alloc((SMB_IDPOOL_MIN_SIZE / 8),
2609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    KM_SLEEP);
2619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	bzero(pool->id_pool, (SMB_IDPOOL_MIN_SIZE / 8));
2629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	/* -1 id made unavailable */
2639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	pool->id_pool[0] = 0x01;		/* id 0 made unavailable */
2649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_init(&pool->id_mutex, NULL, MUTEX_DEFAULT, NULL);
2659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	pool->id_magic = SMB_IDPOOL_MAGIC;
2669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (0);
2679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
2689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
2709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_idpool_destructor
2719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
2729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function tears down and frees the resources associated with the
2739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * pool provided.
2749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
2759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
2769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_idpool_destructor(
2779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_idpool_t	*pool)
2789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
2799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(pool->id_magic == SMB_IDPOOL_MAGIC);
2809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(pool->id_free_counter == pool->id_max_free_counter);
2819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	pool->id_magic = (uint32_t)~SMB_IDPOOL_MAGIC;
2829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_destroy(&pool->id_mutex);
2839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	kmem_free(pool->id_pool, (size_t)(pool->id_size / 8));
2849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
2859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
2879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_idpool_alloc
2889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
2899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function allocates an ID from the pool provided.
2909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
2919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int
2929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_idpool_alloc(
2939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_idpool_t	*pool,
2949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     uint16_t		*id)
2959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
2969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint32_t	i;
2979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint8_t		bit;
2989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint8_t		bit_idx;
2999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint8_t		byte;
3009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(pool->id_magic == SMB_IDPOOL_MAGIC);
3029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&pool->id_mutex);
3049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((pool->id_free_counter == 0) && smb_idpool_increment(pool)) {
3059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		mutex_exit(&pool->id_mutex);
3069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (-1);
3079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
3089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	i = pool->id_size;
3109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	while (i) {
3119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		bit = pool->id_bit;
3129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		bit_idx = pool->id_bit_idx;
3139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		byte = pool->id_pool[pool->id_idx];
3149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		while (bit) {
3159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			if (byte & bit) {
3169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				bit = bit << 1;
3179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				bit_idx++;
3189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				continue;
3199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			}
3209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			pool->id_pool[pool->id_idx] |= bit;
3219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			*id = (uint16_t)(pool->id_idx * 8 + (uint32_t)bit_idx);
3229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			pool->id_free_counter--;
3239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			pool->id_bit = bit;
3249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			pool->id_bit_idx = bit_idx;
3259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			mutex_exit(&pool->id_mutex);
3269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (0);
3279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
3289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		pool->id_bit = 1;
3299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		pool->id_bit_idx = 0;
3309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		pool->id_idx++;
3319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		pool->id_idx &= pool->id_idx_msk;
3329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		--i;
3339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
3349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	/*
3359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	 * This section of code shouldn't be reached. If there are IDs
3369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	 * available and none could be found there's a problem.
3379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	 */
3389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(0);
3399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&pool->id_mutex);
3409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (-1);
3419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
3429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
3449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_idpool_free
3459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
3469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function frees the ID provided.
3479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
3489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
3499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_idpool_free(
3509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_idpool_t	*pool,
3519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     uint16_t		id)
3529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
3539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(pool->id_magic == SMB_IDPOOL_MAGIC);
3549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(id != 0);
3559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(id != 0xFFFF);
3569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&pool->id_mutex);
3589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (pool->id_pool[id >> 3] & (1 << (id & 7))) {
3599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		pool->id_pool[id >> 3] &= ~(1 << (id & 7));
3609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		pool->id_free_counter++;
3619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		ASSERT(pool->id_free_counter <= pool->id_max_free_counter);
3629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		mutex_exit(&pool->id_mutex);
3639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return;
3649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
3659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	/* Freeing a free ID. */
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 }
3699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
3719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Initialize the llist delete queue object cache.
3729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
3739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
3749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_init(void)
3759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
376*8622ec45SGordon Ross 	if (smb_dtor_cache != NULL)
3779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return;
3789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_dtor_cache = kmem_cache_create("smb_dtor_cache",
3809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    sizeof (smb_dtor_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
3819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
3829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
3849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Destroy the llist delete queue object cache.
3859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
3869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
3879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_fini(void)
3889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
389*8622ec45SGordon Ross 	if (smb_dtor_cache != NULL) {
3909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		kmem_cache_destroy(smb_dtor_cache);
391*8622ec45SGordon Ross 		smb_dtor_cache = NULL;
392*8622ec45SGordon Ross 	}
3939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
3949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
3969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_llist_constructor
3979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
3989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function initializes a locked list.
3999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
4009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
4019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_constructor(
4029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_llist_t	*ll,
4039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     size_t	size,
4049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     size_t	offset)
4059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
4069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	rw_init(&ll->ll_lock, NULL, RW_DEFAULT, NULL);
4079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_init(&ll->ll_mutex, NULL, MUTEX_DEFAULT, NULL);
4089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	list_create(&ll->ll_list, size, offset);
4099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	list_create(&ll->ll_deleteq, sizeof (smb_dtor_t),
4109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    offsetof(smb_dtor_t, dt_lnd));
4119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ll->ll_count = 0;
4129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ll->ll_wrop = 0;
4139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ll->ll_deleteq_count = 0;
414cb174861Sjoyce mcintosh 	ll->ll_flushing = B_FALSE;
4159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
4169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
4179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
4189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Flush the delete queue and destroy a locked list.
4199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
4209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
4219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_destructor(
4229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_llist_t	*ll)
4239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
4249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_llist_flush(ll);
4259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
4269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(ll->ll_count == 0);
4279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(ll->ll_deleteq_count == 0);
4289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
4299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	rw_destroy(&ll->ll_lock);
4309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	list_destroy(&ll->ll_list);
4319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	list_destroy(&ll->ll_deleteq);
4329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_destroy(&ll->ll_mutex);
4339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
4349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
4359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
4369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Post an object to the delete queue.  The delete queue will be processed
4379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * during list exit or list destruction.  Objects are often posted for
4389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * deletion during list iteration (while the list is locked) but that is
4399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * not required, and an object can be posted at any time.
4409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
4419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
4429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_post(smb_llist_t *ll, void *object, smb_dtorproc_t dtorproc)
4439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
4449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_dtor_t	*dtor;
4459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
4469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT((object != NULL) && (dtorproc != NULL));
4479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
4489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	dtor = kmem_cache_alloc(smb_dtor_cache, KM_SLEEP);
4499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	bzero(dtor, sizeof (smb_dtor_t));
4509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	dtor->dt_magic = SMB_DTOR_MAGIC;
4519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	dtor->dt_object = object;
4529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	dtor->dt_proc = dtorproc;
4539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
4549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&ll->ll_mutex);
4559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	list_insert_tail(&ll->ll_deleteq, dtor);
4569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	++ll->ll_deleteq_count;
4579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&ll->ll_mutex);
4589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
4599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
4609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
4619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Exit the list lock and process the delete queue.
4629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
4639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
4649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_exit(smb_llist_t *ll)
4659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
4669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	rw_exit(&ll->ll_lock);
4679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_llist_flush(ll);
4689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
4699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
4709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
4719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Flush the list delete queue.  The mutex is dropped across the destructor
4729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * call in case this leads to additional objects being posted to the delete
4739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * queue.
4749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
475c5866007SKeyur Desai void
4769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_flush(smb_llist_t *ll)
4779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
4789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_dtor_t    *dtor;
4799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
4809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&ll->ll_mutex);
481cb174861Sjoyce mcintosh 	if (ll->ll_flushing) {
482cb174861Sjoyce mcintosh 		mutex_exit(&ll->ll_mutex);
483cb174861Sjoyce mcintosh 		return;
484cb174861Sjoyce mcintosh 	}
485cb174861Sjoyce mcintosh 	ll->ll_flushing = B_TRUE;
4869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
4879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	dtor = list_head(&ll->ll_deleteq);
4889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	while (dtor != NULL) {
4899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		SMB_DTOR_VALID(dtor);
4909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		ASSERT((dtor->dt_object != NULL) && (dtor->dt_proc != NULL));
4919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		list_remove(&ll->ll_deleteq, dtor);
4929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		--ll->ll_deleteq_count;
4939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		mutex_exit(&ll->ll_mutex);
4949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
4959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		dtor->dt_proc(dtor->dt_object);
4969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
4979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		dtor->dt_magic = (uint32_t)~SMB_DTOR_MAGIC;
4989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		kmem_cache_free(smb_dtor_cache, dtor);
4999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		mutex_enter(&ll->ll_mutex);
5009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		dtor = list_head(&ll->ll_deleteq);
5019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
502cb174861Sjoyce mcintosh 	ll->ll_flushing = B_FALSE;
5039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
5049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&ll->ll_mutex);
5059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
5069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
5079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
5089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_llist_upgrade
5099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
5109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function tries to upgrade the lock of the locked list. It assumes the
5119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * locked has already been entered in RW_READER mode. It first tries using the
5129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Solaris function rw_tryupgrade(). If that call fails the lock is released
5139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * and reentered in RW_WRITER mode. In that last case a window is opened during
5149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * which the contents of the list may have changed. The return code indicates
5159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * whether or not the list was modified when the lock was exited.
5169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
5179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int smb_llist_upgrade(
5189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_llist_t *ll)
5199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
5209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint64_t	wrop;
5219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
5229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (rw_tryupgrade(&ll->ll_lock) != 0) {
5239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (0);
5249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
5259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	wrop = ll->ll_wrop;
5269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	rw_exit(&ll->ll_lock);
5279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	rw_enter(&ll->ll_lock, RW_WRITER);
5289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (wrop != ll->ll_wrop);
5299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
5309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
5319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
5329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_llist_insert_head
5339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
5349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function inserts the object passed a the beginning of the list. This
5359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * function assumes the lock of the list has already been entered.
5369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
5379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
5389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_insert_head(
5399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_llist_t	*ll,
5409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     void	*obj)
5419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
5429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	list_insert_head(&ll->ll_list, obj);
5439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	++ll->ll_wrop;
5449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	++ll->ll_count;
5459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
5469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
5479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
5489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_llist_insert_tail
5499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
5509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function appends to the object passed to the list. This function assumes
5519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * the lock of the list has already been entered.
5529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
5539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
5549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
5559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_insert_tail(
5569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_llist_t	*ll,
5579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     void	*obj)
5589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
5599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	list_insert_tail(&ll->ll_list, obj);
5609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	++ll->ll_wrop;
5619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	++ll->ll_count;
5629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
5639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
5649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
5659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_llist_remove
5669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
5679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function removes the object passed from the list. This function assumes
5689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * the lock of the list has already been entered.
5699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
5709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
5719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_remove(
5729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_llist_t	*ll,
5739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     void	*obj)
5749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
5759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	list_remove(&ll->ll_list, obj);
5769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	++ll->ll_wrop;
5779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	--ll->ll_count;
5789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
5799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
5809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
5819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_llist_get_count
5829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
5839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function returns the number of elements in the specified list.
5849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
5859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States uint32_t
5869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_get_count(
5879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_llist_t *ll)
5889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
5899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (ll->ll_count);
5909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
5919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
5929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
5939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_slist_constructor
5949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
5959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Synchronized list constructor.
5969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
5979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
5989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_slist_constructor(
5999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_slist_t	*sl,
6009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     size_t	size,
6019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     size_t	offset)
6029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
6039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_init(&sl->sl_mutex, NULL, MUTEX_DEFAULT, NULL);
6049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	cv_init(&sl->sl_cv, NULL, CV_DEFAULT, NULL);
6059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	list_create(&sl->sl_list, size, offset);
6069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	sl->sl_count = 0;
6079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	sl->sl_waiting = B_FALSE;
6089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
6099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
6119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_slist_destructor
6129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
6139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Synchronized list destructor.
6149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
6159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
6169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_slist_destructor(
6179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_slist_t	*sl)
6189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
619148c5f43SAlan Wright 	VERIFY(sl->sl_count == 0);
6209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_destroy(&sl->sl_mutex);
6229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	cv_destroy(&sl->sl_cv);
6239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	list_destroy(&sl->sl_list);
6249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
6259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
6279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_slist_insert_head
6289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
6299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function inserts the object passed a the beginning of the list.
6309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
6319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
6329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_slist_insert_head(
6339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_slist_t	*sl,
6349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     void	*obj)
6359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
6369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&sl->sl_mutex);
6379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	list_insert_head(&sl->sl_list, obj);
6389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	++sl->sl_count;
6399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&sl->sl_mutex);
6409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
6419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
6439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_slist_insert_tail
6449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
6459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function appends the object passed to the list.
6469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
6479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
6489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_slist_insert_tail(
6499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_slist_t	*sl,
6509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     void	*obj)
6519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
6529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&sl->sl_mutex);
6539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	list_insert_tail(&sl->sl_list, obj);
6549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	++sl->sl_count;
6559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&sl->sl_mutex);
6569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
6579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
6599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_llist_remove
6609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
6619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function removes the object passed by the caller from the list.
6629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
6639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
6649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_slist_remove(
6659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_slist_t	*sl,
6669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     void	*obj)
6679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
6689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&sl->sl_mutex);
6699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	list_remove(&sl->sl_list, obj);
6709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((--sl->sl_count == 0) && (sl->sl_waiting)) {
6719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sl->sl_waiting = B_FALSE;
6729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		cv_broadcast(&sl->sl_cv);
6739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
6749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&sl->sl_mutex);
6759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
6769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
6789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_slist_move_tail
6799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
6809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function transfers all the contents of the synchronized list to the
6819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * list_t provided. It returns the number of objects transferred.
6829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
6839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States uint32_t
6849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_slist_move_tail(
6859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     list_t	*lst,
6869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_slist_t	*sl)
6879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
6889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint32_t	rv;
6899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&sl->sl_mutex);
6919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	rv = sl->sl_count;
6929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (sl->sl_count) {
6939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		list_move_tail(lst, &sl->sl_list);
6949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sl->sl_count = 0;
6959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (sl->sl_waiting) {
6969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			sl->sl_waiting = B_FALSE;
6979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			cv_broadcast(&sl->sl_cv);
6989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
6999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
7009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&sl->sl_mutex);
7019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (rv);
7029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
7039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
7049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
7059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_slist_obj_move
7069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
7079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function moves an object from one list to the end of the other list. It
7089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * assumes the mutex of each list has been entered.
7099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
7109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
7119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_slist_obj_move(
7129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_slist_t	*dst,
7139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_slist_t	*src,
7149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     void	*obj)
7159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
7169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(dst->sl_list.list_offset == src->sl_list.list_offset);
7179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(dst->sl_list.list_size == src->sl_list.list_size);
7189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
7199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	list_remove(&src->sl_list, obj);
7209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	list_insert_tail(&dst->sl_list, obj);
7219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	dst->sl_count++;
7229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	src->sl_count--;
7239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((src->sl_count == 0) && (src->sl_waiting)) {
7249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		src->sl_waiting = B_FALSE;
7259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		cv_broadcast(&src->sl_cv);
7269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
7279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
7289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
7299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
7309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_slist_wait_for_empty
7319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
7329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function waits for a list to be emptied.
7339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
7349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
7359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_slist_wait_for_empty(
7369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_slist_t	*sl)
7379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
7389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&sl->sl_mutex);
7399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	while (sl->sl_count) {
7409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sl->sl_waiting = B_TRUE;
7419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		cv_wait(&sl->sl_cv, &sl->sl_mutex);
7429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
7439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&sl->sl_mutex);
7449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
7459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
7469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
7479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_slist_exit
7489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
7499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function exits the muetx of the list and signal the condition variable
7509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * if the list is empty.
7519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
7529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
7539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_slist_exit(smb_slist_t *sl)
7549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
7559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((sl->sl_count == 0) && (sl->sl_waiting)) {
7569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sl->sl_waiting = B_FALSE;
7579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		cv_broadcast(&sl->sl_cv);
7589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
7599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&sl->sl_mutex);
7609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
7619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
7629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
7639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_thread_entry_point
7649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
7659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Common entry point for all the threads created through smb_thread_start.
7669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * The state of the thread is set to "running" at the beginning and moved to
7679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * "exiting" just before calling thread_exit(). The condition variable is
7689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *  also signaled.
7699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
7709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void
7719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_thread_entry_point(
7729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_thread_t	*thread)
7739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
7749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(thread->sth_magic == SMB_THREAD_MAGIC);
7759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&thread->sth_mtx);
7769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(thread->sth_state == SMB_THREAD_STATE_STARTING);
7779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	thread->sth_th = curthread;
7789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	thread->sth_did = thread->sth_th->t_did;
7799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
7809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!thread->sth_kill) {
7819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		thread->sth_state = SMB_THREAD_STATE_RUNNING;
7829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		cv_signal(&thread->sth_cv);
7839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		mutex_exit(&thread->sth_mtx);
7849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		thread->sth_ep(thread, thread->sth_ep_arg);
7859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		mutex_enter(&thread->sth_mtx);
7869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
7879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	thread->sth_th = NULL;
7889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	thread->sth_state = SMB_THREAD_STATE_EXITING;
7899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	cv_broadcast(&thread->sth_cv);
7909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&thread->sth_mtx);
791*8622ec45SGordon Ross 	zthread_exit();
7929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
7939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
7949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
7959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_thread_init
7969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
7979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
7989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_thread_init(
7999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_thread_t	*thread,
8009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     char		*name,
8019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_thread_ep_t	ep,
80208344b29SGordon Ross     void		*ep_arg,
80308344b29SGordon Ross     pri_t		pri)
8049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
8059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(thread->sth_magic != SMB_THREAD_MAGIC);
8069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
8079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	bzero(thread, sizeof (*thread));
8089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
8099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) strlcpy(thread->sth_name, name, sizeof (thread->sth_name));
8109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	thread->sth_ep = ep;
8119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	thread->sth_ep_arg = ep_arg;
8129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	thread->sth_state = SMB_THREAD_STATE_EXITED;
81308344b29SGordon Ross 	thread->sth_pri = pri;
8149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_init(&thread->sth_mtx, NULL, MUTEX_DEFAULT, NULL);
8159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	cv_init(&thread->sth_cv, NULL, CV_DEFAULT, NULL);
8169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	thread->sth_magic = SMB_THREAD_MAGIC;
8179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
8189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
8199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
8209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_thread_destroy
8219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
8229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
8239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_thread_destroy(
8249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_thread_t	*thread)
8259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
8269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(thread->sth_magic == SMB_THREAD_MAGIC);
8279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(thread->sth_state == SMB_THREAD_STATE_EXITED);
8289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	thread->sth_magic = 0;
8299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_destroy(&thread->sth_mtx);
8309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	cv_destroy(&thread->sth_cv);
8319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
8329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
8339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
8349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_thread_start
8359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
8369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function starts a thread with the parameters provided. It waits until
8379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * the state of the thread has been moved to running.
8389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
8399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*ARGSUSED*/
8409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int
8419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_thread_start(
8429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_thread_t	*thread)
8439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
8449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int		rc = 0;
8459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	kthread_t	*tmpthread;
8469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
8479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(thread->sth_magic == SMB_THREAD_MAGIC);
8489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
8499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&thread->sth_mtx);
8509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	switch (thread->sth_state) {
8519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_THREAD_STATE_EXITED:
8529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		thread->sth_state = SMB_THREAD_STATE_STARTING;
8539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		mutex_exit(&thread->sth_mtx);
854*8622ec45SGordon Ross 		tmpthread = zthread_create(NULL, 0, smb_thread_entry_point,
855*8622ec45SGordon Ross 		    thread, 0, thread->sth_pri);
8569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		ASSERT(tmpthread != NULL);
8579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		mutex_enter(&thread->sth_mtx);
8589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		while (thread->sth_state == SMB_THREAD_STATE_STARTING)
8599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			cv_wait(&thread->sth_cv, &thread->sth_mtx);
8609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (thread->sth_state != SMB_THREAD_STATE_RUNNING)
8619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			rc = -1;
8629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
8639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	default:
8649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		ASSERT(0);
8659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		rc = -1;
8669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
8679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
8689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&thread->sth_mtx);
8699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (rc);
8709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
8719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
8729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
8739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_thread_stop
8749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
8759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function signals a thread to kill itself and waits until the "exiting"
8769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * state has been reached.
8779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
8789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
8794163af6aSjose borrego smb_thread_stop(smb_thread_t *thread)
8809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
8819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(thread->sth_magic == SMB_THREAD_MAGIC);
8829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
8839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&thread->sth_mtx);
8849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	switch (thread->sth_state) {
8859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_THREAD_STATE_RUNNING:
8869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_THREAD_STATE_STARTING:
8879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (!thread->sth_kill) {
8889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			thread->sth_kill = B_TRUE;
8899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			cv_broadcast(&thread->sth_cv);
8909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			while (thread->sth_state != SMB_THREAD_STATE_EXITING)
8919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				cv_wait(&thread->sth_cv, &thread->sth_mtx);
8929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			mutex_exit(&thread->sth_mtx);
8939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			thread_join(thread->sth_did);
8949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			mutex_enter(&thread->sth_mtx);
8959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			thread->sth_state = SMB_THREAD_STATE_EXITED;
8969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			thread->sth_did = 0;
8979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			thread->sth_kill = B_FALSE;
8989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			cv_broadcast(&thread->sth_cv);
8999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			break;
9009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
9019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		/*FALLTHRU*/
9029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_THREAD_STATE_EXITING:
9049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (thread->sth_kill) {
9059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			while (thread->sth_state != SMB_THREAD_STATE_EXITED)
9069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				cv_wait(&thread->sth_cv, &thread->sth_mtx);
9079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		} else {
9089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			thread->sth_state = SMB_THREAD_STATE_EXITED;
9099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			thread->sth_did = 0;
9109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
9119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
9129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_THREAD_STATE_EXITED:
9149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
9159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	default:
9179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		ASSERT(0);
9189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
9199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
9209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&thread->sth_mtx);
9219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
9229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
9249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_thread_signal
9259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
9269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function signals a thread.
9279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
9289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
9294163af6aSjose borrego smb_thread_signal(smb_thread_t *thread)
9309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
9319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(thread->sth_magic == SMB_THREAD_MAGIC);
9329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&thread->sth_mtx);
9349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	switch (thread->sth_state) {
9359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_THREAD_STATE_RUNNING:
9369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		cv_signal(&thread->sth_cv);
9379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
9389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	default:
9409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
9419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
9429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&thread->sth_mtx);
9439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
9449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States boolean_t
9469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_thread_continue(smb_thread_t *thread)
9479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
9489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	boolean_t result;
9499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(thread->sth_magic == SMB_THREAD_MAGIC);
9519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&thread->sth_mtx);
9539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	result = smb_thread_continue_timedwait_locked(thread, 0);
9549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&thread->sth_mtx);
9559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (result);
9579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
9589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States boolean_t
9609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_thread_continue_nowait(smb_thread_t *thread)
9619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
9629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	boolean_t result;
9639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(thread->sth_magic == SMB_THREAD_MAGIC);
9659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&thread->sth_mtx);
9679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	/*
9689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	 * Setting ticks=-1 requests a non-blocking check.  We will
9699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	 * still block if the thread is in "suspend" state.
9709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	 */
9719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	result = smb_thread_continue_timedwait_locked(thread, -1);
9729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&thread->sth_mtx);
9739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (result);
9759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
9769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States boolean_t
9789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_thread_continue_timedwait(smb_thread_t *thread, int seconds)
9799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
9809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	boolean_t result;
9819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(thread->sth_magic == SMB_THREAD_MAGIC);
9839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&thread->sth_mtx);
9859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	result = smb_thread_continue_timedwait_locked(thread,
9869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    SEC_TO_TICK(seconds));
9879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&thread->sth_mtx);
9889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (result);
9909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
9919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
9939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_thread_continue_timedwait_locked
9949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
9959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Internal only.  Ticks==-1 means don't block, Ticks == 0 means wait
9969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * indefinitely
9979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
9989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static boolean_t
9999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_thread_continue_timedwait_locked(smb_thread_t *thread, int ticks)
10009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
10019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	boolean_t	result;
10029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
10039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	/* -1 means don't block */
10049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (ticks != -1 && !thread->sth_kill) {
10059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (ticks == 0) {
10069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			cv_wait(&thread->sth_cv, &thread->sth_mtx);
10079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		} else {
10089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			(void) cv_reltimedwait(&thread->sth_cv,
10099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			    &thread->sth_mtx, (clock_t)ticks, TR_CLOCK_TICK);
10109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
10119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
10129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	result = (thread->sth_kill == 0);
10139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
10149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (result);
10159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
10169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
10179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
10189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_rwx_init
10199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
10209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
10219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_rwx_init(
10229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_rwx_t	*rwx)
10239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
10249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	bzero(rwx, sizeof (smb_rwx_t));
10259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	cv_init(&rwx->rwx_cv, NULL, CV_DEFAULT, NULL);
10269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_init(&rwx->rwx_mutex, NULL, MUTEX_DEFAULT, NULL);
10279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	rw_init(&rwx->rwx_lock, NULL, RW_DEFAULT, NULL);
10289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
10299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
10309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
10319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_rwx_destroy
10329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
10339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
10349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_rwx_destroy(
10359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_rwx_t	*rwx)
10369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
10379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_destroy(&rwx->rwx_mutex);
10389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	cv_destroy(&rwx->rwx_cv);
10399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	rw_destroy(&rwx->rwx_lock);
10409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
10419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
10429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
10439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_rwx_rwexit
10449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
10459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
10469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_rwx_rwexit(
10479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_rwx_t	*rwx)
10489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
10499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (rw_write_held(&rwx->rwx_lock)) {
10509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		ASSERT(rw_owner(&rwx->rwx_lock) == curthread);
10519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		mutex_enter(&rwx->rwx_mutex);
10529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (rwx->rwx_waiting) {
10539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			rwx->rwx_waiting = B_FALSE;
10549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			cv_broadcast(&rwx->rwx_cv);
10559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
10569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		mutex_exit(&rwx->rwx_mutex);
10579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
10589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	rw_exit(&rwx->rwx_lock);
10599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
10609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
10619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
10629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_rwx_rwupgrade
10639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
10649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States krw_t
10659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_rwx_rwupgrade(
10669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_rwx_t	*rwx)
10679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
10689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (rw_write_held(&rwx->rwx_lock)) {
10699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		ASSERT(rw_owner(&rwx->rwx_lock) == curthread);
10709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (RW_WRITER);
10719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
10729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!rw_tryupgrade(&rwx->rwx_lock)) {
10739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		rw_exit(&rwx->rwx_lock);
10749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		rw_enter(&rwx->rwx_lock, RW_WRITER);
10759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
10769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (RW_READER);
10779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
10789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
10799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
10809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_rwx_rwrestore
10819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
10829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
10839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_rwx_rwdowngrade(
10849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_rwx_t	*rwx,
10859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     krw_t	mode)
10869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
10879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(rw_write_held(&rwx->rwx_lock));
10889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(rw_owner(&rwx->rwx_lock) == curthread);
10899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
10909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (mode == RW_WRITER) {
10919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return;
10929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
10939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(mode == RW_READER);
10949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&rwx->rwx_mutex);
10959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (rwx->rwx_waiting) {
10969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		rwx->rwx_waiting = B_FALSE;
10979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		cv_broadcast(&rwx->rwx_cv);
10989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
10999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&rwx->rwx_mutex);
11009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	rw_downgrade(&rwx->rwx_lock);
11019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
11029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
11049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_rwx_wait
11059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
11069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This function assumes the smb_rwx lock was enter in RW_READER or RW_WRITER
11079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * mode. It will:
11089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
11099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *	1) release the lock and save its current mode.
11109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *	2) wait until the condition variable is signaled. This can happen for
11119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *	   2 reasons: When a writer releases the lock or when the time out (if
11129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *	   provided) expires.
11139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *	3) re-acquire the lock in the mode saved in (1).
11149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
11159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int
11169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_rwx_rwwait(
11179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_rwx_t	*rwx,
11189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     clock_t	timeout)
11199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
11209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int	rc;
11219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	krw_t	mode;
11229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&rwx->rwx_mutex);
11249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	rwx->rwx_waiting = B_TRUE;
11259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&rwx->rwx_mutex);
11269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (rw_write_held(&rwx->rwx_lock)) {
11289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		ASSERT(rw_owner(&rwx->rwx_lock) == curthread);
11299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		mode = RW_WRITER;
11309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	} else {
11319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		ASSERT(rw_read_held(&rwx->rwx_lock));
11329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		mode = RW_READER;
11339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
11349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	rw_exit(&rwx->rwx_lock);
11359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&rwx->rwx_mutex);
11379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (rwx->rwx_waiting) {
11389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (timeout == -1) {
11399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			rc = 1;
11409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			cv_wait(&rwx->rwx_cv, &rwx->rwx_mutex);
11419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		} else {
11429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			rc = cv_reltimedwait(&rwx->rwx_cv, &rwx->rwx_mutex,
11439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			    timeout, TR_CLOCK_TICK);
11449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
11459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
11469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&rwx->rwx_mutex);
11479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	rw_enter(&rwx->rwx_lock, mode);
11499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (rc);
11509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
11519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
11539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * SMB ID mapping
11549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
11559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Solaris ID mapping service (aka Winchester) works with domain SIDs
11569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * and RIDs where domain SIDs are in string format. CIFS service works
11579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * with binary SIDs understandable by CIFS clients. A layer of SMB ID
11589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * mapping functions are implemeted to hide the SID conversion details
11599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * and also hide the handling of array of batch mapping requests.
11609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
11619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * IMPORTANT NOTE The Winchester API requires a zone. Because CIFS server
11629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * currently only runs in the global zone the global zone is specified.
11639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * This needs to be fixed when the CIFS server supports zones.
11649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
11659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static int smb_idmap_batch_binsid(smb_idmap_batch_t *sib);
11679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
11699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_idmap_getid
11709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
11719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Maps the given Windows SID to a Solaris ID using the
11729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * simple mapping API.
11739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
11749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States idmap_stat
11759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_idmap_getid(smb_sid_t *sid, uid_t *id, int *idtype)
11769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
11779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_idmap_t sim;
11789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	char sidstr[SMB_SID_STRSZ];
11799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_sid_tostr(sid, sidstr);
11819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_sid_splitstr(sidstr, &sim.sim_rid) != 0)
11829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (IDMAP_ERR_SID);
11839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	sim.sim_domsid = sidstr;
11849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	sim.sim_id = id;
11859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	switch (*idtype) {
11879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_IDMAP_USER:
11889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sim.sim_stat = kidmap_getuidbysid(global_zone, sim.sim_domsid,
11899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    sim.sim_rid, sim.sim_id);
11909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
11919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_IDMAP_GROUP:
11939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sim.sim_stat = kidmap_getgidbysid(global_zone, sim.sim_domsid,
11949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    sim.sim_rid, sim.sim_id);
11959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
11969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_IDMAP_UNKNOWN:
11989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sim.sim_stat = kidmap_getpidbysid(global_zone, sim.sim_domsid,
11999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    sim.sim_rid, sim.sim_id, &sim.sim_idtype);
12009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
12019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	default:
12039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		ASSERT(0);
12049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (IDMAP_ERR_ARG);
12059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
12069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	*idtype = sim.sim_idtype;
12089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (sim.sim_stat);
12109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
12119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
12139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_idmap_getsid
12149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
12159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Maps the given Solaris ID to a Windows SID using the
12169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * simple mapping API.
12179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
12189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States idmap_stat
12199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_idmap_getsid(uid_t id, int idtype, smb_sid_t **sid)
12209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
12219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_idmap_t sim;
12229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	switch (idtype) {
12249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_IDMAP_USER:
12259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sim.sim_stat = kidmap_getsidbyuid(global_zone, id,
12269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    (const char **)&sim.sim_domsid, &sim.sim_rid);
12279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
12289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_IDMAP_GROUP:
12309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sim.sim_stat = kidmap_getsidbygid(global_zone, id,
12319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    (const char **)&sim.sim_domsid, &sim.sim_rid);
12329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
12339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_IDMAP_EVERYONE:
12359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		/* Everyone S-1-1-0 */
12369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sim.sim_domsid = "S-1-1";
12379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sim.sim_rid = 0;
12389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sim.sim_stat = IDMAP_SUCCESS;
12399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
12409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	default:
12429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		ASSERT(0);
12439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (IDMAP_ERR_ARG);
12449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
12459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (sim.sim_stat != IDMAP_SUCCESS)
12479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (sim.sim_stat);
12489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (sim.sim_domsid == NULL)
12509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (IDMAP_ERR_NOMAPPING);
12519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	sim.sim_sid = smb_sid_fromstr(sim.sim_domsid);
12539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (sim.sim_sid == NULL)
12549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (IDMAP_ERR_INTERNAL);
12559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	*sid = smb_sid_splice(sim.sim_sid, sim.sim_rid);
12579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_sid_free(sim.sim_sid);
12589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (*sid == NULL)
12599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sim.sim_stat = IDMAP_ERR_INTERNAL;
12609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (sim.sim_stat);
12629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
12639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
12659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_idmap_batch_create
12669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
12679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Creates and initializes the context for batch ID mapping.
12689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
12699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States idmap_stat
12709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_idmap_batch_create(smb_idmap_batch_t *sib, uint16_t nmap, int flags)
12719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
12729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(sib);
12739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	bzero(sib, sizeof (smb_idmap_batch_t));
12759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	sib->sib_idmaph = kidmap_get_create(global_zone);
12779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	sib->sib_flags = flags;
12799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	sib->sib_nmap = nmap;
12809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	sib->sib_size = nmap * sizeof (smb_idmap_t);
12819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	sib->sib_maps = kmem_zalloc(sib->sib_size, KM_SLEEP);
12829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (IDMAP_SUCCESS);
12849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
12859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
12879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_idmap_batch_destroy
12889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
12899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Frees the batch ID mapping context.
12909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * If ID mapping is Solaris -> Windows it frees memories
12919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * allocated for binary SIDs.
12929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
12939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
12949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_idmap_batch_destroy(smb_idmap_batch_t *sib)
12959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
12969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	char *domsid;
12979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int i;
12989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(sib);
13009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(sib->sib_maps);
13019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (sib->sib_idmaph)
13039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		kidmap_get_destroy(sib->sib_idmaph);
13049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (sib->sib_flags & SMB_IDMAP_ID2SID) {
13069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		/*
13079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		 * SIDs are allocated only when mapping
13089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		 * UID/GID to SIDs
13099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		 */
13109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		for (i = 0; i < sib->sib_nmap; i++)
13119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			smb_sid_free(sib->sib_maps[i].sim_sid);
13129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	} else if (sib->sib_flags & SMB_IDMAP_SID2ID) {
13139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		/*
13149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		 * SID prefixes are allocated only when mapping
13159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		 * SIDs to UID/GID
13169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		 */
13179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		for (i = 0; i < sib->sib_nmap; i++) {
13189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			domsid = sib->sib_maps[i].sim_domsid;
13199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			if (domsid)
13209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				smb_mem_free(domsid);
13219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
13229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
13239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (sib->sib_size && sib->sib_maps)
13259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		kmem_free(sib->sib_maps, sib->sib_size);
13269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
13279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
13299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_idmap_batch_getid
13309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
13319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Queue a request to map the given SID to a UID or GID.
13329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
13339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * sim->sim_id should point to variable that's supposed to
13349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * hold the returned UID/GID. This needs to be setup by caller
13359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * of this function.
13369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
13379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * If requested ID type is known, it's passed as 'idtype',
13389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * if it's unknown it'll be returned in sim->sim_idtype.
13399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
13409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States idmap_stat
13419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_idmap_batch_getid(idmap_get_handle_t *idmaph, smb_idmap_t *sim,
13429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     smb_sid_t *sid, int idtype)
13439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
13449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	char strsid[SMB_SID_STRSZ];
13459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	idmap_stat idm_stat;
13469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(idmaph);
13489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(sim);
13499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(sid);
13509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_sid_tostr(sid, strsid);
13529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_sid_splitstr(strsid, &sim->sim_rid) != 0)
13539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (IDMAP_ERR_SID);
13549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	sim->sim_domsid = smb_mem_strdup(strsid);
13559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	switch (idtype) {
13579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_IDMAP_USER:
13589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		idm_stat = kidmap_batch_getuidbysid(idmaph, sim->sim_domsid,
13599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    sim->sim_rid, sim->sim_id, &sim->sim_stat);
13609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
13619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_IDMAP_GROUP:
13639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		idm_stat = kidmap_batch_getgidbysid(idmaph, sim->sim_domsid,
13649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    sim->sim_rid, sim->sim_id, &sim->sim_stat);
13659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
13669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_IDMAP_UNKNOWN:
13689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		idm_stat = kidmap_batch_getpidbysid(idmaph, sim->sim_domsid,
13699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    sim->sim_rid, sim->sim_id, &sim->sim_idtype,
13709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    &sim->sim_stat);
13719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
13729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	default:
13749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		ASSERT(0);
13759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (IDMAP_ERR_ARG);
13769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
13779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (idm_stat);
13799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
13809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
13829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_idmap_batch_getsid
13839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
13849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Queue a request to map the given UID/GID to a SID.
13859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
13869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * sim->sim_domsid and sim->sim_rid will contain the mapping
13879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * result upon successful process of the batched request.
13889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
13899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States idmap_stat
13909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_idmap_batch_getsid(idmap_get_handle_t *idmaph, smb_idmap_t *sim,
13919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States     uid_t id, int idtype)
13929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
13939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	idmap_stat idm_stat;
13949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	switch (idtype) {
13969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_IDMAP_USER:
13979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		idm_stat = kidmap_batch_getsidbyuid(idmaph, id,
13989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    (const char **)&sim->sim_domsid, &sim->sim_rid,
13999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    &sim->sim_stat);
14009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
14019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
14029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_IDMAP_GROUP:
14039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		idm_stat = kidmap_batch_getsidbygid(idmaph, id,
14049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    (const char **)&sim->sim_domsid, &sim->sim_rid,
14059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    &sim->sim_stat);
14069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
14079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
14089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_IDMAP_OWNERAT:
14099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		/* Current Owner S-1-5-32-766 */
14109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sim->sim_domsid = NT_BUILTIN_DOMAIN_SIDSTR;
14119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sim->sim_rid = SECURITY_CURRENT_OWNER_RID;
14129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sim->sim_stat = IDMAP_SUCCESS;
14139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		idm_stat = IDMAP_SUCCESS;
14149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
14159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
14169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_IDMAP_GROUPAT:
14179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		/* Current Group S-1-5-32-767 */
14189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sim->sim_domsid = NT_BUILTIN_DOMAIN_SIDSTR;
14199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sim->sim_rid = SECURITY_CURRENT_GROUP_RID;
14209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sim->sim_stat = IDMAP_SUCCESS;
14219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		idm_stat = IDMAP_SUCCESS;
14229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
14239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
14249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_IDMAP_EVERYONE:
14259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		/* Everyone S-1-1-0 */
14269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sim->sim_domsid = NT_WORLD_AUTH_SIDSTR;
14279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sim->sim_rid = 0;
14289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sim->sim_stat = IDMAP_SUCCESS;
14299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		idm_stat = IDMAP_SUCCESS;
14309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
14319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
14329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	default:
14339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		ASSERT(0);
14349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (IDMAP_ERR_ARG);
14359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
14369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
14379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (idm_stat);
14389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
14399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
14409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
14419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_idmap_batch_binsid
14429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
14439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Convert sidrids to binary sids
14449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
14459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Returns 0 if successful and non-zero upon failure.
14469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
14479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static int
14489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_idmap_batch_binsid(smb_idmap_batch_t *sib)
14499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
14509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_sid_t *sid;
14519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_idmap_t *sim;
14529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int i;
14539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
14549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (sib->sib_flags & SMB_IDMAP_SID2ID)
14559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		/* This operation is not required */
14569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (0);
14579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
14589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	sim = sib->sib_maps;
14599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	for (i = 0; i < sib->sib_nmap; sim++, i++) {
14609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		ASSERT(sim->sim_domsid);
14619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (sim->sim_domsid == NULL)
14629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (1);
14639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
14649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if ((sid = smb_sid_fromstr(sim->sim_domsid)) == NULL)
14659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (1);
14669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
14679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sim->sim_sid = smb_sid_splice(sid, sim->sim_rid);
14689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_sid_free(sid);
14699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
14709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
14719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (0);
14729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
14739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
14749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
14759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_idmap_batch_getmappings
14769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
14779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * trigger ID mapping service to get the mappings for queued
14789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * requests.
14799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
14809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Checks the result of all the queued requests.
14819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * If this is a Solaris -> Windows mapping it generates
14829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * binary SIDs from returned (domsid, rid) pairs.
14839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
14849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States idmap_stat
14859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_idmap_batch_getmappings(smb_idmap_batch_t *sib)
14869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
14879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	idmap_stat idm_stat = IDMAP_SUCCESS;
14889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int i;
14899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
14909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	idm_stat = kidmap_get_mappings(sib->sib_idmaph);
14919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (idm_stat != IDMAP_SUCCESS)
14929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (idm_stat);
14939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
14949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	/*
14959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	 * Check the status for all the queued requests
14969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	 */
14979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	for (i = 0; i < sib->sib_nmap; i++) {
14989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (sib->sib_maps[i].sim_stat != IDMAP_SUCCESS)
14999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (sib->sib_maps[i].sim_stat);
15009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
15019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_idmap_batch_binsid(sib) != 0)
15039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		idm_stat = IDMAP_ERR_OTHER;
15049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (idm_stat);
15069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
15079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States uint64_t
15099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_time_unix_to_nt(timestruc_t *unix_time)
15109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
15119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint64_t nt_time;
15129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((unix_time->tv_sec == 0) && (unix_time->tv_nsec == 0))
15149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (0);
15159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	nt_time = unix_time->tv_sec;
15179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	nt_time *= 10000000;  /* seconds to 100ns */
15189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	nt_time += unix_time->tv_nsec / 100;
15199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (nt_time + NT_TIME_BIAS);
15209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
15219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
15239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_time_nt_to_unix(uint64_t nt_time, timestruc_t *unix_time)
15249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
15259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint32_t seconds;
15269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(unix_time);
15289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((nt_time == 0) || (nt_time == -1)) {
15309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		unix_time->tv_sec = 0;
15319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		unix_time->tv_nsec = 0;
15329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return;
15339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
15349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	nt_time -= NT_TIME_BIAS;
15369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	seconds = nt_time / 10000000;
15379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	unix_time->tv_sec = seconds;
15389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	unix_time->tv_nsec = (nt_time  % 10000000) * 100;
15399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
15409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
15429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_time_gmt_to_local, smb_time_local_to_gmt
15439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
15449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Apply the gmt offset to convert between local time and gmt
15459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
15469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int32_t
15479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_time_gmt_to_local(smb_request_t *sr, int32_t gmt)
15489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
15499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((gmt == 0) || (gmt == -1))
15509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (0);
15519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (gmt - sr->sr_gmtoff);
15539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
15549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int32_t
15569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_time_local_to_gmt(smb_request_t *sr, int32_t local)
15579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
15589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((local == 0) || (local == -1))
15599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (0);
15609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (local + sr->sr_gmtoff);
15629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
15639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
15669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_time_dos_to_unix
15679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
15689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Convert SMB_DATE & SMB_TIME values to a unix timestamp.
15699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
15709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * A date/time field of 0 means that that server file system
15719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * assigned value need not be changed. The behaviour when the
15729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * date/time field is set to -1 is not documented but is
15739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * generally treated like 0.
15749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * If date or time is 0 or -1 the unix time is returned as 0
15759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * so that the caller can identify and handle this special case.
15769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
15779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int32_t
15789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_time_dos_to_unix(int16_t date, int16_t time)
15799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
15809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	struct tm	atm;
15819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (((date == 0) || (time == 0)) ||
15839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    ((date == -1) || (time == -1))) {
15849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (0);
15859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
15869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	atm.tm_year = ((date >>  9) & 0x3F) + 80;
15889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	atm.tm_mon  = ((date >>  5) & 0x0F) - 1;
15899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	atm.tm_mday = ((date >>  0) & 0x1F);
15909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	atm.tm_hour = ((time >> 11) & 0x1F);
15919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	atm.tm_min  = ((time >>  5) & 0x3F);
15929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	atm.tm_sec  = ((time >>  0) & 0x1F) << 1;
15939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (smb_timegm(&atm));
15959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
15969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
15989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_time_unix_to_dos(int32_t ux_time, int16_t *date_p, int16_t *time_p)
15999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
16009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	struct tm	atm;
16019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int		i;
16029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	time_t		tmp_time;
16039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
16049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (ux_time == 0) {
16059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		*date_p = 0;
16069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		*time_p = 0;
16079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return;
16089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
16099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
16109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	tmp_time = (time_t)ux_time;
16119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) smb_gmtime_r(&tmp_time, &atm);
16129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
16139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (date_p) {
16149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		i = 0;
16159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		i += atm.tm_year - 80;
16169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		i <<= 4;
16179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		i += atm.tm_mon + 1;
16189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		i <<= 5;
16199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		i += atm.tm_mday;
16209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
16219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		*date_p = (short)i;
16229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
16239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (time_p) {
16249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		i = 0;
16259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		i += atm.tm_hour;
16269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		i <<= 6;
16279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		i += atm.tm_min;
16289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		i <<= 5;
16299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		i += atm.tm_sec >> 1;
16309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
16319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		*time_p = (short)i;
16329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
16339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
16349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
16359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
16369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
16379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_gmtime_r
16389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
16399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Thread-safe version of smb_gmtime. Returns a null pointer if either
16409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * input parameter is a null pointer. Otherwise returns a pointer
16419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * to result.
16429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
16439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Day of the week calculation: the Epoch was a thursday.
16449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
16459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * There are no timezone corrections so tm_isdst and tm_gmtoff are
16469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * always zero, and the zone is always WET.
16479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
16489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States struct tm *
16499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_gmtime_r(time_t *clock, struct tm *result)
16509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
16519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	time_t tsec;
16529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int year;
16539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int month;
16549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int sec_per_month;
16559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
16569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (clock == 0 || result == 0)
16579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (0);
16589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
16599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	bzero(result, sizeof (struct tm));
16609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	tsec = *clock;
16619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	tsec -= tzh_leapcnt;
16629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
16639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	result->tm_wday = tsec / SECSPERDAY;
16649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	result->tm_wday = (result->tm_wday + TM_THURSDAY) % DAYSPERWEEK;
16659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
16669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	year = EPOCH_YEAR;
16679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	while (tsec >= (isleap(year) ? (SECSPERDAY * DAYSPERLYEAR) :
16689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    (SECSPERDAY * DAYSPERNYEAR))) {
16699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (isleap(year))
16709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			tsec -= SECSPERDAY * DAYSPERLYEAR;
16719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		else
16729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			tsec -= SECSPERDAY * DAYSPERNYEAR;
16739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
16749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		++year;
16759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
16769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
16779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	result->tm_year = year - TM_YEAR_BASE;
16789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	result->tm_yday = tsec / SECSPERDAY;
16799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
16809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	for (month = TM_JANUARY; month <= TM_DECEMBER; ++month) {
16819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sec_per_month = days_in_month[month] * SECSPERDAY;
16829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
16839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (month == TM_FEBRUARY && isleap(year))
16849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			sec_per_month += SECSPERDAY;
16859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
16869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (tsec < sec_per_month)
16879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			break;
16889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
16899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		tsec -= sec_per_month;
16909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
16919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
16929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	result->tm_mon = month;
16939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	result->tm_mday = (tsec / SECSPERDAY) + 1;
16949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	tsec %= SECSPERDAY;
16959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	result->tm_sec = tsec % 60;
16969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	tsec /= 60;
16979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	result->tm_min = tsec % 60;
16989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	tsec /= 60;
16999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	result->tm_hour = (int)tsec;
17009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
17019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (result);
17029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
17039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
17049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
17059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
17069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_timegm
17079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
17089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Converts the broken-down time in tm to a time value, i.e. the number
17099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * of seconds since the Epoch (00:00:00 UTC, January 1, 1970). This is
17109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * not a POSIX or ANSI function. Per the man page, the input values of
17119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * tm_wday and tm_yday are ignored and, as the input data is assumed to
17129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * represent GMT, we force tm_isdst and tm_gmtoff to 0.
17139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
17149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Before returning the clock time, we use smb_gmtime_r to set up tm_wday
17159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * and tm_yday, and bring the other fields within normal range. I don't
17169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * think this is really how it should be done but it's convenient for
17179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * now.
17189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
17199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States time_t
17209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_timegm(struct tm *tm)
17219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
17229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	time_t tsec;
17239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int dd;
17249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int mm;
17259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int yy;
17269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int year;
17279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
17289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (tm == 0)
17299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (-1);
17309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
17319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	year = tm->tm_year + TM_YEAR_BASE;
17329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	tsec = tzh_leapcnt;
17339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
17349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	for (yy = EPOCH_YEAR; yy < year; ++yy) {
17359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (isleap(yy))
17369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			tsec += SECSPERDAY * DAYSPERLYEAR;
17379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		else
17389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			tsec += SECSPERDAY * DAYSPERNYEAR;
17399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
17409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
17419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	for (mm = TM_JANUARY; mm < tm->tm_mon; ++mm) {
17429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		dd = days_in_month[mm] * SECSPERDAY;
17439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
17449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (mm == TM_FEBRUARY && isleap(year))
17459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			dd += SECSPERDAY;
17469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
17479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		tsec += dd;
17489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
17499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
17509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	tsec += (tm->tm_mday - 1) * SECSPERDAY;
17519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	tsec += tm->tm_sec;
17529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	tsec += tm->tm_min * SECSPERMIN;
17539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	tsec += tm->tm_hour * SECSPERHOUR;
17549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
17559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	tm->tm_isdst = 0;
17569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) smb_gmtime_r(&tsec, tm);
17579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (tsec);
17589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
17599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
17609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
17619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_pad_align
17629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
17639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Returns the number of bytes required to pad an offset to the
17649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * specified alignment.
17659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
17669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States uint32_t
17679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_pad_align(uint32_t offset, uint32_t align)
17689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
17699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint32_t pad = offset % align;
17709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
17719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (pad != 0)
17729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		pad = align - pad;
17739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
17749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (pad);
17759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
17769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
17779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
17789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * smb_panic
17799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
17809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Logs the file name, function name and line number passed in and panics the
17819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * system.
17829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
17839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
17849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_panic(char *file, const char *func, int line)
17859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
17869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	cmn_err(CE_PANIC, "%s:%s:%d\n", file, func, line);
17879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
1788148c5f43SAlan Wright 
1789148c5f43SAlan Wright /*
1790148c5f43SAlan Wright  * Creates an AVL tree and initializes the given smb_avl_t
1791148c5f43SAlan Wright  * structure using the passed args
1792148c5f43SAlan Wright  */
1793148c5f43SAlan Wright void
1794*8622ec45SGordon Ross smb_avl_create(smb_avl_t *avl, size_t size, size_t offset,
1795*8622ec45SGordon Ross 	const smb_avl_nops_t *ops)
1796148c5f43SAlan Wright {
1797148c5f43SAlan Wright 	ASSERT(avl);
1798148c5f43SAlan Wright 	ASSERT(ops);
1799148c5f43SAlan Wright 
1800148c5f43SAlan Wright 	rw_init(&avl->avl_lock, NULL, RW_DEFAULT, NULL);
1801148c5f43SAlan Wright 	mutex_init(&avl->avl_mutex, NULL, MUTEX_DEFAULT, NULL);
1802148c5f43SAlan Wright 
1803148c5f43SAlan Wright 	avl->avl_nops = ops;
1804148c5f43SAlan Wright 	avl->avl_state = SMB_AVL_STATE_READY;
1805148c5f43SAlan Wright 	avl->avl_refcnt = 0;
1806148c5f43SAlan Wright 	(void) random_get_pseudo_bytes((uint8_t *)&avl->avl_sequence,
1807148c5f43SAlan Wright 	    sizeof (uint32_t));
1808148c5f43SAlan Wright 
1809148c5f43SAlan Wright 	avl_create(&avl->avl_tree, ops->avln_cmp, size, offset);
1810148c5f43SAlan Wright }
1811148c5f43SAlan Wright 
1812148c5f43SAlan Wright /*
1813148c5f43SAlan Wright  * Destroys the specified AVL tree.
1814148c5f43SAlan Wright  * It waits for all the in-flight operations to finish
1815148c5f43SAlan Wright  * before destroying the AVL.
1816148c5f43SAlan Wright  */
1817148c5f43SAlan Wright void
1818148c5f43SAlan Wright smb_avl_destroy(smb_avl_t *avl)
1819148c5f43SAlan Wright {
1820148c5f43SAlan Wright 	void *cookie = NULL;
1821148c5f43SAlan Wright 	void *node;
1822148c5f43SAlan Wright 
1823148c5f43SAlan Wright 	ASSERT(avl);
1824148c5f43SAlan Wright 
1825148c5f43SAlan Wright 	mutex_enter(&avl->avl_mutex);
1826148c5f43SAlan Wright 	if (avl->avl_state != SMB_AVL_STATE_READY) {
1827148c5f43SAlan Wright 		mutex_exit(&avl->avl_mutex);
1828148c5f43SAlan Wright 		return;
1829148c5f43SAlan Wright 	}
1830148c5f43SAlan Wright 
1831148c5f43SAlan Wright 	avl->avl_state = SMB_AVL_STATE_DESTROYING;
1832148c5f43SAlan Wright 
1833148c5f43SAlan Wright 	while (avl->avl_refcnt > 0)
1834148c5f43SAlan Wright 		(void) cv_wait(&avl->avl_cv, &avl->avl_mutex);
1835148c5f43SAlan Wright 	mutex_exit(&avl->avl_mutex);
1836148c5f43SAlan Wright 
1837148c5f43SAlan Wright 	rw_enter(&avl->avl_lock, RW_WRITER);
1838148c5f43SAlan Wright 	while ((node = avl_destroy_nodes(&avl->avl_tree, &cookie)) != NULL)
1839148c5f43SAlan Wright 		avl->avl_nops->avln_destroy(node);
1840148c5f43SAlan Wright 
1841148c5f43SAlan Wright 	avl_destroy(&avl->avl_tree);
1842148c5f43SAlan Wright 	rw_exit(&avl->avl_lock);
1843148c5f43SAlan Wright 
1844148c5f43SAlan Wright 	rw_destroy(&avl->avl_lock);
1845148c5f43SAlan Wright 
1846148c5f43SAlan Wright 	mutex_destroy(&avl->avl_mutex);
1847148c5f43SAlan Wright 	bzero(avl, sizeof (smb_avl_t));
1848148c5f43SAlan Wright }
1849148c5f43SAlan Wright 
1850148c5f43SAlan Wright /*
1851148c5f43SAlan Wright  * Adds the given item to the AVL if it's
1852148c5f43SAlan Wright  * not already there.
1853148c5f43SAlan Wright  *
1854148c5f43SAlan Wright  * Returns:
1855148c5f43SAlan Wright  *
1856148c5f43SAlan Wright  * 	ENOTACTIVE	AVL is not in READY state
1857148c5f43SAlan Wright  * 	EEXIST		The item is already in AVL
1858148c5f43SAlan Wright  */
1859148c5f43SAlan Wright int
1860148c5f43SAlan Wright smb_avl_add(smb_avl_t *avl, void *item)
1861148c5f43SAlan Wright {
1862148c5f43SAlan Wright 	avl_index_t where;
1863148c5f43SAlan Wright 
1864148c5f43SAlan Wright 	ASSERT(avl);
1865148c5f43SAlan Wright 	ASSERT(item);
1866148c5f43SAlan Wright 
1867148c5f43SAlan Wright 	if (!smb_avl_hold(avl))
1868148c5f43SAlan Wright 		return (ENOTACTIVE);
1869148c5f43SAlan Wright 
1870148c5f43SAlan Wright 	rw_enter(&avl->avl_lock, RW_WRITER);
1871148c5f43SAlan Wright 	if (avl_find(&avl->avl_tree, item, &where) != NULL) {
1872148c5f43SAlan Wright 		rw_exit(&avl->avl_lock);
1873148c5f43SAlan Wright 		smb_avl_rele(avl);
1874148c5f43SAlan Wright 		return (EEXIST);
1875148c5f43SAlan Wright 	}
1876148c5f43SAlan Wright 
1877148c5f43SAlan Wright 	avl_insert(&avl->avl_tree, item, where);
1878148c5f43SAlan Wright 	avl->avl_sequence++;
1879148c5f43SAlan Wright 	rw_exit(&avl->avl_lock);
1880148c5f43SAlan Wright 
1881148c5f43SAlan Wright 	smb_avl_rele(avl);
1882148c5f43SAlan Wright 	return (0);
1883148c5f43SAlan Wright }
1884148c5f43SAlan Wright 
1885148c5f43SAlan Wright /*
1886148c5f43SAlan Wright  * Removes the given item from the AVL.
1887148c5f43SAlan Wright  * If no reference is left on the item
1888148c5f43SAlan Wright  * it will also be destroyed by calling the
1889148c5f43SAlan Wright  * registered destroy operation.
1890148c5f43SAlan Wright  */
1891148c5f43SAlan Wright void
1892148c5f43SAlan Wright smb_avl_remove(smb_avl_t *avl, void *item)
1893148c5f43SAlan Wright {
1894148c5f43SAlan Wright 	avl_index_t where;
1895148c5f43SAlan Wright 	void *rm_item;
1896148c5f43SAlan Wright 
1897148c5f43SAlan Wright 	ASSERT(avl);
1898148c5f43SAlan Wright 	ASSERT(item);
1899148c5f43SAlan Wright 
1900148c5f43SAlan Wright 	if (!smb_avl_hold(avl))
1901148c5f43SAlan Wright 		return;
1902148c5f43SAlan Wright 
1903148c5f43SAlan Wright 	rw_enter(&avl->avl_lock, RW_WRITER);
1904148c5f43SAlan Wright 	if ((rm_item = avl_find(&avl->avl_tree, item, &where)) == NULL) {
1905148c5f43SAlan Wright 		rw_exit(&avl->avl_lock);
1906148c5f43SAlan Wright 		smb_avl_rele(avl);
1907148c5f43SAlan Wright 		return;
1908148c5f43SAlan Wright 	}
1909148c5f43SAlan Wright 
1910148c5f43SAlan Wright 	avl_remove(&avl->avl_tree, rm_item);
1911148c5f43SAlan Wright 	if (avl->avl_nops->avln_rele(rm_item))
1912148c5f43SAlan Wright 		avl->avl_nops->avln_destroy(rm_item);
1913148c5f43SAlan Wright 	avl->avl_sequence++;
1914148c5f43SAlan Wright 	rw_exit(&avl->avl_lock);
1915148c5f43SAlan Wright 
1916148c5f43SAlan Wright 	smb_avl_rele(avl);
1917148c5f43SAlan Wright }
1918148c5f43SAlan Wright 
1919148c5f43SAlan Wright /*
1920148c5f43SAlan Wright  * Looks up the AVL for the given item.
1921148c5f43SAlan Wright  * If the item is found a hold on the object
1922148c5f43SAlan Wright  * is taken before the pointer to it is
1923148c5f43SAlan Wright  * returned to the caller. The caller MUST
1924148c5f43SAlan Wright  * always call smb_avl_release() after it's done
1925148c5f43SAlan Wright  * using the returned object to release the hold
1926148c5f43SAlan Wright  * taken on the object.
1927148c5f43SAlan Wright  */
1928148c5f43SAlan Wright void *
1929148c5f43SAlan Wright smb_avl_lookup(smb_avl_t *avl, void *item)
1930148c5f43SAlan Wright {
1931148c5f43SAlan Wright 	void *node = NULL;
1932148c5f43SAlan Wright 
1933148c5f43SAlan Wright 	ASSERT(avl);
1934148c5f43SAlan Wright 	ASSERT(item);
1935148c5f43SAlan Wright 
1936148c5f43SAlan Wright 	if (!smb_avl_hold(avl))
1937148c5f43SAlan Wright 		return (NULL);
1938148c5f43SAlan Wright 
1939148c5f43SAlan Wright 	rw_enter(&avl->avl_lock, RW_READER);
1940148c5f43SAlan Wright 	node = avl_find(&avl->avl_tree, item, NULL);
1941148c5f43SAlan Wright 	if (node != NULL)
1942148c5f43SAlan Wright 		avl->avl_nops->avln_hold(node);
1943148c5f43SAlan Wright 	rw_exit(&avl->avl_lock);
1944148c5f43SAlan Wright 
1945148c5f43SAlan Wright 	if (node == NULL)
1946148c5f43SAlan Wright 		smb_avl_rele(avl);
1947148c5f43SAlan Wright 
1948148c5f43SAlan Wright 	return (node);
1949148c5f43SAlan Wright }
1950148c5f43SAlan Wright 
1951148c5f43SAlan Wright /*
1952148c5f43SAlan Wright  * The hold on the given object is released.
1953148c5f43SAlan Wright  * This function MUST always be called after
1954148c5f43SAlan Wright  * smb_avl_lookup() and smb_avl_iterate() for
1955148c5f43SAlan Wright  * the returned object.
1956148c5f43SAlan Wright  *
1957148c5f43SAlan Wright  * If AVL is in DESTROYING state, the destroying
1958148c5f43SAlan Wright  * thread will be notified.
1959148c5f43SAlan Wright  */
1960148c5f43SAlan Wright void
1961148c5f43SAlan Wright smb_avl_release(smb_avl_t *avl, void *item)
1962148c5f43SAlan Wright {
1963148c5f43SAlan Wright 	ASSERT(avl);
1964148c5f43SAlan Wright 	ASSERT(item);
1965148c5f43SAlan Wright 
1966148c5f43SAlan Wright 	if (avl->avl_nops->avln_rele(item))
1967148c5f43SAlan Wright 		avl->avl_nops->avln_destroy(item);
1968148c5f43SAlan Wright 
1969148c5f43SAlan Wright 	smb_avl_rele(avl);
1970148c5f43SAlan Wright }
1971148c5f43SAlan Wright 
1972148c5f43SAlan Wright /*
1973148c5f43SAlan Wright  * Initializes the given cursor for the AVL.
1974148c5f43SAlan Wright  * The cursor will be used to iterate through the AVL
1975148c5f43SAlan Wright  */
1976148c5f43SAlan Wright void
1977148c5f43SAlan Wright smb_avl_iterinit(smb_avl_t *avl, smb_avl_cursor_t *cursor)
1978148c5f43SAlan Wright {
1979148c5f43SAlan Wright 	ASSERT(avl);
1980148c5f43SAlan Wright 	ASSERT(cursor);
1981148c5f43SAlan Wright 
1982148c5f43SAlan Wright 	cursor->avlc_next = NULL;
1983148c5f43SAlan Wright 	cursor->avlc_sequence = avl->avl_sequence;
1984148c5f43SAlan Wright }
1985148c5f43SAlan Wright 
1986148c5f43SAlan Wright /*
1987148c5f43SAlan Wright  * Iterates through the AVL using the given cursor.
1988148c5f43SAlan Wright  * It always starts at the beginning and then returns
1989148c5f43SAlan Wright  * a pointer to the next object on each subsequent call.
1990148c5f43SAlan Wright  *
1991148c5f43SAlan Wright  * If a new object is added to or removed from the AVL
1992148c5f43SAlan Wright  * between two calls to this function, the iteration
1993148c5f43SAlan Wright  * will terminate prematurely.
1994148c5f43SAlan Wright  *
1995148c5f43SAlan Wright  * The caller MUST always call smb_avl_release() after it's
1996148c5f43SAlan Wright  * done using the returned object to release the hold taken
1997148c5f43SAlan Wright  * on the object.
1998148c5f43SAlan Wright  */
1999148c5f43SAlan Wright void *
2000148c5f43SAlan Wright smb_avl_iterate(smb_avl_t *avl, smb_avl_cursor_t *cursor)
2001148c5f43SAlan Wright {
2002148c5f43SAlan Wright 	void *node;
2003148c5f43SAlan Wright 
2004148c5f43SAlan Wright 	ASSERT(avl);
2005148c5f43SAlan Wright 	ASSERT(cursor);
2006148c5f43SAlan Wright 
2007148c5f43SAlan Wright 	if (!smb_avl_hold(avl))
2008148c5f43SAlan Wright 		return (NULL);
2009148c5f43SAlan Wright 
2010148c5f43SAlan Wright 	rw_enter(&avl->avl_lock, RW_READER);
2011148c5f43SAlan Wright 	if (cursor->avlc_sequence != avl->avl_sequence) {
2012148c5f43SAlan Wright 		rw_exit(&avl->avl_lock);
2013148c5f43SAlan Wright 		smb_avl_rele(avl);
2014148c5f43SAlan Wright 		return (NULL);
2015148c5f43SAlan Wright 	}
2016148c5f43SAlan Wright 
2017148c5f43SAlan Wright 	if (cursor->avlc_next == NULL)
2018148c5f43SAlan Wright 		node = avl_first(&avl->avl_tree);
2019148c5f43SAlan Wright 	else
2020148c5f43SAlan Wright 		node = AVL_NEXT(&avl->avl_tree, cursor->avlc_next);
2021148c5f43SAlan Wright 
2022148c5f43SAlan Wright 	if (node != NULL)
2023148c5f43SAlan Wright 		avl->avl_nops->avln_hold(node);
2024148c5f43SAlan Wright 
2025148c5f43SAlan Wright 	cursor->avlc_next = node;
2026148c5f43SAlan Wright 	rw_exit(&avl->avl_lock);
2027148c5f43SAlan Wright 
2028148c5f43SAlan Wright 	if (node == NULL)
2029148c5f43SAlan Wright 		smb_avl_rele(avl);
2030148c5f43SAlan Wright 
2031148c5f43SAlan Wright 	return (node);
2032148c5f43SAlan Wright }
2033148c5f43SAlan Wright 
2034148c5f43SAlan Wright /*
2035148c5f43SAlan Wright  * Increments the AVL reference count in order to
2036148c5f43SAlan Wright  * prevent the avl from being destroyed while it's
2037148c5f43SAlan Wright  * being accessed.
2038148c5f43SAlan Wright  */
2039148c5f43SAlan Wright static boolean_t
2040148c5f43SAlan Wright smb_avl_hold(smb_avl_t *avl)
2041148c5f43SAlan Wright {
2042148c5f43SAlan Wright 	mutex_enter(&avl->avl_mutex);
2043148c5f43SAlan Wright 	if (avl->avl_state != SMB_AVL_STATE_READY) {
2044148c5f43SAlan Wright 		mutex_exit(&avl->avl_mutex);
2045148c5f43SAlan Wright 		return (B_FALSE);
2046148c5f43SAlan Wright 	}
2047148c5f43SAlan Wright 	avl->avl_refcnt++;
2048148c5f43SAlan Wright 	mutex_exit(&avl->avl_mutex);
2049148c5f43SAlan Wright 
2050148c5f43SAlan Wright 	return (B_TRUE);
2051148c5f43SAlan Wright }
2052148c5f43SAlan Wright 
2053148c5f43SAlan Wright /*
2054148c5f43SAlan Wright  * Decrements the AVL reference count to release the
2055148c5f43SAlan Wright  * hold. If another thread is trying to destroy the
2056148c5f43SAlan Wright  * AVL and is waiting for the reference count to become
2057148c5f43SAlan Wright  * 0, it is signaled to wake up.
2058148c5f43SAlan Wright  */
2059148c5f43SAlan Wright static void
2060148c5f43SAlan Wright smb_avl_rele(smb_avl_t *avl)
2061148c5f43SAlan Wright {
2062148c5f43SAlan Wright 	mutex_enter(&avl->avl_mutex);
2063148c5f43SAlan Wright 	ASSERT(avl->avl_refcnt > 0);
2064148c5f43SAlan Wright 	avl->avl_refcnt--;
2065148c5f43SAlan Wright 	if (avl->avl_state == SMB_AVL_STATE_DESTROYING)
2066148c5f43SAlan Wright 		cv_broadcast(&avl->avl_cv);
2067148c5f43SAlan Wright 	mutex_exit(&avl->avl_mutex);
2068148c5f43SAlan Wright }
2069148c5f43SAlan Wright 
2070148c5f43SAlan Wright /*
2071148c5f43SAlan Wright  * smb_latency_init
2072148c5f43SAlan Wright  */
2073148c5f43SAlan Wright void
2074148c5f43SAlan Wright smb_latency_init(smb_latency_t *lat)
2075148c5f43SAlan Wright {
2076148c5f43SAlan Wright 	bzero(lat, sizeof (*lat));
2077148c5f43SAlan Wright 	mutex_init(&lat->ly_mutex, NULL, MUTEX_SPIN, (void *)ipltospl(SPL7));
2078148c5f43SAlan Wright }
2079148c5f43SAlan Wright 
2080148c5f43SAlan Wright /*
2081148c5f43SAlan Wright  * smb_latency_destroy
2082148c5f43SAlan Wright  */
2083148c5f43SAlan Wright void
2084148c5f43SAlan Wright smb_latency_destroy(smb_latency_t *lat)
2085148c5f43SAlan Wright {
2086148c5f43SAlan Wright 	mutex_destroy(&lat->ly_mutex);
2087148c5f43SAlan Wright }
2088148c5f43SAlan Wright 
2089148c5f43SAlan Wright /*
2090148c5f43SAlan Wright  * smb_latency_add_sample
2091148c5f43SAlan Wright  *
2092148c5f43SAlan Wright  * Uses the new sample to calculate the new mean and standard deviation. The
2093148c5f43SAlan Wright  * sample must be a scaled value.
2094148c5f43SAlan Wright  */
2095148c5f43SAlan Wright void
2096148c5f43SAlan Wright smb_latency_add_sample(smb_latency_t *lat, hrtime_t sample)
2097148c5f43SAlan Wright {
2098148c5f43SAlan Wright 	hrtime_t	a_mean;
2099148c5f43SAlan Wright 	hrtime_t	d_mean;
2100148c5f43SAlan Wright 
2101148c5f43SAlan Wright 	mutex_enter(&lat->ly_mutex);
2102148c5f43SAlan Wright 	lat->ly_a_nreq++;
2103148c5f43SAlan Wright 	lat->ly_a_sum += sample;
2104148c5f43SAlan Wright 	if (lat->ly_a_nreq != 0) {
2105148c5f43SAlan Wright 		a_mean = lat->ly_a_sum / lat->ly_a_nreq;
2106148c5f43SAlan Wright 		lat->ly_a_stddev =
2107148c5f43SAlan Wright 		    (sample - a_mean) * (sample - lat->ly_a_mean);
2108148c5f43SAlan Wright 		lat->ly_a_mean = a_mean;
2109148c5f43SAlan Wright 	}
2110148c5f43SAlan Wright 	lat->ly_d_nreq++;
2111148c5f43SAlan Wright 	lat->ly_d_sum += sample;
2112148c5f43SAlan Wright 	if (lat->ly_d_nreq != 0) {
2113148c5f43SAlan Wright 		d_mean = lat->ly_d_sum / lat->ly_d_nreq;
2114148c5f43SAlan Wright 		lat->ly_d_stddev =
2115148c5f43SAlan Wright 		    (sample - d_mean) * (sample - lat->ly_d_mean);
2116148c5f43SAlan Wright 		lat->ly_d_mean = d_mean;
2117148c5f43SAlan Wright 	}
2118148c5f43SAlan Wright 	mutex_exit(&lat->ly_mutex);
2119148c5f43SAlan Wright }
2120148c5f43SAlan Wright 
2121148c5f43SAlan Wright /*
2122148c5f43SAlan Wright  * smb_srqueue_init
2123148c5f43SAlan Wright  */
2124148c5f43SAlan Wright void
2125148c5f43SAlan Wright smb_srqueue_init(smb_srqueue_t *srq)
2126148c5f43SAlan Wright {
2127148c5f43SAlan Wright 	bzero(srq, sizeof (*srq));
2128148c5f43SAlan Wright 	mutex_init(&srq->srq_mutex, NULL, MUTEX_SPIN, (void *)ipltospl(SPL7));
2129148c5f43SAlan Wright 	srq->srq_wlastupdate = srq->srq_rlastupdate = gethrtime_unscaled();
2130148c5f43SAlan Wright }
2131148c5f43SAlan Wright 
2132148c5f43SAlan Wright /*
2133148c5f43SAlan Wright  * smb_srqueue_destroy
2134148c5f43SAlan Wright  */
2135148c5f43SAlan Wright void
2136148c5f43SAlan Wright smb_srqueue_destroy(smb_srqueue_t *srq)
2137148c5f43SAlan Wright {
2138148c5f43SAlan Wright 	mutex_destroy(&srq->srq_mutex);
2139148c5f43SAlan Wright }
2140148c5f43SAlan Wright 
2141148c5f43SAlan Wright /*
2142148c5f43SAlan Wright  * smb_srqueue_waitq_enter
2143148c5f43SAlan Wright  */
2144148c5f43SAlan Wright void
2145148c5f43SAlan Wright smb_srqueue_waitq_enter(smb_srqueue_t *srq)
2146148c5f43SAlan Wright {
2147148c5f43SAlan Wright 	hrtime_t	new;
2148148c5f43SAlan Wright 	hrtime_t	delta;
2149148c5f43SAlan Wright 	uint32_t	wcnt;
2150148c5f43SAlan Wright 
2151148c5f43SAlan Wright 	mutex_enter(&srq->srq_mutex);
2152148c5f43SAlan Wright 	new = gethrtime_unscaled();
2153148c5f43SAlan Wright 	delta = new - srq->srq_wlastupdate;
2154148c5f43SAlan Wright 	srq->srq_wlastupdate = new;
2155148c5f43SAlan Wright 	wcnt = srq->srq_wcnt++;
2156148c5f43SAlan Wright 	if (wcnt != 0) {
2157148c5f43SAlan Wright 		srq->srq_wlentime += delta * wcnt;
2158148c5f43SAlan Wright 		srq->srq_wtime += delta;
2159148c5f43SAlan Wright 	}
2160148c5f43SAlan Wright 	mutex_exit(&srq->srq_mutex);
2161148c5f43SAlan Wright }
2162148c5f43SAlan Wright 
2163148c5f43SAlan Wright /*
2164148c5f43SAlan Wright  * smb_srqueue_runq_exit
2165148c5f43SAlan Wright  */
2166148c5f43SAlan Wright void
2167148c5f43SAlan Wright smb_srqueue_runq_exit(smb_srqueue_t *srq)
2168148c5f43SAlan Wright {
2169148c5f43SAlan Wright 	hrtime_t	new;
2170148c5f43SAlan Wright 	hrtime_t	delta;
2171148c5f43SAlan Wright 	uint32_t	rcnt;
2172148c5f43SAlan Wright 
2173148c5f43SAlan Wright 	mutex_enter(&srq->srq_mutex);
2174148c5f43SAlan Wright 	new = gethrtime_unscaled();
2175148c5f43SAlan Wright 	delta = new - srq->srq_rlastupdate;
2176148c5f43SAlan Wright 	srq->srq_rlastupdate = new;
2177148c5f43SAlan Wright 	rcnt = srq->srq_rcnt--;
2178148c5f43SAlan Wright 	ASSERT(rcnt > 0);
2179148c5f43SAlan Wright 	srq->srq_rlentime += delta * rcnt;
2180148c5f43SAlan Wright 	srq->srq_rtime += delta;
2181148c5f43SAlan Wright 	mutex_exit(&srq->srq_mutex);
2182148c5f43SAlan Wright }
2183148c5f43SAlan Wright 
2184148c5f43SAlan Wright /*
2185148c5f43SAlan Wright  * smb_srqueue_waitq_to_runq
2186148c5f43SAlan Wright  */
2187148c5f43SAlan Wright void
2188148c5f43SAlan Wright smb_srqueue_waitq_to_runq(smb_srqueue_t *srq)
2189148c5f43SAlan Wright {
2190148c5f43SAlan Wright 	hrtime_t	new;
2191148c5f43SAlan Wright 	hrtime_t	delta;
2192148c5f43SAlan Wright 	uint32_t	wcnt;
2193148c5f43SAlan Wright 	uint32_t	rcnt;
2194148c5f43SAlan Wright 
2195148c5f43SAlan Wright 	mutex_enter(&srq->srq_mutex);
2196148c5f43SAlan Wright 	new = gethrtime_unscaled();
2197148c5f43SAlan Wright 	delta = new - srq->srq_wlastupdate;
2198148c5f43SAlan Wright 	srq->srq_wlastupdate = new;
2199148c5f43SAlan Wright 	wcnt = srq->srq_wcnt--;
2200148c5f43SAlan Wright 	ASSERT(wcnt > 0);
2201148c5f43SAlan Wright 	srq->srq_wlentime += delta * wcnt;
2202148c5f43SAlan Wright 	srq->srq_wtime += delta;
2203148c5f43SAlan Wright 	delta = new - srq->srq_rlastupdate;
2204148c5f43SAlan Wright 	srq->srq_rlastupdate = new;
2205148c5f43SAlan Wright 	rcnt = srq->srq_rcnt++;
2206148c5f43SAlan Wright 	if (rcnt != 0) {
2207148c5f43SAlan Wright 		srq->srq_rlentime += delta * rcnt;
2208148c5f43SAlan Wright 		srq->srq_rtime += delta;
2209148c5f43SAlan Wright 	}
2210148c5f43SAlan Wright 	mutex_exit(&srq->srq_mutex);
2211148c5f43SAlan Wright }
2212148c5f43SAlan Wright 
2213148c5f43SAlan Wright /*
2214148c5f43SAlan Wright  * smb_srqueue_update
2215148c5f43SAlan Wright  *
2216148c5f43SAlan Wright  * Takes a snapshot of the smb_sr_stat_t structure passed in.
2217148c5f43SAlan Wright  */
2218148c5f43SAlan Wright void
2219148c5f43SAlan Wright smb_srqueue_update(smb_srqueue_t *srq, smb_kstat_utilization_t *kd)
2220148c5f43SAlan Wright {
2221148c5f43SAlan Wright 	hrtime_t	delta;
2222148c5f43SAlan Wright 	hrtime_t	snaptime;
2223148c5f43SAlan Wright 
2224148c5f43SAlan Wright 	mutex_enter(&srq->srq_mutex);
2225148c5f43SAlan Wright 	snaptime = gethrtime_unscaled();
2226148c5f43SAlan Wright 	delta = snaptime - srq->srq_wlastupdate;
2227148c5f43SAlan Wright 	srq->srq_wlastupdate = snaptime;
2228148c5f43SAlan Wright 	if (srq->srq_wcnt != 0) {
2229148c5f43SAlan Wright 		srq->srq_wlentime += delta * srq->srq_wcnt;
2230148c5f43SAlan Wright 		srq->srq_wtime += delta;
2231148c5f43SAlan Wright 	}
2232148c5f43SAlan Wright 	delta = snaptime - srq->srq_rlastupdate;
2233148c5f43SAlan Wright 	srq->srq_rlastupdate = snaptime;
2234148c5f43SAlan Wright 	if (srq->srq_rcnt != 0) {
2235148c5f43SAlan Wright 		srq->srq_rlentime += delta * srq->srq_rcnt;
2236148c5f43SAlan Wright 		srq->srq_rtime += delta;
2237148c5f43SAlan Wright 	}
2238148c5f43SAlan Wright 	kd->ku_rlentime = srq->srq_rlentime;
2239148c5f43SAlan Wright 	kd->ku_rtime = srq->srq_rtime;
2240148c5f43SAlan Wright 	kd->ku_wlentime = srq->srq_wlentime;
2241148c5f43SAlan Wright 	kd->ku_wtime = srq->srq_wtime;
2242148c5f43SAlan Wright 	mutex_exit(&srq->srq_mutex);
2243148c5f43SAlan Wright 	scalehrtime(&kd->ku_rlentime);
2244148c5f43SAlan Wright 	scalehrtime(&kd->ku_rtime);
2245148c5f43SAlan Wright 	scalehrtime(&kd->ku_wlentime);
2246148c5f43SAlan Wright 	scalehrtime(&kd->ku_wtime);
2247148c5f43SAlan Wright }
2248cb174861Sjoyce mcintosh 
2249cb174861Sjoyce mcintosh void
2250*8622ec45SGordon Ross smb_threshold_init(smb_cmd_threshold_t *ct, smb_server_t *sv, char *cmd,
2251*8622ec45SGordon Ross     int threshold, int timeout)
2252cb174861Sjoyce mcintosh {
2253cb174861Sjoyce mcintosh 	bzero(ct, sizeof (smb_cmd_threshold_t));
2254cb174861Sjoyce mcintosh 	mutex_init(&ct->ct_mutex, NULL, MUTEX_DEFAULT, NULL);
2255cb174861Sjoyce mcintosh 	ct->ct_cmd = cmd;
2256cb174861Sjoyce mcintosh 	ct->ct_threshold = threshold;
2257*8622ec45SGordon Ross 	ct->ct_event = smb_event_create(sv, timeout);
2258cb174861Sjoyce mcintosh 	ct->ct_event_id = smb_event_txid(ct->ct_event);
2259cb174861Sjoyce mcintosh 
2260cb174861Sjoyce mcintosh 	if (smb_threshold_debug) {
2261cb174861Sjoyce mcintosh 		cmn_err(CE_NOTE, "smb_threshold_init[%s]: threshold (%d), "
2262cb174861Sjoyce mcintosh 		    "timeout (%d)", cmd, threshold, timeout);
2263cb174861Sjoyce mcintosh 	}
2264cb174861Sjoyce mcintosh }
2265cb174861Sjoyce mcintosh 
2266cb174861Sjoyce mcintosh /*
2267cb174861Sjoyce mcintosh  * This function must be called prior to SMB_SERVER_STATE_STOPPING state
2268cb174861Sjoyce mcintosh  * so that ct_event can be successfully removed from the event list.
2269cb174861Sjoyce mcintosh  * It should not be called when the server mutex is held or when the
2270cb174861Sjoyce mcintosh  * server is removed from the server list.
2271cb174861Sjoyce mcintosh  */
2272cb174861Sjoyce mcintosh void
2273cb174861Sjoyce mcintosh smb_threshold_fini(smb_cmd_threshold_t *ct)
2274cb174861Sjoyce mcintosh {
2275cb174861Sjoyce mcintosh 	smb_event_destroy(ct->ct_event);
2276cb174861Sjoyce mcintosh 	mutex_destroy(&ct->ct_mutex);
2277cb174861Sjoyce mcintosh 	bzero(ct, sizeof (smb_cmd_threshold_t));
2278cb174861Sjoyce mcintosh }
2279cb174861Sjoyce mcintosh 
2280cb174861Sjoyce mcintosh /*
2281cb174861Sjoyce mcintosh  * This threshold mechanism can be used to limit the number of simultaneous
2282cb174861Sjoyce mcintosh  * requests, which serves to limit the stress that can be applied to the
2283cb174861Sjoyce mcintosh  * service and also allows the service to respond to requests before the
2284cb174861Sjoyce mcintosh  * client times out and reports that the server is not responding,
2285cb174861Sjoyce mcintosh  *
2286cb174861Sjoyce mcintosh  * If the number of requests exceeds the threshold, new requests will be
2287cb174861Sjoyce mcintosh  * stalled until the number drops back to the threshold.  Stalled requests
2288cb174861Sjoyce mcintosh  * will be notified as appropriate, in which case 0 will be returned.
2289cb174861Sjoyce mcintosh  * If the timeout expires before the request is notified, a non-zero errno
2290cb174861Sjoyce mcintosh  * value will be returned.
2291cb174861Sjoyce mcintosh  *
2292cb174861Sjoyce mcintosh  * To avoid a flood of messages, the message rate is throttled as well.
2293cb174861Sjoyce mcintosh  */
2294cb174861Sjoyce mcintosh int
2295cb174861Sjoyce mcintosh smb_threshold_enter(smb_cmd_threshold_t *ct)
2296cb174861Sjoyce mcintosh {
2297cb174861Sjoyce mcintosh 	int	rc;
2298cb174861Sjoyce mcintosh 
2299cb174861Sjoyce mcintosh 	mutex_enter(&ct->ct_mutex);
2300cb174861Sjoyce mcintosh 	if (ct->ct_active_cnt >= ct->ct_threshold && ct->ct_event != NULL) {
2301cb174861Sjoyce mcintosh 		atomic_inc_32(&ct->ct_blocked_cnt);
2302cb174861Sjoyce mcintosh 
2303cb174861Sjoyce mcintosh 		if (smb_threshold_debug) {
2304cb174861Sjoyce mcintosh 			cmn_err(CE_NOTE, "smb_threshold_enter[%s]: blocked "
2305cb174861Sjoyce mcintosh 			    "(blocked ops: %u, inflight ops: %u)",
2306cb174861Sjoyce mcintosh 			    ct->ct_cmd, ct->ct_blocked_cnt, ct->ct_active_cnt);
2307cb174861Sjoyce mcintosh 		}
2308cb174861Sjoyce mcintosh 
2309cb174861Sjoyce mcintosh 		mutex_exit(&ct->ct_mutex);
2310cb174861Sjoyce mcintosh 
2311cb174861Sjoyce mcintosh 		if ((rc = smb_event_wait(ct->ct_event)) != 0) {
2312cb174861Sjoyce mcintosh 			if (rc == ECANCELED)
2313cb174861Sjoyce mcintosh 				return (rc);
2314cb174861Sjoyce mcintosh 
2315cb174861Sjoyce mcintosh 			mutex_enter(&ct->ct_mutex);
2316cb174861Sjoyce mcintosh 			if (ct->ct_active_cnt >= ct->ct_threshold) {
2317cb174861Sjoyce mcintosh 
2318cb174861Sjoyce mcintosh 				if ((ct->ct_error_cnt %
2319cb174861Sjoyce mcintosh 				    SMB_THRESHOLD_REPORT_THROTTLE) == 0) {
2320cb174861Sjoyce mcintosh 					cmn_err(CE_NOTE, "%s: server busy: "
2321cb174861Sjoyce mcintosh 					    "threshold %d exceeded)",
2322cb174861Sjoyce mcintosh 					    ct->ct_cmd, ct->ct_threshold);
2323cb174861Sjoyce mcintosh 				}
2324cb174861Sjoyce mcintosh 
2325cb174861Sjoyce mcintosh 				atomic_inc_32(&ct->ct_error_cnt);
2326cb174861Sjoyce mcintosh 				mutex_exit(&ct->ct_mutex);
2327cb174861Sjoyce mcintosh 				return (rc);
2328cb174861Sjoyce mcintosh 			}
2329cb174861Sjoyce mcintosh 
2330cb174861Sjoyce mcintosh 			mutex_exit(&ct->ct_mutex);
2331cb174861Sjoyce mcintosh 
2332cb174861Sjoyce mcintosh 		}
2333cb174861Sjoyce mcintosh 
2334cb174861Sjoyce mcintosh 		mutex_enter(&ct->ct_mutex);
2335cb174861Sjoyce mcintosh 		atomic_dec_32(&ct->ct_blocked_cnt);
2336cb174861Sjoyce mcintosh 		if (smb_threshold_debug) {
2337cb174861Sjoyce mcintosh 			cmn_err(CE_NOTE, "smb_threshold_enter[%s]: resumed "
2338cb174861Sjoyce mcintosh 			    "(blocked ops: %u, inflight ops: %u)", ct->ct_cmd,
2339cb174861Sjoyce mcintosh 			    ct->ct_blocked_cnt, ct->ct_active_cnt);
2340cb174861Sjoyce mcintosh 		}
2341cb174861Sjoyce mcintosh 	}
2342cb174861Sjoyce mcintosh 
2343cb174861Sjoyce mcintosh 	atomic_inc_32(&ct->ct_active_cnt);
2344cb174861Sjoyce mcintosh 	mutex_exit(&ct->ct_mutex);
2345cb174861Sjoyce mcintosh 	return (0);
2346cb174861Sjoyce mcintosh }
2347cb174861Sjoyce mcintosh 
2348cb174861Sjoyce mcintosh void
2349cb174861Sjoyce mcintosh smb_threshold_exit(smb_cmd_threshold_t *ct, smb_server_t *sv)
2350cb174861Sjoyce mcintosh {
2351cb174861Sjoyce mcintosh 	mutex_enter(&ct->ct_mutex);
2352cb174861Sjoyce mcintosh 	atomic_dec_32(&ct->ct_active_cnt);
2353cb174861Sjoyce mcintosh 	mutex_exit(&ct->ct_mutex);
2354cb174861Sjoyce mcintosh 	smb_event_notify(sv, ct->ct_event_id);
2355cb174861Sjoyce mcintosh }
2356