xref: /illumos-gate/usr/src/uts/common/fs/smbsrv/smb_server.c (revision c586600796766c83eb9485c446886fd9ed2359a9)
1faa1795aSjb150015 /*
2faa1795aSjb150015  * CDDL HEADER START
3faa1795aSjb150015  *
4faa1795aSjb150015  * The contents of this file are subject to the terms of the
5faa1795aSjb150015  * Common Development and Distribution License (the "License").
6faa1795aSjb150015  * You may not use this file except in compliance with the License.
7faa1795aSjb150015  *
8faa1795aSjb150015  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9faa1795aSjb150015  * or http://www.opensolaris.org/os/licensing.
10faa1795aSjb150015  * See the License for the specific language governing permissions
11faa1795aSjb150015  * and limitations under the License.
12faa1795aSjb150015  *
13faa1795aSjb150015  * When distributing Covered Code, include this CDDL HEADER in each
14faa1795aSjb150015  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15faa1795aSjb150015  * If applicable, add the following below this CDDL HEADER, with the
16faa1795aSjb150015  * fields enclosed by brackets "[]" replaced with your own identifying
17faa1795aSjb150015  * information: Portions Copyright [yyyy] [name of copyright owner]
18faa1795aSjb150015  *
19faa1795aSjb150015  * CDDL HEADER END
20faa1795aSjb150015  */
21faa1795aSjb150015 /*
22*c5866007SKeyur Desai  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
23faa1795aSjb150015  */
24faa1795aSjb150015 
25faa1795aSjb150015 /*
26faa1795aSjb150015  * General Structures Layout
27faa1795aSjb150015  * -------------------------
28faa1795aSjb150015  *
29faa1795aSjb150015  * This is a simplified diagram showing the relationship between most of the
30faa1795aSjb150015  * main structures.
31faa1795aSjb150015  *
32faa1795aSjb150015  * +-------------------+
33faa1795aSjb150015  * |     SMB_SERVER    |
34faa1795aSjb150015  * +-------------------+
35faa1795aSjb150015  *          |
36faa1795aSjb150015  *          |
37faa1795aSjb150015  *          v
38faa1795aSjb150015  * +-------------------+       +-------------------+      +-------------------+
39faa1795aSjb150015  * |     SESSION       |<----->|     SESSION       |......|      SESSION      |
40faa1795aSjb150015  * +-------------------+       +-------------------+      +-------------------+
41faa1795aSjb150015  *          |
42faa1795aSjb150015  *          |
43faa1795aSjb150015  *          v
44faa1795aSjb150015  * +-------------------+       +-------------------+      +-------------------+
45faa1795aSjb150015  * |       USER        |<----->|       USER        |......|       USER        |
46faa1795aSjb150015  * +-------------------+       +-------------------+      +-------------------+
47faa1795aSjb150015  *          |
48faa1795aSjb150015  *          |
49faa1795aSjb150015  *          v
50faa1795aSjb150015  * +-------------------+       +-------------------+      +-------------------+
51faa1795aSjb150015  * |       TREE        |<----->|       TREE        |......|       TREE        |
52faa1795aSjb150015  * +-------------------+       +-------------------+      +-------------------+
53faa1795aSjb150015  *      |         |
54faa1795aSjb150015  *      |         |
55faa1795aSjb150015  *      |         v
56faa1795aSjb150015  *      |     +-------+       +-------+      +-------+
57faa1795aSjb150015  *      |     | OFILE |<----->| OFILE |......| OFILE |
58faa1795aSjb150015  *      |     +-------+       +-------+      +-------+
59faa1795aSjb150015  *      |
60faa1795aSjb150015  *      |
61faa1795aSjb150015  *      v
62faa1795aSjb150015  *  +-------+       +------+      +------+
63faa1795aSjb150015  *  | ODIR  |<----->| ODIR |......| ODIR |
64faa1795aSjb150015  *  +-------+       +------+      +------+
65faa1795aSjb150015  *
66faa1795aSjb150015  *
67faa1795aSjb150015  * Module Interface Overview
68faa1795aSjb150015  * -------------------------
69faa1795aSjb150015  *
70faa1795aSjb150015  *
71faa1795aSjb150015  *	    +===================================+
72faa1795aSjb150015  *	    |		 smbd daemon		|
73faa1795aSjb150015  *	    +===================================+
74faa1795aSjb150015  *	      |		     |		      ^
75faa1795aSjb150015  *	      |		     |		      |
76faa1795aSjb150015  * User	      |		     |		      |
77faa1795aSjb150015  * -----------|--------------|----------------|--------------------------------
78faa1795aSjb150015  * Kernel     |		     |		      |
79faa1795aSjb150015  *            |		     |		      |
80faa1795aSjb150015  *	      |		     |		      |
81faa1795aSjb150015  *  +=========|==============|================|=================+
82faa1795aSjb150015  *  |	      v		     v		      |			|
83faa1795aSjb150015  *  | +-----------+ +--------------------+ +------------------+ |
84faa1795aSjb150015  *  | |     IO    | | Kernel Door Server | | User Door Servers|	|
85faa1795aSjb150015  *  | | Interface | |     Interface      | |   Interface      | |
86faa1795aSjb150015  *  | +-----------+ +--------------------+ +------------------+ |
87faa1795aSjb150015  *  |		|	     |		      ^		^	|
88faa1795aSjb150015  *  |		v	     v		      |		|	|    +=========+
89faa1795aSjb150015  *  |	     +-----------------------------------+	|	|    |	       |
90faa1795aSjb150015  *  |	     + SMB Server Management (this file) |<------------------|	 ZFS   |
91faa1795aSjb150015  *  |	     +-----------------------------------+	|	|    |	       |
92faa1795aSjb150015  *  |							|	|    |  Module |
93faa1795aSjb150015  *  |	     +-----------------------------------+	|	|    |	       |
94faa1795aSjb150015  *  |	     +     SMB Server Internal Layers    |------+	|    +=========+
95faa1795aSjb150015  *  |	     +-----------------------------------+		|
96faa1795aSjb150015  *  |								|
97faa1795aSjb150015  *  |								|
98faa1795aSjb150015  *  +===========================================================+
99faa1795aSjb150015  *
100faa1795aSjb150015  *
101faa1795aSjb150015  * Server State Machine
102faa1795aSjb150015  * --------------------
103faa1795aSjb150015  *                                  |
104faa1795aSjb150015  *                                  | T0
105faa1795aSjb150015  *                                  |
106faa1795aSjb150015  *                                  v
107faa1795aSjb150015  *                    +-----------------------------+
108faa1795aSjb150015  *		      |   SMB_SERVER_STATE_CREATED  |
109faa1795aSjb150015  *		      +-----------------------------+
110faa1795aSjb150015  *				    |
111faa1795aSjb150015  *				    | T1
112faa1795aSjb150015  *				    |
113faa1795aSjb150015  *				    v
114faa1795aSjb150015  *		      +-----------------------------+
115faa1795aSjb150015  *		      | SMB_SERVER_STATE_CONFIGURED |
116faa1795aSjb150015  *		      +-----------------------------+
117faa1795aSjb150015  *				    |
118faa1795aSjb150015  *				    | T2
119faa1795aSjb150015  *				    |
120faa1795aSjb150015  *				    v
121faa1795aSjb150015  *		      +-----------------------------+
1229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *		      |  SMB_SERVER_STATE_RUNNING / |
1239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *		      |  SMB_SERVER_STATE_STOPPING  |
124faa1795aSjb150015  *		      +-----------------------------+
125faa1795aSjb150015  *				    |
126faa1795aSjb150015  *				    | T3
127faa1795aSjb150015  *				    |
128faa1795aSjb150015  *				    v
129faa1795aSjb150015  *		      +-----------------------------+
130faa1795aSjb150015  *		      |  SMB_SERVER_STATE_DELETING  |
131faa1795aSjb150015  *                    +-----------------------------+
132faa1795aSjb150015  *				    |
133faa1795aSjb150015  *				    |
134faa1795aSjb150015  *				    |
135faa1795aSjb150015  *				    v
136faa1795aSjb150015  *
137faa1795aSjb150015  * States
138faa1795aSjb150015  * ------
139faa1795aSjb150015  *
140faa1795aSjb150015  * SMB_SERVER_STATE_CREATED
141faa1795aSjb150015  *
142faa1795aSjb150015  *    This is the state of the server just after creation.
143faa1795aSjb150015  *
144faa1795aSjb150015  * SMB_SERVER_STATE_CONFIGURED
145faa1795aSjb150015  *
146faa1795aSjb150015  *    The server has been configured.
147faa1795aSjb150015  *
148faa1795aSjb150015  * SMB_SERVER_STATE_RUNNING
149faa1795aSjb150015  *
150faa1795aSjb150015  *    The server has been started. While in this state the threads listening on
151faa1795aSjb150015  *    the sockets car be started. The smbd daemon does so through an Ioctl:
152faa1795aSjb150015  *
153faa1795aSjb150015  *	smb_drv_ioctl(SMB_IOC_NBT_LISTEN) --> smb_server_nbt_listen()
154faa1795aSjb150015  *	smb_drv_ioctl(SMB_IOC_TCP_LISTEN) --> smb_server_nbt_listen()
155faa1795aSjb150015  *
156faa1795aSjb150015  *    When a client establishes a connection the thread listening leaves
157faa1795aSjb150015  *    temporarily the kernel. While in user space it creates a thread for the
158faa1795aSjb150015  *    new session. It then returns to kernel with the result of the thread
159faa1795aSjb150015  *    creation. If the creation failed the new session context is destroyed
160faa1795aSjb150015  *    before returning listening.
161faa1795aSjb150015  *
162faa1795aSjb150015  *    The new created thread enters the kernel though an Ioctl:
163faa1795aSjb150015  *
164faa1795aSjb150015  *	smb_drv_ioctl(SMB_IOC_NBT_RECEIVE) --> smb_server_nbt_receive()
165faa1795aSjb150015  *	smb_drv_ioctl(SMB_IOC_TCP_RECEIVE) --> smb_server_tcp_receive()
166faa1795aSjb150015  *
167faa1795aSjb150015  * SMB_SERVER_STATE_STOPPING
168faa1795aSjb150015  *
169faa1795aSjb150015  *    The threads listening on the NBT and TCP sockets are being terminated.
170faa1795aSjb150015  *
171faa1795aSjb150015  *
172faa1795aSjb150015  * Transitions
173faa1795aSjb150015  * -----------
174faa1795aSjb150015  *
175faa1795aSjb150015  * Transition T0
176faa1795aSjb150015  *
177faa1795aSjb150015  *    The daemon smbd triggers its creation by opening the smbsrv device. If
178faa1795aSjb150015  *    the zone where the daemon lives doesn't have an smb server yet it is
179faa1795aSjb150015  *    created.
180faa1795aSjb150015  *
181faa1795aSjb150015  *		smb_drv_open() --> smb_server_create()
182faa1795aSjb150015  *
183faa1795aSjb150015  * Transition T1
184faa1795aSjb150015  *
185faa1795aSjb150015  *    This transition occurs in smb_server_configure(). It is triggered by the
186faa1795aSjb150015  *    daemon through an Ioctl.
187faa1795aSjb150015  *
188faa1795aSjb150015  *	smb_drv_ioctl(SMB_IOC_CONFIG) --> smb_server_configure()
189faa1795aSjb150015  *
190faa1795aSjb150015  * Transition T2
191faa1795aSjb150015  *
192faa1795aSjb150015  *    This transition occurs in smb_server_start(). It is triggered by the
193faa1795aSjb150015  *    daemon through an Ioctl.
194faa1795aSjb150015  *
195faa1795aSjb150015  *	smb_drv_ioctl(SMB_IOC_START) --> smb_server_start()
196faa1795aSjb150015  *
197faa1795aSjb150015  * Transition T3
198faa1795aSjb150015  *
199faa1795aSjb150015  *    This transition occurs in smb_server_delete(). It is triggered by the
200faa1795aSjb150015  *    daemon when closing the smbsrv device
201faa1795aSjb150015  *
202faa1795aSjb150015  *		smb_drv_close() --> smb_server_delete()
203faa1795aSjb150015  *
204faa1795aSjb150015  * Comments
205faa1795aSjb150015  * --------
206faa1795aSjb150015  *
207faa1795aSjb150015  * This files assumes that there will one SMB server per zone. For now the
208faa1795aSjb150015  * smb server works only in global zone. There's nothing in this file preventing
209faa1795aSjb150015  * an smb server from being created in a non global zone. That limitation is
210faa1795aSjb150015  * enforced in user space.
211faa1795aSjb150015  */
212faa1795aSjb150015 
213faa1795aSjb150015 #include <sys/strsubr.h>
214faa1795aSjb150015 #include <sys/cmn_err.h>
215faa1795aSjb150015 #include <sys/priv.h>
216faa1795aSjb150015 #include <sys/socketvar.h>
217faa1795aSjb150015 #include <sys/zone.h>
218bbf6f00cSJordan Brown #include <netinet/in.h>
219bbf6f00cSJordan Brown #include <netinet/in_systm.h>
220bbf6f00cSJordan Brown #include <netinet/ip.h>
221bbf6f00cSJordan Brown #include <netinet/ip_icmp.h>
222bbf6f00cSJordan Brown #include <netinet/ip_var.h>
223bbf6f00cSJordan Brown #include <netinet/tcp.h>
224faa1795aSjb150015 #include <smbsrv/smb_kproto.h>
225bbf6f00cSJordan Brown #include <smbsrv/string.h>
226faa1795aSjb150015 #include <smbsrv/netbios.h>
227faa1795aSjb150015 #include <smbsrv/smb_fsops.h>
2283db3f65cSamw #include <smbsrv/smb_share.h>
2299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <smbsrv/smb_door.h>
2306537f381Sas200622 #include <smbsrv/smb_kstat.h>
231faa1795aSjb150015 
2329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #define	SMB_EVENT_TIMEOUT		45	/* seconds */
2339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
234faa1795aSjb150015 extern void smb_dispatch_kstat_init(void);
235faa1795aSjb150015 extern void smb_dispatch_kstat_fini(void);
236faa1795aSjb150015 extern void smb_reply_notify_change_request(smb_request_t *);
237faa1795aSjb150015 
238faa1795aSjb150015 static int smb_server_kstat_init(smb_server_t *);
239faa1795aSjb150015 static void smb_server_kstat_fini(smb_server_t *);
240faa1795aSjb150015 static int smb_server_kstat_update_info(kstat_t *, int);
241faa1795aSjb150015 static void smb_server_timers(smb_thread_t *, void *);
242faa1795aSjb150015 static int smb_server_listen(smb_server_t *, smb_listener_daemon_t *,
2437f667e74Sjose borrego     in_port_t, int, int);
2449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void smb_server_listen_fini(smb_listener_daemon_t *);
2459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static kt_did_t smb_server_listener_tid(smb_listener_daemon_t *);
246faa1795aSjb150015 static int smb_server_lookup(smb_server_t **);
247faa1795aSjb150015 static void smb_server_release(smb_server_t *);
24829bd2886SAlan Wright static void smb_server_store_cfg(smb_server_t *, smb_ioc_cfg_t *);
2499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void smb_server_shutdown(smb_server_t *);
250faa1795aSjb150015 static int smb_server_fsop_start(smb_server_t *);
251faa1795aSjb150015 static void smb_server_fsop_stop(smb_server_t *);
2529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void smb_server_signal_listeners(smb_server_t *);
2539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void smb_event_cancel(smb_server_t *, uint32_t);
2549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void smb_event_notify(smb_server_t *, uint32_t);
2559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static uint32_t smb_event_alloc_txid(void);
256faa1795aSjb150015 
2579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void smb_server_disconnect_share(smb_session_list_t *, const char *);
2582c1b14e5Sjose borrego static void smb_server_thread_unexport(smb_thread_t *, void *);
2591fcced4cSJordan Brown static void smb_server_enum_private(smb_session_list_t *, smb_svcenum_t *);
2601fcced4cSJordan Brown static int smb_server_sesion_disconnect(smb_session_list_t *, const char *,
2611fcced4cSJordan Brown     const char *);
2621fcced4cSJordan Brown static int smb_server_fclose(smb_session_list_t *, uint32_t);
2631fcced4cSJordan Brown 
2649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int smb_event_debug = 0;
2659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
266faa1795aSjb150015 static smb_llist_t	smb_servers;
267faa1795aSjb150015 
268faa1795aSjb150015 /*
269faa1795aSjb150015  * *****************************************************************************
270faa1795aSjb150015  * **************** Functions called from the device interface *****************
271faa1795aSjb150015  * *****************************************************************************
272faa1795aSjb150015  *
2731fcced4cSJordan Brown  * These functions typically have to determine the relevant smb server
2741fcced4cSJordan Brown  * to which the call applies.
275faa1795aSjb150015  */
276faa1795aSjb150015 
277faa1795aSjb150015 /*
278faa1795aSjb150015  * smb_server_svc_init
279faa1795aSjb150015  *
280c8ec8eeaSjose borrego  * This function must be called from smb_drv_attach().
281faa1795aSjb150015  */
282faa1795aSjb150015 int
283faa1795aSjb150015 smb_server_svc_init(void)
284faa1795aSjb150015 {
285faa1795aSjb150015 	int	rc = 0;
286faa1795aSjb150015 
287faa1795aSjb150015 	while (rc == 0) {
2882c2961f8Sjose borrego 		if (rc = smb_mbc_init())
2892c2961f8Sjose borrego 			continue;
290faa1795aSjb150015 		if (rc = smb_vop_init())
291faa1795aSjb150015 			continue;
292faa1795aSjb150015 		if (rc = smb_node_init())
29321b7895dSjb150015 			continue;
294faa1795aSjb150015 		if (rc = smb_fem_init())
29521b7895dSjb150015 			continue;
296c8ec8eeaSjose borrego 		if (rc = smb_user_init())
297c8ec8eeaSjose borrego 			continue;
298faa1795aSjb150015 		if (rc = smb_notify_init())
29921b7895dSjb150015 			continue;
30021b7895dSjb150015 		if (rc = smb_net_init())
30121b7895dSjb150015 			continue;
3029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_llist_init();
303faa1795aSjb150015 		smb_llist_constructor(&smb_servers, sizeof (smb_server_t),
304faa1795aSjb150015 		    offsetof(smb_server_t, sv_lnd));
305faa1795aSjb150015 		return (0);
306faa1795aSjb150015 	}
3079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_llist_fini();
30921b7895dSjb150015 	smb_net_fini();
310faa1795aSjb150015 	smb_notify_fini();
311c8ec8eeaSjose borrego 	smb_user_fini();
312faa1795aSjb150015 	smb_fem_fini();
313faa1795aSjb150015 	smb_node_fini();
314faa1795aSjb150015 	smb_vop_fini();
3152c2961f8Sjose borrego 	smb_mbc_fini();
316faa1795aSjb150015 	return (rc);
317faa1795aSjb150015 }
318faa1795aSjb150015 
319faa1795aSjb150015 /*
320faa1795aSjb150015  * smb_server_svc_fini
321faa1795aSjb150015  *
322faa1795aSjb150015  * This function must called from smb_drv_detach(). It will fail if servers
323faa1795aSjb150015  * still exist.
324faa1795aSjb150015  */
325faa1795aSjb150015 int
326faa1795aSjb150015 smb_server_svc_fini(void)
327faa1795aSjb150015 {
328faa1795aSjb150015 	int	rc = EBUSY;
329faa1795aSjb150015 
330faa1795aSjb150015 	if (smb_llist_get_count(&smb_servers) == 0) {
3319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_llist_fini();
33221b7895dSjb150015 		smb_net_fini();
333faa1795aSjb150015 		smb_notify_fini();
334c8ec8eeaSjose borrego 		smb_user_fini();
335faa1795aSjb150015 		smb_fem_fini();
336faa1795aSjb150015 		smb_node_fini();
337faa1795aSjb150015 		smb_vop_fini();
3382c2961f8Sjose borrego 		smb_mbc_fini();
339faa1795aSjb150015 		smb_llist_destructor(&smb_servers);
340faa1795aSjb150015 		rc = 0;
341faa1795aSjb150015 	}
342faa1795aSjb150015 	return (rc);
343faa1795aSjb150015 }
344faa1795aSjb150015 
345faa1795aSjb150015 /*
346faa1795aSjb150015  * smb_server_create
347faa1795aSjb150015  *
348faa1795aSjb150015  * This function will fail if there's already a server associated with the
349faa1795aSjb150015  * caller's zone.
350faa1795aSjb150015  */
351faa1795aSjb150015 int
352faa1795aSjb150015 smb_server_create(void)
353faa1795aSjb150015 {
354faa1795aSjb150015 	zoneid_t	zid;
355faa1795aSjb150015 	smb_server_t	*sv;
356faa1795aSjb150015 
357faa1795aSjb150015 	zid = getzoneid();
358faa1795aSjb150015 
359faa1795aSjb150015 	smb_llist_enter(&smb_servers, RW_WRITER);
360faa1795aSjb150015 	sv = smb_llist_head(&smb_servers);
361faa1795aSjb150015 	while (sv) {
3629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		SMB_SERVER_VALID(sv);
363faa1795aSjb150015 		if (sv->sv_zid == zid) {
364faa1795aSjb150015 			smb_llist_exit(&smb_servers);
36594fff790SAlan Wright 			return (EPERM);
366faa1795aSjb150015 		}
367faa1795aSjb150015 		sv = smb_llist_next(&smb_servers, sv);
368faa1795aSjb150015 	}
369faa1795aSjb150015 
370faa1795aSjb150015 	sv = kmem_zalloc(sizeof (smb_server_t), KM_NOSLEEP);
371faa1795aSjb150015 	if (sv == NULL) {
372faa1795aSjb150015 		smb_llist_exit(&smb_servers);
373faa1795aSjb150015 		return (ENOMEM);
374faa1795aSjb150015 	}
375faa1795aSjb150015 
376faa1795aSjb150015 	smb_llist_constructor(&sv->sv_vfs_list, sizeof (smb_vfs_t),
377faa1795aSjb150015 	    offsetof(smb_vfs_t, sv_lnd));
378faa1795aSjb150015 
3799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_llist_constructor(&sv->sv_opipe_list, sizeof (smb_opipe_t),
3809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    offsetof(smb_opipe_t, p_lnd));
3819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_llist_constructor(&sv->sv_event_list, sizeof (smb_event_t),
3839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    offsetof(smb_event_t, se_lnd));
3849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3852c1b14e5Sjose borrego 	smb_slist_constructor(&sv->sv_unexport_list, sizeof (smb_unexport_t),
3862c1b14e5Sjose borrego 	    offsetof(smb_unexport_t, ux_lnd));
3872c1b14e5Sjose borrego 
388faa1795aSjb150015 	smb_session_list_constructor(&sv->sv_nbt_daemon.ld_session_list);
389faa1795aSjb150015 	smb_session_list_constructor(&sv->sv_tcp_daemon.ld_session_list);
390faa1795aSjb150015 
3912c1b14e5Sjose borrego 	sv->si_cache_unexport = kmem_cache_create("smb_unexport_cache",
3922c1b14e5Sjose borrego 	    sizeof (smb_unexport_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
393faa1795aSjb150015 	sv->si_cache_vfs = kmem_cache_create("smb_vfs_cache",
394faa1795aSjb150015 	    sizeof (smb_vfs_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
395faa1795aSjb150015 	sv->si_cache_request = kmem_cache_create("smb_request_cache",
396faa1795aSjb150015 	    sizeof (smb_request_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
397faa1795aSjb150015 	sv->si_cache_session = kmem_cache_create("smb_session_cache",
398faa1795aSjb150015 	    sizeof (smb_session_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
399faa1795aSjb150015 	sv->si_cache_user = kmem_cache_create("smb_user_cache",
400faa1795aSjb150015 	    sizeof (smb_user_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
401faa1795aSjb150015 	sv->si_cache_tree = kmem_cache_create("smb_tree_cache",
402faa1795aSjb150015 	    sizeof (smb_tree_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
403faa1795aSjb150015 	sv->si_cache_ofile = kmem_cache_create("smb_ofile_cache",
404faa1795aSjb150015 	    sizeof (smb_ofile_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
405faa1795aSjb150015 	sv->si_cache_odir = kmem_cache_create("smb_odir_cache",
406faa1795aSjb150015 	    sizeof (smb_odir_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
4079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	sv->si_cache_opipe = kmem_cache_create("smb_opipe_cache",
4089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    sizeof (smb_opipe_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
4099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	sv->si_cache_event = kmem_cache_create("smb_event_cache",
4109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    sizeof (smb_event_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
411faa1795aSjb150015 
412faa1795aSjb150015 	smb_thread_init(&sv->si_thread_timers,
413faa1795aSjb150015 	    "smb_timers", smb_server_timers, sv,
414faa1795aSjb150015 	    NULL, NULL);
415faa1795aSjb150015 
4162c1b14e5Sjose borrego 	smb_thread_init(&sv->si_thread_unexport, "smb_thread_unexport",
4172c1b14e5Sjose borrego 	    smb_server_thread_unexport, sv, NULL, NULL);
4182c1b14e5Sjose borrego 
4196537f381Sas200622 	sv->sv_pid = curproc->p_pid;
420faa1795aSjb150015 
4219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_kdoor_init();
4223db3f65cSamw 	smb_opipe_door_init();
423faa1795aSjb150015 	(void) smb_server_kstat_init(sv);
424faa1795aSjb150015 
425faa1795aSjb150015 	mutex_init(&sv->sv_mutex, NULL, MUTEX_DEFAULT, NULL);
426faa1795aSjb150015 	cv_init(&sv->sv_cv, NULL, CV_DEFAULT, NULL);
427faa1795aSjb150015 	sv->sv_state = SMB_SERVER_STATE_CREATED;
428faa1795aSjb150015 	sv->sv_magic = SMB_SERVER_MAGIC;
429faa1795aSjb150015 	sv->sv_zid = zid;
430faa1795aSjb150015 
431faa1795aSjb150015 	smb_llist_insert_tail(&smb_servers, sv);
432faa1795aSjb150015 	smb_llist_exit(&smb_servers);
433faa1795aSjb150015 	return (0);
434faa1795aSjb150015 }
435faa1795aSjb150015 
436faa1795aSjb150015 /*
437faa1795aSjb150015  * smb_server_delete
438faa1795aSjb150015  *
439faa1795aSjb150015  * This function will delete the server passed in. It will make sure that all
440faa1795aSjb150015  * activity associated that server has ceased before destroying it.
441faa1795aSjb150015  */
442faa1795aSjb150015 int
443faa1795aSjb150015 smb_server_delete(void)
444faa1795aSjb150015 {
445faa1795aSjb150015 	smb_server_t	*sv;
4462c1b14e5Sjose borrego 	smb_unexport_t	*ux;
4479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	kt_did_t	nbt_tid;
4489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	kt_did_t	tcp_tid;
449faa1795aSjb150015 	int		rc;
450faa1795aSjb150015 
451faa1795aSjb150015 	rc = smb_server_lookup(&sv);
452faa1795aSjb150015 	if (rc != 0)
453faa1795aSjb150015 		return (rc);
454faa1795aSjb150015 
455faa1795aSjb150015 	mutex_enter(&sv->sv_mutex);
456faa1795aSjb150015 	switch (sv->sv_state) {
457faa1795aSjb150015 	case SMB_SERVER_STATE_RUNNING:
4589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_SERVER_STATE_STOPPING:
4599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sv->sv_state = SMB_SERVER_STATE_STOPPING;
4609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_server_signal_listeners(sv);
4619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		nbt_tid = smb_server_listener_tid(&sv->sv_nbt_daemon);
4629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		tcp_tid = smb_server_listener_tid(&sv->sv_tcp_daemon);
463faa1795aSjb150015 
464faa1795aSjb150015 		sv->sv_state = SMB_SERVER_STATE_DELETING;
465faa1795aSjb150015 		mutex_exit(&sv->sv_mutex);
4669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
4679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (nbt_tid != 0)
4689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			thread_join(nbt_tid);
4699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (tcp_tid != 0)
4709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			thread_join(tcp_tid);
4719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
4729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_server_listen_fini(&sv->sv_nbt_daemon);
4739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_server_listen_fini(&sv->sv_tcp_daemon);
474faa1795aSjb150015 		mutex_enter(&sv->sv_mutex);
475faa1795aSjb150015 		break;
476faa1795aSjb150015 	case SMB_SERVER_STATE_CONFIGURED:
477faa1795aSjb150015 	case SMB_SERVER_STATE_CREATED:
478faa1795aSjb150015 		sv->sv_state = SMB_SERVER_STATE_DELETING;
479faa1795aSjb150015 		break;
480faa1795aSjb150015 	default:
4819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		SMB_SERVER_STATE_VALID(sv->sv_state);
482faa1795aSjb150015 		mutex_exit(&sv->sv_mutex);
483faa1795aSjb150015 		smb_server_release(sv);
484faa1795aSjb150015 		return (ENOTTY);
485faa1795aSjb150015 	}
486faa1795aSjb150015 
487faa1795aSjb150015 	ASSERT(sv->sv_state == SMB_SERVER_STATE_DELETING);
488faa1795aSjb150015 
489faa1795aSjb150015 	sv->sv_refcnt--;
490faa1795aSjb150015 	while (sv->sv_refcnt)
491faa1795aSjb150015 		cv_wait(&sv->sv_cv, &sv->sv_mutex);
492faa1795aSjb150015 
493faa1795aSjb150015 	mutex_exit(&sv->sv_mutex);
494faa1795aSjb150015 
495faa1795aSjb150015 	smb_llist_enter(&smb_servers, RW_WRITER);
496faa1795aSjb150015 	smb_llist_remove(&smb_servers, sv);
497faa1795aSjb150015 	smb_llist_exit(&smb_servers);
498faa1795aSjb150015 
4999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_server_shutdown(sv);
500faa1795aSjb150015 	rw_destroy(&sv->sv_cfg_lock);
5013db3f65cSamw 	smb_opipe_door_fini();
5029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_kdoor_fini();
503faa1795aSjb150015 	smb_server_kstat_fini(sv);
504faa1795aSjb150015 	smb_llist_destructor(&sv->sv_vfs_list);
5059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_llist_destructor(&sv->sv_opipe_list);
5069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_llist_destructor(&sv->sv_event_list);
5072c1b14e5Sjose borrego 
5082c1b14e5Sjose borrego 	while ((ux = list_head(&sv->sv_unexport_list.sl_list)) != NULL) {
5092c1b14e5Sjose borrego 		smb_slist_remove(&sv->sv_unexport_list, ux);
5102c1b14e5Sjose borrego 		kmem_cache_free(sv->si_cache_unexport, ux);
5112c1b14e5Sjose borrego 	}
5122c1b14e5Sjose borrego 	smb_slist_destructor(&sv->sv_unexport_list);
5132c1b14e5Sjose borrego 
5142c1b14e5Sjose borrego 	kmem_cache_destroy(sv->si_cache_unexport);
515faa1795aSjb150015 	kmem_cache_destroy(sv->si_cache_vfs);
516faa1795aSjb150015 	kmem_cache_destroy(sv->si_cache_request);
517faa1795aSjb150015 	kmem_cache_destroy(sv->si_cache_session);
518faa1795aSjb150015 	kmem_cache_destroy(sv->si_cache_user);
519faa1795aSjb150015 	kmem_cache_destroy(sv->si_cache_tree);
520faa1795aSjb150015 	kmem_cache_destroy(sv->si_cache_ofile);
521faa1795aSjb150015 	kmem_cache_destroy(sv->si_cache_odir);
5229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	kmem_cache_destroy(sv->si_cache_opipe);
5239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	kmem_cache_destroy(sv->si_cache_event);
524faa1795aSjb150015 
525faa1795aSjb150015 	smb_thread_destroy(&sv->si_thread_timers);
5262c1b14e5Sjose borrego 	smb_thread_destroy(&sv->si_thread_unexport);
527faa1795aSjb150015 	mutex_destroy(&sv->sv_mutex);
528faa1795aSjb150015 	cv_destroy(&sv->sv_cv);
529faa1795aSjb150015 	sv->sv_magic = 0;
530faa1795aSjb150015 	kmem_free(sv, sizeof (smb_server_t));
531faa1795aSjb150015 
532faa1795aSjb150015 	return (0);
533faa1795aSjb150015 }
534faa1795aSjb150015 
535faa1795aSjb150015 /*
536faa1795aSjb150015  * smb_server_configure
537faa1795aSjb150015  */
538faa1795aSjb150015 int
53929bd2886SAlan Wright smb_server_configure(smb_ioc_cfg_t *ioc)
540faa1795aSjb150015 {
541faa1795aSjb150015 	int		rc = 0;
542faa1795aSjb150015 	smb_server_t	*sv;
543faa1795aSjb150015 
544faa1795aSjb150015 	rc = smb_server_lookup(&sv);
545faa1795aSjb150015 	if (rc)
546faa1795aSjb150015 		return (rc);
547faa1795aSjb150015 
548faa1795aSjb150015 	mutex_enter(&sv->sv_mutex);
549faa1795aSjb150015 	switch (sv->sv_state) {
550faa1795aSjb150015 	case SMB_SERVER_STATE_CREATED:
55129bd2886SAlan Wright 		smb_server_store_cfg(sv, ioc);
552faa1795aSjb150015 		sv->sv_state = SMB_SERVER_STATE_CONFIGURED;
553faa1795aSjb150015 		break;
554faa1795aSjb150015 
555faa1795aSjb150015 	case SMB_SERVER_STATE_CONFIGURED:
55629bd2886SAlan Wright 		smb_server_store_cfg(sv, ioc);
557faa1795aSjb150015 		break;
558faa1795aSjb150015 
559faa1795aSjb150015 	case SMB_SERVER_STATE_RUNNING:
5609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_SERVER_STATE_STOPPING:
561faa1795aSjb150015 		rw_enter(&sv->sv_cfg_lock, RW_WRITER);
56229bd2886SAlan Wright 		smb_server_store_cfg(sv, ioc);
563faa1795aSjb150015 		rw_exit(&sv->sv_cfg_lock);
564faa1795aSjb150015 		break;
565faa1795aSjb150015 
566faa1795aSjb150015 	default:
5679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		SMB_SERVER_STATE_VALID(sv->sv_state);
568faa1795aSjb150015 		rc = EFAULT;
569faa1795aSjb150015 		break;
570faa1795aSjb150015 	}
571faa1795aSjb150015 	mutex_exit(&sv->sv_mutex);
572faa1795aSjb150015 
573faa1795aSjb150015 	smb_server_release(sv);
574faa1795aSjb150015 
575faa1795aSjb150015 	return (rc);
576faa1795aSjb150015 }
577faa1795aSjb150015 
578faa1795aSjb150015 /*
579faa1795aSjb150015  * smb_server_start
580faa1795aSjb150015  */
581faa1795aSjb150015 int
58229bd2886SAlan Wright smb_server_start(smb_ioc_start_t *ioc)
583faa1795aSjb150015 {
584faa1795aSjb150015 	int		rc = 0;
585faa1795aSjb150015 	smb_server_t	*sv;
586faa1795aSjb150015 
587faa1795aSjb150015 	rc = smb_server_lookup(&sv);
588faa1795aSjb150015 	if (rc)
589faa1795aSjb150015 		return (rc);
590faa1795aSjb150015 
591faa1795aSjb150015 	mutex_enter(&sv->sv_mutex);
592faa1795aSjb150015 	switch (sv->sv_state) {
593faa1795aSjb150015 	case SMB_SERVER_STATE_CONFIGURED:
594bbf6f00cSJordan Brown 		smb_codepage_init();
595faa1795aSjb150015 
596faa1795aSjb150015 		sv->sv_thread_pool = taskq_create("smb_workers",
597faa1795aSjb150015 		    sv->sv_cfg.skc_maxworkers, SMB_WORKER_PRIORITY,
598faa1795aSjb150015 		    sv->sv_cfg.skc_maxworkers, INT_MAX,
599faa1795aSjb150015 		    TASKQ_DYNAMIC|TASKQ_PREPOPULATE);
600faa1795aSjb150015 
6017f667e74Sjose borrego 		sv->sv_session = smb_session_create(NULL, 0, sv, 0);
6028d96b23eSAlan Wright 
6038d96b23eSAlan Wright 		if (sv->sv_thread_pool == NULL || sv->sv_session == NULL) {
604faa1795aSjb150015 			rc = ENOMEM;
605faa1795aSjb150015 			break;
606faa1795aSjb150015 		}
607faa1795aSjb150015 
608faa1795aSjb150015 		if (rc = smb_server_fsop_start(sv))
609faa1795aSjb150015 			break;
610faa1795aSjb150015 		ASSERT(sv->sv_lmshrd == NULL);
61129bd2886SAlan Wright 		sv->sv_lmshrd = smb_kshare_init(ioc->lmshrd);
612faa1795aSjb150015 		if (sv->sv_lmshrd == NULL)
613faa1795aSjb150015 			break;
6149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (rc = smb_kdoor_open(ioc->udoor)) {
6159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			cmn_err(CE_WARN, "Cannot open smbd door");
616faa1795aSjb150015 			break;
6179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
61829bd2886SAlan Wright 		if (rc = smb_opipe_door_open(ioc->opipe)) {
6193db3f65cSamw 			cmn_err(CE_WARN, "Cannot open opipe door");
620faa1795aSjb150015 			break;
621faa1795aSjb150015 		}
6229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (rc = smb_thread_start(&sv->si_thread_timers))
6239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			break;
6249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (rc = smb_thread_start(&sv->si_thread_unexport))
6259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			break;
626faa1795aSjb150015 		sv->sv_state = SMB_SERVER_STATE_RUNNING;
627faa1795aSjb150015 		mutex_exit(&sv->sv_mutex);
628faa1795aSjb150015 		smb_server_release(sv);
629faa1795aSjb150015 		return (0);
630faa1795aSjb150015 	default:
6319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		SMB_SERVER_STATE_VALID(sv->sv_state);
632faa1795aSjb150015 		mutex_exit(&sv->sv_mutex);
633faa1795aSjb150015 		smb_server_release(sv);
634faa1795aSjb150015 		return (ENOTTY);
635faa1795aSjb150015 	}
636faa1795aSjb150015 
6379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_server_shutdown(sv);
638faa1795aSjb150015 	mutex_exit(&sv->sv_mutex);
639faa1795aSjb150015 	smb_server_release(sv);
640faa1795aSjb150015 	return (rc);
641faa1795aSjb150015 }
642faa1795aSjb150015 
643faa1795aSjb150015 /*
6449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * An smbd is shutting down.
6459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
6469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int
6479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_stop(void)
6489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
6499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_server_t	*sv;
6509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int		rc;
6519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((rc = smb_server_lookup(&sv)) != 0)
6539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (rc);
6549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&sv->sv_mutex);
6569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	switch (sv->sv_state) {
6579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_SERVER_STATE_RUNNING:
6589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sv->sv_state = SMB_SERVER_STATE_STOPPING;
6599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_server_signal_listeners(sv);
6609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
6619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	default:
6629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		SMB_SERVER_STATE_VALID(sv->sv_state);
6639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
6649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
6659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&sv->sv_mutex);
6669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_server_release(sv);
6689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (0);
6699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
6709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States boolean_t
6729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_is_stopping(void)
6739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
6749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_server_t	*sv;
6759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	boolean_t	status;
6769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_server_lookup(&sv) != 0)
6789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (B_TRUE);
6799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	SMB_SERVER_VALID(sv);
6819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&sv->sv_mutex);
6839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	switch (sv->sv_state) {
6859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_SERVER_STATE_STOPPING:
6869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_SERVER_STATE_DELETING:
6879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		status = B_TRUE;
6889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
6899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	default:
6909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		status = B_FALSE;
6919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
6929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
6939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&sv->sv_mutex);
6959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_server_release(sv);
6969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (status);
6979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
6989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int
7009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_cancel_event(uint32_t txid)
7019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
7029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_server_t	*sv;
7039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int		rc;
7049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
7059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((rc = smb_server_lookup(&sv)) == 0) {
7069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_event_cancel(sv, txid);
7079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_server_release(sv);
7089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
7099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
7109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (rc);
7119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
7129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
7139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int
7149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_notify_event(smb_ioc_event_t *ioc)
7159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
7169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_server_t	*sv;
7179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int		rc;
7189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
7199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((rc = smb_server_lookup(&sv)) == 0) {
7209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_event_notify(sv, ioc->txid);
7219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_server_release(sv);
7229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
7239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
7249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (rc);
7259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
7269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
7279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
7289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * SMB-over-NetBIOS (port 139)
729faa1795aSjb150015  *
7309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Traditional SMB service over NetBIOS, which requires that a NetBIOS
7319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * session be established.
732faa1795aSjb150015  */
733faa1795aSjb150015 int
73429bd2886SAlan Wright smb_server_nbt_listen(smb_ioc_listen_t *ioc)
735faa1795aSjb150015 {
736faa1795aSjb150015 	smb_server_t	*sv;
737faa1795aSjb150015 	int		rc;
738faa1795aSjb150015 
739faa1795aSjb150015 	rc = smb_server_lookup(&sv);
740faa1795aSjb150015 	if (rc)
741faa1795aSjb150015 		return (rc);
742faa1795aSjb150015 
743faa1795aSjb150015 	mutex_enter(&sv->sv_mutex);
744faa1795aSjb150015 	switch (sv->sv_state) {
745faa1795aSjb150015 	case SMB_SERVER_STATE_RUNNING:
746faa1795aSjb150015 		if ((sv->sv_nbt_daemon.ld_kth != NULL) &&
747faa1795aSjb150015 		    (sv->sv_nbt_daemon.ld_kth != curthread)) {
748faa1795aSjb150015 			mutex_exit(&sv->sv_mutex);
74908f0d8daSafshin salek ardakani - Sun Microsystems - Irvine United States 			smb_server_release(sv);
750faa1795aSjb150015 			return (EACCES);
751faa1795aSjb150015 		} else {
752faa1795aSjb150015 			sv->sv_nbt_daemon.ld_kth = curthread;
753faa1795aSjb150015 			sv->sv_nbt_daemon.ld_ktdid = curthread->t_did;
754faa1795aSjb150015 		}
755faa1795aSjb150015 		break;
7569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_SERVER_STATE_STOPPING:
7579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		mutex_exit(&sv->sv_mutex);
7589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_server_release(sv);
7599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (ECANCELED);
760faa1795aSjb150015 	default:
7619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		SMB_SERVER_STATE_VALID(sv->sv_state);
762faa1795aSjb150015 		mutex_exit(&sv->sv_mutex);
763faa1795aSjb150015 		smb_server_release(sv);
764faa1795aSjb150015 		return (EFAULT);
765faa1795aSjb150015 	}
766faa1795aSjb150015 	mutex_exit(&sv->sv_mutex);
767faa1795aSjb150015 
7687f667e74Sjose borrego 	/*
7697f667e74Sjose borrego 	 * netbios must be ipv4
7707f667e74Sjose borrego 	 */
771a0aa776eSAlan Wright 	rc = smb_server_listen(sv, &sv->sv_nbt_daemon, IPPORT_NETBIOS_SSN,
77229bd2886SAlan Wright 	    AF_INET, ioc->error);
773faa1795aSjb150015 
774faa1795aSjb150015 	mutex_enter(&sv->sv_mutex);
775faa1795aSjb150015 	sv->sv_nbt_daemon.ld_kth = NULL;
7769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
777faa1795aSjb150015 	mutex_exit(&sv->sv_mutex);
778faa1795aSjb150015 
779faa1795aSjb150015 	smb_server_release(sv);
780faa1795aSjb150015 	return (rc);
781faa1795aSjb150015 }
782faa1795aSjb150015 
7839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
7849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *  SMB-over-TCP (port 445)
7859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
786faa1795aSjb150015 int
78729bd2886SAlan Wright smb_server_tcp_listen(smb_ioc_listen_t *ioc)
788faa1795aSjb150015 {
789faa1795aSjb150015 	smb_server_t	*sv;
790faa1795aSjb150015 	int		rc;
791faa1795aSjb150015 
792faa1795aSjb150015 	rc = smb_server_lookup(&sv);
793faa1795aSjb150015 	if (rc)
794faa1795aSjb150015 		return (rc);
795faa1795aSjb150015 
796faa1795aSjb150015 	mutex_enter(&sv->sv_mutex);
797faa1795aSjb150015 	switch (sv->sv_state) {
798faa1795aSjb150015 	case SMB_SERVER_STATE_RUNNING:
7999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if ((sv->sv_tcp_daemon.ld_kth != NULL) &&
800faa1795aSjb150015 		    (sv->sv_tcp_daemon.ld_kth != curthread)) {
801faa1795aSjb150015 			mutex_exit(&sv->sv_mutex);
80208f0d8daSafshin salek ardakani - Sun Microsystems - Irvine United States 			smb_server_release(sv);
803faa1795aSjb150015 			return (EACCES);
804faa1795aSjb150015 		} else {
805faa1795aSjb150015 			sv->sv_tcp_daemon.ld_kth = curthread;
806faa1795aSjb150015 			sv->sv_tcp_daemon.ld_ktdid = curthread->t_did;
807faa1795aSjb150015 		}
808faa1795aSjb150015 		break;
8099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_SERVER_STATE_STOPPING:
8109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		mutex_exit(&sv->sv_mutex);
8119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_server_release(sv);
8129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (ECANCELED);
813faa1795aSjb150015 	default:
8149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		SMB_SERVER_STATE_VALID(sv->sv_state);
815faa1795aSjb150015 		mutex_exit(&sv->sv_mutex);
81608f0d8daSafshin salek ardakani - Sun Microsystems - Irvine United States 		smb_server_release(sv);
817faa1795aSjb150015 		return (EFAULT);
818faa1795aSjb150015 	}
819faa1795aSjb150015 	mutex_exit(&sv->sv_mutex);
820faa1795aSjb150015 
8217f667e74Sjose borrego 	if (sv->sv_cfg.skc_ipv6_enable)
8227f667e74Sjose borrego 		rc = smb_server_listen(sv, &sv->sv_tcp_daemon,
823a0aa776eSAlan Wright 		    IPPORT_SMB, AF_INET6, ioc->error);
8247f667e74Sjose borrego 	else
8257f667e74Sjose borrego 		rc = smb_server_listen(sv, &sv->sv_tcp_daemon,
826a0aa776eSAlan Wright 		    IPPORT_SMB, AF_INET, ioc->error);
8279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
828faa1795aSjb150015 	mutex_enter(&sv->sv_mutex);
829faa1795aSjb150015 	sv->sv_tcp_daemon.ld_kth = NULL;
8309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
831faa1795aSjb150015 	mutex_exit(&sv->sv_mutex);
832faa1795aSjb150015 
833faa1795aSjb150015 	smb_server_release(sv);
834faa1795aSjb150015 	return (rc);
835faa1795aSjb150015 }
836faa1795aSjb150015 
837faa1795aSjb150015 /*
838faa1795aSjb150015  * smb_server_nbt_receive
839faa1795aSjb150015  */
840faa1795aSjb150015 int
841faa1795aSjb150015 smb_server_nbt_receive(void)
842faa1795aSjb150015 {
843faa1795aSjb150015 	int		rc;
844faa1795aSjb150015 	smb_server_t	*sv;
845faa1795aSjb150015 
84608f0d8daSafshin salek ardakani - Sun Microsystems - Irvine United States 	if ((rc = smb_server_lookup(&sv)) == 0) {
847faa1795aSjb150015 		rc = smb_session_daemon(&sv->sv_nbt_daemon.ld_session_list);
848faa1795aSjb150015 		smb_server_release(sv);
84908f0d8daSafshin salek ardakani - Sun Microsystems - Irvine United States 	}
850faa1795aSjb150015 
851faa1795aSjb150015 	return (rc);
852faa1795aSjb150015 }
853faa1795aSjb150015 
854faa1795aSjb150015 /*
855faa1795aSjb150015  * smb_server_tcp_receive
856faa1795aSjb150015  */
857faa1795aSjb150015 int
858faa1795aSjb150015 smb_server_tcp_receive(void)
859faa1795aSjb150015 {
860faa1795aSjb150015 	int		rc;
861faa1795aSjb150015 	smb_server_t	*sv;
862faa1795aSjb150015 
86308f0d8daSafshin salek ardakani - Sun Microsystems - Irvine United States 	if ((rc = smb_server_lookup(&sv)) == 0) {
864faa1795aSjb150015 		rc = smb_session_daemon(&sv->sv_tcp_daemon.ld_session_list);
865faa1795aSjb150015 		smb_server_release(sv);
86608f0d8daSafshin salek ardakani - Sun Microsystems - Irvine United States 	}
867faa1795aSjb150015 
868faa1795aSjb150015 	return (rc);
869faa1795aSjb150015 }
870faa1795aSjb150015 
871faa1795aSjb150015 int
87229bd2886SAlan Wright smb_server_set_gmtoff(smb_ioc_gmt_t *ioc)
873faa1795aSjb150015 {
874faa1795aSjb150015 	int		rc;
875faa1795aSjb150015 	smb_server_t	*sv;
876faa1795aSjb150015 
87708f0d8daSafshin salek ardakani - Sun Microsystems - Irvine United States 	if ((rc = smb_server_lookup(&sv)) == 0) {
87829bd2886SAlan Wright 		sv->si_gmtoff = ioc->offset;
879faa1795aSjb150015 		smb_server_release(sv);
88008f0d8daSafshin salek ardakani - Sun Microsystems - Irvine United States 	}
881faa1795aSjb150015 
882faa1795aSjb150015 	return (rc);
883faa1795aSjb150015 }
884faa1795aSjb150015 
88529bd2886SAlan Wright int
8861fcced4cSJordan Brown smb_server_numopen(smb_ioc_opennum_t *ioc)
88729bd2886SAlan Wright {
88829bd2886SAlan Wright 	smb_server_t	*sv;
88929bd2886SAlan Wright 	int		rc;
89029bd2886SAlan Wright 
89129bd2886SAlan Wright 	if ((rc = smb_server_lookup(&sv)) == 0) {
8921fcced4cSJordan Brown 		ioc->open_users = sv->sv_open_users;
8931fcced4cSJordan Brown 		ioc->open_trees = sv->sv_open_trees;
8941fcced4cSJordan Brown 		ioc->open_files = sv->sv_open_files;
89529bd2886SAlan Wright 		smb_server_release(sv);
89629bd2886SAlan Wright 	}
89729bd2886SAlan Wright 	return (rc);
89829bd2886SAlan Wright }
89929bd2886SAlan Wright 
900faa1795aSjb150015 /*
9011fcced4cSJordan Brown  * Enumerate objects within the server.  The svcenum provides the
9021fcced4cSJordan Brown  * enumeration context, i.e. what the caller want to get back.
9031fcced4cSJordan Brown  */
9041fcced4cSJordan Brown int
9051fcced4cSJordan Brown smb_server_enum(smb_ioc_svcenum_t *ioc)
9061fcced4cSJordan Brown {
9071fcced4cSJordan Brown 	smb_svcenum_t		*svcenum = &ioc->svcenum;
9081fcced4cSJordan Brown 	smb_server_t		*sv;
9091fcced4cSJordan Brown 	smb_session_list_t	*se;
9101fcced4cSJordan Brown 	int			rc;
9111fcced4cSJordan Brown 
9121fcced4cSJordan Brown 	switch (svcenum->se_type) {
9131fcced4cSJordan Brown 	case SMB_SVCENUM_TYPE_USER:
9141fcced4cSJordan Brown 	case SMB_SVCENUM_TYPE_TREE:
9151fcced4cSJordan Brown 	case SMB_SVCENUM_TYPE_FILE:
9161fcced4cSJordan Brown 		break;
9171fcced4cSJordan Brown 	default:
9181fcced4cSJordan Brown 		return (EINVAL);
9191fcced4cSJordan Brown 	}
9201fcced4cSJordan Brown 
9211fcced4cSJordan Brown 	if ((rc = smb_server_lookup(&sv)) != 0)
9221fcced4cSJordan Brown 		return (rc);
9231fcced4cSJordan Brown 
9241fcced4cSJordan Brown 	svcenum->se_bavail = svcenum->se_buflen;
9251fcced4cSJordan Brown 	svcenum->se_bused = 0;
9261fcced4cSJordan Brown 	svcenum->se_nitems = 0;
9271fcced4cSJordan Brown 
9281fcced4cSJordan Brown 	se = &sv->sv_nbt_daemon.ld_session_list;
9291fcced4cSJordan Brown 	smb_server_enum_private(se, svcenum);
9301fcced4cSJordan Brown 
9311fcced4cSJordan Brown 	se = &sv->sv_tcp_daemon.ld_session_list;
9321fcced4cSJordan Brown 	smb_server_enum_private(se, svcenum);
9331fcced4cSJordan Brown 
9341fcced4cSJordan Brown 	smb_server_release(sv);
9351fcced4cSJordan Brown 	return (0);
9361fcced4cSJordan Brown }
9371fcced4cSJordan Brown 
9381fcced4cSJordan Brown /*
9391fcced4cSJordan Brown  * Look for sessions to disconnect by client and user name.
9401fcced4cSJordan Brown  */
9411fcced4cSJordan Brown int
9421fcced4cSJordan Brown smb_server_session_close(smb_ioc_session_t *ioc)
9431fcced4cSJordan Brown {
9441fcced4cSJordan Brown 	smb_session_list_t	*se;
9451fcced4cSJordan Brown 	smb_server_t		*sv;
9461fcced4cSJordan Brown 	int			nbt_cnt;
9471fcced4cSJordan Brown 	int			tcp_cnt;
9481fcced4cSJordan Brown 	int			rc;
9491fcced4cSJordan Brown 
9501fcced4cSJordan Brown 	if ((rc = smb_server_lookup(&sv)) != 0)
9511fcced4cSJordan Brown 		return (rc);
9521fcced4cSJordan Brown 
9531fcced4cSJordan Brown 	se = &sv->sv_nbt_daemon.ld_session_list;
9541fcced4cSJordan Brown 	nbt_cnt = smb_server_sesion_disconnect(se, ioc->client, ioc->username);
9551fcced4cSJordan Brown 
9561fcced4cSJordan Brown 	se = &sv->sv_tcp_daemon.ld_session_list;
9571fcced4cSJordan Brown 	tcp_cnt = smb_server_sesion_disconnect(se, ioc->client, ioc->username);
9581fcced4cSJordan Brown 
9591fcced4cSJordan Brown 	smb_server_release(sv);
9601fcced4cSJordan Brown 
9611fcced4cSJordan Brown 	if ((nbt_cnt == 0) && (tcp_cnt == 0))
9621fcced4cSJordan Brown 		return (ENOENT);
9631fcced4cSJordan Brown 	return (0);
9641fcced4cSJordan Brown }
9651fcced4cSJordan Brown 
9661fcced4cSJordan Brown /*
9671fcced4cSJordan Brown  * Close a file by uniqid.
9681fcced4cSJordan Brown  */
9691fcced4cSJordan Brown int
9701fcced4cSJordan Brown smb_server_file_close(smb_ioc_fileid_t *ioc)
9711fcced4cSJordan Brown {
9721fcced4cSJordan Brown 	uint32_t		uniqid = ioc->uniqid;
9731fcced4cSJordan Brown 	smb_session_list_t	*se;
9741fcced4cSJordan Brown 	smb_server_t		*sv;
9751fcced4cSJordan Brown 	int			rc;
9761fcced4cSJordan Brown 
9771fcced4cSJordan Brown 	if ((rc = smb_server_lookup(&sv)) != 0)
9781fcced4cSJordan Brown 		return (rc);
9791fcced4cSJordan Brown 
9801fcced4cSJordan Brown 	se = &sv->sv_nbt_daemon.ld_session_list;
9811fcced4cSJordan Brown 	rc = smb_server_fclose(se, uniqid);
9821fcced4cSJordan Brown 
9831fcced4cSJordan Brown 	if (rc == ENOENT) {
9841fcced4cSJordan Brown 		se = &sv->sv_tcp_daemon.ld_session_list;
9851fcced4cSJordan Brown 		rc = smb_server_fclose(se, uniqid);
9861fcced4cSJordan Brown 	}
9871fcced4cSJordan Brown 
9881fcced4cSJordan Brown 	smb_server_release(sv);
9891fcced4cSJordan Brown 	return (rc);
9901fcced4cSJordan Brown }
9911fcced4cSJordan Brown 
9921fcced4cSJordan Brown /*
993faa1795aSjb150015  * These functions determine the relevant smb server to which the call apply.
994faa1795aSjb150015  */
995faa1795aSjb150015 
996faa1795aSjb150015 uint32_t
997faa1795aSjb150015 smb_server_get_session_count(void)
998faa1795aSjb150015 {
999faa1795aSjb150015 	smb_server_t	*sv;
1000faa1795aSjb150015 	uint32_t	counter = 0;
1001faa1795aSjb150015 
1002faa1795aSjb150015 	if (smb_server_lookup(&sv))
1003faa1795aSjb150015 		return (0);
1004faa1795aSjb150015 
1005faa1795aSjb150015 	rw_enter(&sv->sv_nbt_daemon.ld_session_list.se_lock, RW_READER);
1006faa1795aSjb150015 	counter = sv->sv_nbt_daemon.ld_session_list.se_act.count;
1007faa1795aSjb150015 	rw_exit(&sv->sv_nbt_daemon.ld_session_list.se_lock);
1008faa1795aSjb150015 	rw_enter(&sv->sv_tcp_daemon.ld_session_list.se_lock, RW_READER);
1009faa1795aSjb150015 	counter += sv->sv_tcp_daemon.ld_session_list.se_act.count;
1010faa1795aSjb150015 	rw_exit(&sv->sv_tcp_daemon.ld_session_list.se_lock);
1011faa1795aSjb150015 
1012faa1795aSjb150015 	smb_server_release(sv);
1013faa1795aSjb150015 
1014faa1795aSjb150015 	return (counter);
1015faa1795aSjb150015 }
1016faa1795aSjb150015 
1017faa1795aSjb150015 /*
10189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Disconnect the specified share.
10199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Typically called when a share has been removed.
1020faa1795aSjb150015  */
10212c1b14e5Sjose borrego static void
10229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_disconnect_share(smb_session_list_t *slist, const char *sharename)
1023faa1795aSjb150015 {
10249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_session_t		*session;
10259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
10269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	rw_enter(&slist->se_lock, RW_READER);
10279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
10289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	session = list_head(&slist->se_act.lst);
10299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	while (session) {
10309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		ASSERT(session->s_magic == SMB_SESSION_MAGIC);
10319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_rwx_rwenter(&session->s_lock, RW_READER);
10329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		switch (session->s_state) {
10339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		case SMB_SESSION_STATE_NEGOTIATED:
10349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		case SMB_SESSION_STATE_OPLOCK_BREAKING:
10359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		case SMB_SESSION_STATE_WRITE_RAW_ACTIVE:
10369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			smb_session_disconnect_share(session, sharename);
10379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			break;
10389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		default:
10399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			break;
10409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
10419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_rwx_rwexit(&session->s_lock);
10429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		session = list_next(&slist->se_act.lst, session);
10439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
10449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
10459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	rw_exit(&slist->se_lock);
1046faa1795aSjb150015 }
1047faa1795aSjb150015 
1048faa1795aSjb150015 /*
1049faa1795aSjb150015  * smb_server_share_export()
1050faa1795aSjb150015  *
1051faa1795aSjb150015  * This function handles kernel processing at share enable time.
1052faa1795aSjb150015  *
1053faa1795aSjb150015  * At share-enable time (LMSHRD_ADD), the file system corresponding to
1054faa1795aSjb150015  * the share is checked for characteristics that are required for SMB
1055faa1795aSjb150015  * sharing.  If this check passes, then a hold is taken on the root vnode
1056faa1795aSjb150015  * of the file system (or a reference count on the corresponding smb_vfs_t
1057faa1795aSjb150015  * is bumped), preventing an unmount.  (See smb_vfs_hold()).
1058faa1795aSjb150015  */
1059faa1795aSjb150015 
1060faa1795aSjb150015 int
106129bd2886SAlan Wright smb_server_share_export(smb_ioc_share_t *ioc)
1062faa1795aSjb150015 {
1063faa1795aSjb150015 	smb_server_t	*sv;
106408f0d8daSafshin salek ardakani - Sun Microsystems - Irvine United States 	int		error = 0;
1065faa1795aSjb150015 	smb_node_t	*fnode = NULL;
1066faa1795aSjb150015 	smb_node_t	*dnode;
1067faa1795aSjb150015 	char		last_comp[MAXNAMELEN];
1068faa1795aSjb150015 	smb_request_t	*sr;
1069faa1795aSjb150015 
1070faa1795aSjb150015 	if (smb_server_lookup(&sv))
1071faa1795aSjb150015 		return (EINVAL);
1072faa1795aSjb150015 
107329bd2886SAlan Wright 	mutex_enter(&sv->sv_mutex);
107429bd2886SAlan Wright 	switch (sv->sv_state) {
107529bd2886SAlan Wright 	case SMB_SERVER_STATE_RUNNING:
10769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_SERVER_STATE_STOPPING:
107729bd2886SAlan Wright 		break;
107829bd2886SAlan Wright 	default:
107929bd2886SAlan Wright 		mutex_exit(&sv->sv_mutex);
108029bd2886SAlan Wright 		return (ENOTACTIVE);
108129bd2886SAlan Wright 	}
108229bd2886SAlan Wright 	mutex_exit(&sv->sv_mutex);
108329bd2886SAlan Wright 
1084faa1795aSjb150015 	sr = smb_request_alloc(sv->sv_session, 0);
1085faa1795aSjb150015 	if (sr == NULL) {
1086faa1795aSjb150015 		smb_server_release(sv);
1087faa1795aSjb150015 		return (ENOMEM);
1088faa1795aSjb150015 	}
1089faa1795aSjb150015 
1090faa1795aSjb150015 	sr->user_cr = kcred;
1091faa1795aSjb150015 
109229bd2886SAlan Wright 	error = smb_pathname_reduce(sr, kcred, ioc->path,
109329bd2886SAlan Wright 	    NULL, NULL, &dnode, last_comp);
1094faa1795aSjb150015 
1095faa1795aSjb150015 	if (error) {
1096faa1795aSjb150015 		smb_request_free(sr);
1097faa1795aSjb150015 		smb_server_release(sv);
1098faa1795aSjb150015 		return (error);
1099faa1795aSjb150015 	}
1100faa1795aSjb150015 
11018b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	error = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS,
1102037cac00Sjoyce mcintosh 	    sv->si_root_smb_node, dnode, last_comp, &fnode);
1103faa1795aSjb150015 
1104faa1795aSjb150015 	smb_node_release(dnode);
1105faa1795aSjb150015 
1106faa1795aSjb150015 	if (error) {
1107faa1795aSjb150015 		smb_request_free(sr);
1108faa1795aSjb150015 		smb_server_release(sv);
1109faa1795aSjb150015 		return (error);
1110faa1795aSjb150015 	}
1111faa1795aSjb150015 
1112faa1795aSjb150015 	ASSERT(fnode->vp && fnode->vp->v_vfsp);
1113faa1795aSjb150015 
1114faa1795aSjb150015 #ifdef SMB_ENFORCE_NODEV
111508f0d8daSafshin salek ardakani - Sun Microsystems - Irvine United States 	if (vfs_optionisset(fnode->vp->v_vfsp, MNTOPT_NODEVICES, NULL) == 0) {
1116faa1795aSjb150015 		smb_node_release(fnode);
1117faa1795aSjb150015 		smb_request_free(sr);
1118faa1795aSjb150015 		smb_server_release(sv);
111908f0d8daSafshin salek ardakani - Sun Microsystems - Irvine United States 		return (EINVAL);
1120faa1795aSjb150015 	}
112108f0d8daSafshin salek ardakani - Sun Microsystems - Irvine United States #endif /* SMB_ENFORCE_NODEV */
112208f0d8daSafshin salek ardakani - Sun Microsystems - Irvine United States 
112308f0d8daSafshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_vfs_hold(sv, fnode->vp->v_vfsp))
112408f0d8daSafshin salek ardakani - Sun Microsystems - Irvine United States 		error = ENOMEM;
1125faa1795aSjb150015 
1126faa1795aSjb150015 	/*
1127faa1795aSjb150015 	 * The refcount on the smb_vfs has been incremented.
1128faa1795aSjb150015 	 * If it wasn't already, a hold has also been taken
1129faa1795aSjb150015 	 * on the root vnode of the file system.
1130faa1795aSjb150015 	 */
1131faa1795aSjb150015 
1132faa1795aSjb150015 	smb_node_release(fnode);
1133faa1795aSjb150015 	smb_request_free(sr);
1134faa1795aSjb150015 	smb_server_release(sv);
113508f0d8daSafshin salek ardakani - Sun Microsystems - Irvine United States 	return (error);
1136faa1795aSjb150015 }
1137faa1795aSjb150015 
1138faa1795aSjb150015 /*
1139faa1795aSjb150015  * smb_server_share_unexport()
1140faa1795aSjb150015  *
11412c1b14e5Sjose borrego  * This function is invoked when a share is disabled to disconnect trees
11422c1b14e5Sjose borrego  * and close files.  Cleaning up may involve VOP and/or VFS calls, which
11432c1b14e5Sjose borrego  * may conflict/deadlock with stuck threads if something is amiss with the
11442c1b14e5Sjose borrego  * file system.  Queueing the request for asynchronous processing allows the
11452c1b14e5Sjose borrego  * call to return immediately so that, if the unshare is being done in the
11462c1b14e5Sjose borrego  * context of a forced unmount, the forced unmount will always be able to
11472c1b14e5Sjose borrego  * proceed (unblocking stuck I/O and eventually allowing all blocked unshare
11482c1b14e5Sjose borrego  * processes to complete).
1149faa1795aSjb150015  *
11502c1b14e5Sjose borrego  * The path lookup to find the root vnode of the VFS in question and the
11512c1b14e5Sjose borrego  * release of this vnode are done synchronously prior to any associated
11522c1b14e5Sjose borrego  * unmount.  Doing these asynchronous to an associated unmount could run
11532c1b14e5Sjose borrego  * the risk of a spurious EBUSY for a standard unmount or an EIO during
11542c1b14e5Sjose borrego  * the path lookup due to a forced unmount finishing first.
1155faa1795aSjb150015  */
1156faa1795aSjb150015 
1157faa1795aSjb150015 int
115829bd2886SAlan Wright smb_server_share_unexport(smb_ioc_share_t *ioc)
1159faa1795aSjb150015 {
1160faa1795aSjb150015 	smb_server_t	*sv;
11612c1b14e5Sjose borrego 	smb_request_t	*sr;
11622c1b14e5Sjose borrego 	smb_unexport_t	*ux;
1163faa1795aSjb150015 	smb_node_t	*fnode = NULL;
1164faa1795aSjb150015 	smb_node_t	*dnode;
1165faa1795aSjb150015 	char		last_comp[MAXNAMELEN];
11662c1b14e5Sjose borrego 	int		rc;
1167faa1795aSjb150015 
11682c1b14e5Sjose borrego 	if ((rc = smb_server_lookup(&sv)))
11692c1b14e5Sjose borrego 		return (rc);
1170faa1795aSjb150015 
117129bd2886SAlan Wright 	mutex_enter(&sv->sv_mutex);
117229bd2886SAlan Wright 	switch (sv->sv_state) {
117329bd2886SAlan Wright 	case SMB_SERVER_STATE_RUNNING:
11749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_SERVER_STATE_STOPPING:
117529bd2886SAlan Wright 		break;
117629bd2886SAlan Wright 	default:
117729bd2886SAlan Wright 		mutex_exit(&sv->sv_mutex);
117829bd2886SAlan Wright 		return (ENOTACTIVE);
117929bd2886SAlan Wright 	}
118029bd2886SAlan Wright 	mutex_exit(&sv->sv_mutex);
118129bd2886SAlan Wright 
1182faa1795aSjb150015 	sr = smb_request_alloc(sv->sv_session, 0);
11832c1b14e5Sjose borrego 
1184faa1795aSjb150015 	if (sr == NULL) {
1185faa1795aSjb150015 		smb_server_release(sv);
1186faa1795aSjb150015 		return (ENOMEM);
1187faa1795aSjb150015 	}
11882c1b14e5Sjose borrego 
1189faa1795aSjb150015 	sr->user_cr = kcred;
1190faa1795aSjb150015 
119129bd2886SAlan Wright 	rc = smb_pathname_reduce(sr, kcred, ioc->path, NULL, NULL,
119229bd2886SAlan Wright 	    &dnode, last_comp);
1193faa1795aSjb150015 
11942c1b14e5Sjose borrego 	if (rc) {
1195faa1795aSjb150015 		smb_request_free(sr);
1196faa1795aSjb150015 		smb_server_release(sv);
11972c1b14e5Sjose borrego 		return (rc);
1198faa1795aSjb150015 	}
1199faa1795aSjb150015 
12008b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	rc = smb_fsop_lookup(sr, kcred, SMB_FOLLOW_LINKS, sv->si_root_smb_node,
1201037cac00Sjoyce mcintosh 	    dnode, last_comp, &fnode);
1202faa1795aSjb150015 
1203faa1795aSjb150015 	smb_node_release(dnode);
1204faa1795aSjb150015 	smb_request_free(sr);
12052c1b14e5Sjose borrego 
12062c1b14e5Sjose borrego 	if (rc) {
1207faa1795aSjb150015 		smb_server_release(sv);
12082c1b14e5Sjose borrego 		return (rc);
1209faa1795aSjb150015 	}
1210faa1795aSjb150015 
1211faa1795aSjb150015 	ASSERT(fnode->vp && fnode->vp->v_vfsp);
1212faa1795aSjb150015 
1213faa1795aSjb150015 	smb_vfs_rele(sv, fnode->vp->v_vfsp);
12142c1b14e5Sjose borrego 
1215faa1795aSjb150015 	smb_node_release(fnode);
12162c1b14e5Sjose borrego 
12172c1b14e5Sjose borrego 	ux = kmem_cache_alloc(sv->si_cache_unexport, KM_SLEEP);
12182c1b14e5Sjose borrego 
121929bd2886SAlan Wright 	(void) strlcpy(ux->ux_sharename, ioc->name, MAXNAMELEN);
12202c1b14e5Sjose borrego 
12212c1b14e5Sjose borrego 	smb_slist_insert_tail(&sv->sv_unexport_list, ux);
12222c1b14e5Sjose borrego 	smb_thread_signal(&sv->si_thread_unexport);
12232c1b14e5Sjose borrego 
1224faa1795aSjb150015 	smb_server_release(sv);
1225faa1795aSjb150015 	return (0);
1226faa1795aSjb150015 }
1227faa1795aSjb150015 
1228faa1795aSjb150015 /*
12292c1b14e5Sjose borrego  * smb_server_thread_unexport
12302c1b14e5Sjose borrego  *
12312c1b14e5Sjose borrego  * This function processes the unexport event list and disconnects shares
12322c1b14e5Sjose borrego  * asynchronously.  The function executes as a zone-specific thread.
12332c1b14e5Sjose borrego  *
12342c1b14e5Sjose borrego  * The server arg passed in is safe to use without a reference count, because
12352c1b14e5Sjose borrego  * the server cannot be deleted until smb_thread_stop()/destroy() return,
12362c1b14e5Sjose borrego  * which is also when the thread exits.
12372c1b14e5Sjose borrego  */
12382c1b14e5Sjose borrego 
12392c1b14e5Sjose borrego static void
12402c1b14e5Sjose borrego smb_server_thread_unexport(smb_thread_t *thread, void *arg)
12412c1b14e5Sjose borrego {
12422c1b14e5Sjose borrego 	smb_server_t		*sv = (smb_server_t *)arg;
12432c1b14e5Sjose borrego 	smb_unexport_t		*ux;
12449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_session_list_t	*slist;
12452c1b14e5Sjose borrego 
12462c1b14e5Sjose borrego 	while (smb_thread_continue(thread)) {
12472c1b14e5Sjose borrego 		while ((ux = list_head(&sv->sv_unexport_list.sl_list))
12482c1b14e5Sjose borrego 		    != NULL) {
12492c1b14e5Sjose borrego 			smb_slist_remove(&sv->sv_unexport_list, ux);
12509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			slist = &sv->sv_nbt_daemon.ld_session_list;
12529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			smb_server_disconnect_share(slist, ux->ux_sharename);
12539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			slist = &sv->sv_tcp_daemon.ld_session_list;
12559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			smb_server_disconnect_share(slist, ux->ux_sharename);
12569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12572c1b14e5Sjose borrego 			kmem_cache_free(sv->si_cache_unexport, ux);
12582c1b14e5Sjose borrego 		}
12592c1b14e5Sjose borrego 	}
12602c1b14e5Sjose borrego }
12612c1b14e5Sjose borrego 
12622c1b14e5Sjose borrego /*
1263faa1795aSjb150015  * This is a special interface that will be utilized by ZFS to cause a share to
1264faa1795aSjb150015  * be added/removed.
1265faa1795aSjb150015  *
1266faa1795aSjb150015  * arg is either a lmshare_info_t or share_name from userspace.
1267faa1795aSjb150015  * It will need to be copied into the kernel.   It is lmshare_info_t
1268faa1795aSjb150015  * for add operations and share_name for delete operations.
1269faa1795aSjb150015  */
1270faa1795aSjb150015 int
1271faa1795aSjb150015 smb_server_share(void *arg, boolean_t add_share)
1272faa1795aSjb150015 {
1273faa1795aSjb150015 	smb_server_t	*sv;
1274faa1795aSjb150015 	int		rc;
1275faa1795aSjb150015 
1276faa1795aSjb150015 	rc = smb_server_lookup(&sv);
1277faa1795aSjb150015 	if (rc == 0) {
1278faa1795aSjb150015 		mutex_enter(&sv->sv_mutex);
127929bd2886SAlan Wright 		switch (sv->sv_state) {
128029bd2886SAlan Wright 		case SMB_SERVER_STATE_RUNNING:
1281faa1795aSjb150015 			mutex_exit(&sv->sv_mutex);
128229bd2886SAlan Wright 			(void) smb_kshare_upcall(sv->sv_lmshrd, arg, add_share);
128329bd2886SAlan Wright 			break;
128429bd2886SAlan Wright 		default:
1285faa1795aSjb150015 			mutex_exit(&sv->sv_mutex);
128629bd2886SAlan Wright 			break;
1287faa1795aSjb150015 		}
1288faa1795aSjb150015 		smb_server_release(sv);
1289faa1795aSjb150015 	}
129029bd2886SAlan Wright 	return (0);
1291faa1795aSjb150015 }
1292faa1795aSjb150015 
1293faa1795aSjb150015 /*
1294faa1795aSjb150015  * *****************************************************************************
1295faa1795aSjb150015  * **************** Functions called from the internal layers ******************
1296faa1795aSjb150015  * *****************************************************************************
1297faa1795aSjb150015  *
1298faa1795aSjb150015  * These functions are provided the relevant smb server by the caller.
1299faa1795aSjb150015  */
1300faa1795aSjb150015 
1301faa1795aSjb150015 void
1302faa1795aSjb150015 smb_server_reconnection_check(smb_server_t *sv, smb_session_t *session)
1303faa1795aSjb150015 {
1304faa1795aSjb150015 	ASSERT(sv == session->s_server);
1305faa1795aSjb150015 
1306faa1795aSjb150015 	smb_session_reconnection_check(&sv->sv_nbt_daemon.ld_session_list,
1307faa1795aSjb150015 	    session);
1308faa1795aSjb150015 	smb_session_reconnection_check(&sv->sv_tcp_daemon.ld_session_list,
1309faa1795aSjb150015 	    session);
1310faa1795aSjb150015 }
1311faa1795aSjb150015 
1312faa1795aSjb150015 void
1313faa1795aSjb150015 smb_server_get_cfg(smb_server_t *sv, smb_kmod_cfg_t *cfg)
1314faa1795aSjb150015 {
1315faa1795aSjb150015 	rw_enter(&sv->sv_cfg_lock, RW_READER);
1316faa1795aSjb150015 	bcopy(&sv->sv_cfg, cfg, sizeof (*cfg));
1317faa1795aSjb150015 	rw_exit(&sv->sv_cfg_lock);
1318faa1795aSjb150015 }
1319faa1795aSjb150015 
1320faa1795aSjb150015 /*
1321faa1795aSjb150015  * *****************************************************************************
1322faa1795aSjb150015  * *************************** Static Functions ********************************
1323faa1795aSjb150015  * *****************************************************************************
1324faa1795aSjb150015  */
1325faa1795aSjb150015 
1326faa1795aSjb150015 static void
1327faa1795aSjb150015 smb_server_timers(smb_thread_t *thread, void *arg)
1328faa1795aSjb150015 {
1329faa1795aSjb150015 	smb_server_t	*sv = (smb_server_t *)arg;
1330faa1795aSjb150015 
1331faa1795aSjb150015 	ASSERT(sv != NULL);
1332faa1795aSjb150015 
1333faa1795aSjb150015 	while (smb_thread_continue_timedwait(thread, 1 /* Seconds */)) {
1334faa1795aSjb150015 		smb_session_timers(&sv->sv_nbt_daemon.ld_session_list);
1335faa1795aSjb150015 		smb_session_timers(&sv->sv_tcp_daemon.ld_session_list);
1336faa1795aSjb150015 	}
1337faa1795aSjb150015 }
1338faa1795aSjb150015 
1339faa1795aSjb150015 /*
1340faa1795aSjb150015  * smb_server_kstat_init
1341faa1795aSjb150015  */
1342faa1795aSjb150015 static int
1343faa1795aSjb150015 smb_server_kstat_init(smb_server_t *sv)
1344faa1795aSjb150015 {
13456537f381Sas200622 	(void) snprintf(sv->sv_ksp_name, sizeof (sv->sv_ksp_name), "%s%d",
13466537f381Sas200622 	    SMBSRV_KSTAT_NAME, sv->sv_zid);
1347faa1795aSjb150015 
13486537f381Sas200622 	sv->sv_ksp = kstat_create(SMBSRV_KSTAT_MODULE, 0, sv->sv_ksp_name,
13496537f381Sas200622 	    SMBSRV_KSTAT_CLASS, KSTAT_TYPE_NAMED,
13506537f381Sas200622 	    sizeof (sv->sv_ks_data) / sizeof (kstat_named_t),
1351faa1795aSjb150015 	    KSTAT_FLAG_VIRTUAL);
1352faa1795aSjb150015 
1353faa1795aSjb150015 	if (sv->sv_ksp) {
1354faa1795aSjb150015 		(void) strlcpy(sv->sv_ks_data.open_files.name, "open_files",
1355faa1795aSjb150015 		    sizeof (sv->sv_ks_data.open_files.name));
1356faa1795aSjb150015 		sv->sv_ks_data.open_files.data_type = KSTAT_DATA_UINT32;
1357faa1795aSjb150015 		(void) strlcpy(sv->sv_ks_data.open_trees.name, "connections",
1358faa1795aSjb150015 		    sizeof (sv->sv_ks_data.open_trees.name));
1359faa1795aSjb150015 		sv->sv_ks_data.open_trees.data_type = KSTAT_DATA_UINT32;
1360faa1795aSjb150015 		(void) strlcpy(sv->sv_ks_data.open_users.name, "sessions",
1361faa1795aSjb150015 		    sizeof (sv->sv_ks_data.open_users.name));
1362faa1795aSjb150015 		sv->sv_ks_data.open_users.data_type = KSTAT_DATA_UINT32;
1363faa1795aSjb150015 
1364faa1795aSjb150015 		mutex_init(&sv->sv_ksp_mutex, NULL, MUTEX_DEFAULT, NULL);
1365faa1795aSjb150015 		sv->sv_ksp->ks_lock = &sv->sv_ksp_mutex;
1366faa1795aSjb150015 		sv->sv_ksp->ks_data = (void *)&sv->sv_ks_data;
1367faa1795aSjb150015 		sv->sv_ksp->ks_update = smb_server_kstat_update_info;
1368faa1795aSjb150015 		kstat_install(sv->sv_ksp);
1369faa1795aSjb150015 	}
1370faa1795aSjb150015 
1371faa1795aSjb150015 	/* create and initialize smb kstats - smb_dispatch stats */
1372faa1795aSjb150015 	smb_dispatch_kstat_init();
1373faa1795aSjb150015 
1374faa1795aSjb150015 	return (0);
1375faa1795aSjb150015 }
1376faa1795aSjb150015 
1377faa1795aSjb150015 /*
1378faa1795aSjb150015  * smb_server_kstat_fini
1379faa1795aSjb150015  */
1380faa1795aSjb150015 static void
1381faa1795aSjb150015 smb_server_kstat_fini(smb_server_t *sv)
1382faa1795aSjb150015 {
1383faa1795aSjb150015 	if (sv->sv_ksp) {
1384faa1795aSjb150015 		kstat_delete(sv->sv_ksp);
1385faa1795aSjb150015 		mutex_destroy(&sv->sv_ksp_mutex);
1386faa1795aSjb150015 		sv->sv_ksp = NULL;
1387faa1795aSjb150015 	}
1388faa1795aSjb150015 	smb_dispatch_kstat_fini();
1389faa1795aSjb150015 }
1390faa1795aSjb150015 
1391faa1795aSjb150015 /* ARGSUSED */
1392faa1795aSjb150015 static int
1393faa1795aSjb150015 smb_server_kstat_update_info(kstat_t *ksp, int rw)
1394faa1795aSjb150015 {
1395faa1795aSjb150015 	smb_server_t	*sv;
1396faa1795aSjb150015 
1397faa1795aSjb150015 	if (rw == KSTAT_WRITE) {
1398faa1795aSjb150015 		return (EACCES);
1399faa1795aSjb150015 	} else {
1400faa1795aSjb150015 		ASSERT(MUTEX_HELD(ksp->ks_lock));
1401faa1795aSjb150015 
1402faa1795aSjb150015 		_NOTE(LINTED("pointer cast may result in improper alignment"))
1403faa1795aSjb150015 		sv = (smb_server_t *)((uint8_t *)(ksp->ks_data) -
1404faa1795aSjb150015 		    offsetof(smb_server_t, sv_ks_data));
1405faa1795aSjb150015 
14069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		SMB_SERVER_VALID(sv);
1407faa1795aSjb150015 
1408faa1795aSjb150015 		sv->sv_ks_data.open_files.value.ui32 = sv->sv_open_files;
1409faa1795aSjb150015 		sv->sv_ks_data.open_trees.value.ui32 = sv->sv_open_trees;
1410faa1795aSjb150015 		sv->sv_ks_data.open_users.value.ui32 = sv->sv_open_users;
1411faa1795aSjb150015 	}
1412faa1795aSjb150015 	return (0);
1413faa1795aSjb150015 }
1414faa1795aSjb150015 
1415faa1795aSjb150015 /*
1416faa1795aSjb150015  * The mutex of the server must have been entered before calling this function.
1417faa1795aSjb150015  */
1418faa1795aSjb150015 static void
14199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_shutdown(smb_server_t *sv)
1420faa1795aSjb150015 {
14219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	SMB_SERVER_VALID(sv);
1422faa1795aSjb150015 
14233db3f65cSamw 	smb_opipe_door_close();
1424faa1795aSjb150015 	smb_thread_stop(&sv->si_thread_timers);
14252c1b14e5Sjose borrego 	smb_thread_stop(&sv->si_thread_unexport);
14269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_kdoor_close();
14273ad684d6Sjb150015 	smb_kshare_fini(sv->sv_lmshrd);
14280dcb3379Sjb150015 	sv->sv_lmshrd = NULL;
1429faa1795aSjb150015 	smb_server_fsop_stop(sv);
14308d96b23eSAlan Wright 
1431faa1795aSjb150015 	if (sv->sv_session) {
1432faa1795aSjb150015 		smb_session_delete(sv->sv_session);
1433faa1795aSjb150015 		sv->sv_session = NULL;
1434faa1795aSjb150015 	}
14358d96b23eSAlan Wright 
14368d96b23eSAlan Wright 	if (sv->sv_thread_pool) {
14378d96b23eSAlan Wright 		taskq_destroy(sv->sv_thread_pool);
14388d96b23eSAlan Wright 		sv->sv_thread_pool = NULL;
14398d96b23eSAlan Wright 	}
1440faa1795aSjb150015 }
1441faa1795aSjb150015 
1442faa1795aSjb150015 static int
1443faa1795aSjb150015 smb_server_listen(
1444faa1795aSjb150015     smb_server_t		*sv,
1445faa1795aSjb150015     smb_listener_daemon_t	*ld,
1446faa1795aSjb150015     in_port_t			port,
14477f667e74Sjose borrego     int				family,
1448faa1795aSjb150015     int				pthread_create_error)
1449faa1795aSjb150015 {
14509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int			rc = 0;
14510f1702c5SYu Xiangning 	ksocket_t		s_so;
14529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint32_t		on;
14539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint32_t		off;
14549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint32_t		txbuf_size;
1455faa1795aSjb150015 	smb_session_t		*session;
1456faa1795aSjb150015 
1457faa1795aSjb150015 	if (pthread_create_error) {
1458faa1795aSjb150015 		/*
1459faa1795aSjb150015 		 * Delete the last session created. The user space thread
1460faa1795aSjb150015 		 * creation failed.
1461faa1795aSjb150015 		 */
1462faa1795aSjb150015 		smb_session_list_delete_tail(&ld->ld_session_list);
1463faa1795aSjb150015 	}
1464faa1795aSjb150015 
1465faa1795aSjb150015 	if (ld->ld_so == NULL) {
1466faa1795aSjb150015 		/* First time listener */
14677f667e74Sjose borrego 		if (family == AF_INET) {
14687f667e74Sjose borrego 			ld->ld_sin.sin_family = (uint32_t)family;
1469faa1795aSjb150015 			ld->ld_sin.sin_port = htons(port);
1470faa1795aSjb150015 			ld->ld_sin.sin_addr.s_addr = htonl(INADDR_ANY);
14717f667e74Sjose borrego 		} else {
14727f667e74Sjose borrego 			ld->ld_sin6.sin6_family = (uint32_t)family;
14737f667e74Sjose borrego 			ld->ld_sin6.sin6_port = htons(port);
14747f667e74Sjose borrego 			(void) memset(&ld->ld_sin6.sin6_addr.s6_addr, 0,
14757f667e74Sjose borrego 			    sizeof (ld->ld_sin6.sin6_addr.s6_addr));
14767f667e74Sjose borrego 		}
1477faa1795aSjb150015 
14789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		ld->ld_so = smb_socreate(family, SOCK_STREAM, 0);
14799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (ld->ld_so == NULL) {
14809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			cmn_err(CE_WARN, "port %d: socket create failed", port);
14819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (ENOMEM);
14829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
14839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
14849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		off = 0;
14850f1702c5SYu Xiangning 		(void) ksocket_setsockopt(ld->ld_so, SOL_SOCKET,
1486fc724630SAlan Wright 		    SO_MAC_EXEMPT, &off, sizeof (off), CRED());
14879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
14889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		on = 1;
1489fc724630SAlan Wright 		(void) ksocket_setsockopt(ld->ld_so, SOL_SOCKET,
1490fc724630SAlan Wright 		    SO_REUSEADDR, &on, sizeof (on), CRED());
1491fc724630SAlan Wright 
14927f667e74Sjose borrego 		if (family == AF_INET) {
14930f1702c5SYu Xiangning 			rc = ksocket_bind(ld->ld_so,
14940f1702c5SYu Xiangning 			    (struct sockaddr *)&ld->ld_sin,
14950f1702c5SYu Xiangning 			    sizeof (ld->ld_sin), CRED());
14967f667e74Sjose borrego 		} else {
14977f667e74Sjose borrego 			rc = ksocket_bind(ld->ld_so,
14987f667e74Sjose borrego 			    (struct sockaddr *)&ld->ld_sin6,
14997f667e74Sjose borrego 			    sizeof (ld->ld_sin6), CRED());
15007f667e74Sjose borrego 		}
15019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (rc != 0) {
15039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			cmn_err(CE_WARN, "port %d: bind failed (%d)", port, rc);
15049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			smb_server_listen_fini(ld);
15059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (rc);
15069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
15079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15080f1702c5SYu Xiangning 		rc =  ksocket_listen(ld->ld_so, 20, CRED());
1509faa1795aSjb150015 		if (rc < 0) {
15109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			cmn_err(CE_WARN, "port %d: listen failed", port);
15119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			smb_server_listen_fini(ld);
1512faa1795aSjb150015 			return (rc);
1513faa1795aSjb150015 		}
1514faa1795aSjb150015 	}
1515faa1795aSjb150015 
1516faa1795aSjb150015 	DTRACE_PROBE1(so__wait__accept, struct sonode *, ld->ld_so);
1517faa1795aSjb150015 
1518faa1795aSjb150015 	for (;;) {
15199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (smb_server_is_stopping()) {
15209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			rc = ECANCELED;
15219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			break;
15229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
15239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15240f1702c5SYu Xiangning 		rc = ksocket_accept(ld->ld_so, NULL, NULL, &s_so, CRED());
15259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (rc != 0)
15269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			break;
15279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (smb_server_is_stopping()) {
15299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			smb_soshutdown(s_so);
15309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			smb_sodestroy(s_so);
15319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			rc = ECANCELED;
15329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			break;
15339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
1534faa1795aSjb150015 
1535faa1795aSjb150015 		DTRACE_PROBE1(so__accept, struct sonode *, s_so);
1536faa1795aSjb150015 
15379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		on = 1;
15389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) ksocket_setsockopt(s_so, IPPROTO_TCP, TCP_NODELAY,
15399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    &on, sizeof (on), CRED());
15409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		on = 1;
15429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) ksocket_setsockopt(s_so, SOL_SOCKET, SO_KEEPALIVE,
15439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    &on, sizeof (on), CRED());
15449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		txbuf_size = 128*1024;
15460f1702c5SYu Xiangning 		(void) ksocket_setsockopt(s_so, SOL_SOCKET, SO_SNDBUF,
15479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    (const void *)&txbuf_size, sizeof (txbuf_size), CRED());
15489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1549faa1795aSjb150015 		/*
1550faa1795aSjb150015 		 * Create a session for this connection.
1551faa1795aSjb150015 		 */
15527f667e74Sjose borrego 		session = smb_session_create(s_so, port, sv, family);
1553faa1795aSjb150015 		if (session) {
15549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			smb_session_list_append(&ld->ld_session_list, session);
15559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			rc = 0;
1556faa1795aSjb150015 			break;
1557faa1795aSjb150015 		} else {
1558faa1795aSjb150015 			smb_soshutdown(s_so);
1559faa1795aSjb150015 			smb_sodestroy(s_so);
1560faa1795aSjb150015 		}
1561faa1795aSjb150015 	}
15629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (rc != 0)
15649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_server_listen_fini(ld);
15659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (rc);
15679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
15689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void
15709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_listen_fini(smb_listener_daemon_t *ld)
15719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
15729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (ld->ld_so != NULL) {
1573faa1795aSjb150015 		smb_session_list_signal(&ld->ld_session_list);
1574faa1795aSjb150015 		smb_soshutdown(ld->ld_so);
1575faa1795aSjb150015 		smb_sodestroy(ld->ld_so);
1576faa1795aSjb150015 		ld->ld_so = NULL;
15779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
1578faa1795aSjb150015 }
1579faa1795aSjb150015 
15809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static kt_did_t
15819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_listener_tid(smb_listener_daemon_t *ld)
15829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
15839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	kt_did_t	tid;
15849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (ld->ld_ktdid != 0) {
15869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		tid = ld->ld_ktdid;
15879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		ld->ld_ktdid = 0;
15889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
15899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (tid);
1591faa1795aSjb150015 }
1592faa1795aSjb150015 
1593faa1795aSjb150015 /*
1594faa1795aSjb150015  * smb_server_lookup
1595faa1795aSjb150015  *
1596faa1795aSjb150015  * This function tries to find the server associated with the zone of the
1597faa1795aSjb150015  * caller.
1598faa1795aSjb150015  */
1599faa1795aSjb150015 static int
1600faa1795aSjb150015 smb_server_lookup(smb_server_t **psv)
1601faa1795aSjb150015 {
1602faa1795aSjb150015 	zoneid_t	zid;
1603faa1795aSjb150015 	smb_server_t	*sv;
1604faa1795aSjb150015 
1605faa1795aSjb150015 	zid = getzoneid();
1606faa1795aSjb150015 
1607faa1795aSjb150015 	smb_llist_enter(&smb_servers, RW_READER);
1608faa1795aSjb150015 	sv = smb_llist_head(&smb_servers);
1609faa1795aSjb150015 	while (sv) {
16109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		SMB_SERVER_VALID(sv);
1611faa1795aSjb150015 		if (sv->sv_zid == zid) {
1612faa1795aSjb150015 			mutex_enter(&sv->sv_mutex);
1613faa1795aSjb150015 			if (sv->sv_state != SMB_SERVER_STATE_DELETING) {
1614faa1795aSjb150015 				sv->sv_refcnt++;
1615faa1795aSjb150015 				mutex_exit(&sv->sv_mutex);
1616faa1795aSjb150015 				smb_llist_exit(&smb_servers);
1617faa1795aSjb150015 				*psv = sv;
1618faa1795aSjb150015 				return (0);
1619faa1795aSjb150015 			}
1620faa1795aSjb150015 			mutex_exit(&sv->sv_mutex);
1621faa1795aSjb150015 			break;
1622faa1795aSjb150015 		}
1623faa1795aSjb150015 		sv = smb_llist_next(&smb_servers, sv);
1624faa1795aSjb150015 	}
1625faa1795aSjb150015 	smb_llist_exit(&smb_servers);
1626faa1795aSjb150015 	return (EPERM);
1627faa1795aSjb150015 }
1628faa1795aSjb150015 
1629faa1795aSjb150015 /*
1630faa1795aSjb150015  * smb_server_release
1631faa1795aSjb150015  *
1632faa1795aSjb150015  * This function decrements the reference count of the server and signals its
1633faa1795aSjb150015  * condition variable if the state of the server is SMB_SERVER_STATE_DELETING.
1634faa1795aSjb150015  */
1635faa1795aSjb150015 static void
1636faa1795aSjb150015 smb_server_release(smb_server_t *sv)
1637faa1795aSjb150015 {
16389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	SMB_SERVER_VALID(sv);
1639faa1795aSjb150015 
1640faa1795aSjb150015 	mutex_enter(&sv->sv_mutex);
1641faa1795aSjb150015 	ASSERT(sv->sv_refcnt);
1642faa1795aSjb150015 	sv->sv_refcnt--;
1643faa1795aSjb150015 	if ((sv->sv_refcnt == 0) && (sv->sv_state == SMB_SERVER_STATE_DELETING))
1644faa1795aSjb150015 		cv_signal(&sv->sv_cv);
1645faa1795aSjb150015 	mutex_exit(&sv->sv_mutex);
1646faa1795aSjb150015 }
1647faa1795aSjb150015 
16481fcced4cSJordan Brown /*
16491fcced4cSJordan Brown  * Enumerate the users associated with a session list.
16501fcced4cSJordan Brown  */
16511fcced4cSJordan Brown static void
16521fcced4cSJordan Brown smb_server_enum_private(smb_session_list_t *se, smb_svcenum_t *svcenum)
1653faa1795aSjb150015 {
16541fcced4cSJordan Brown 	smb_session_t	*sn;
1655faa1795aSjb150015 	smb_llist_t	*ulist;
16561fcced4cSJordan Brown 	smb_user_t	*user;
165729bd2886SAlan Wright 	int		rc = 0;
1658faa1795aSjb150015 
1659faa1795aSjb150015 	rw_enter(&se->se_lock, RW_READER);
1660faa1795aSjb150015 	sn = list_head(&se->se_act.lst);
16611fcced4cSJordan Brown 
16621fcced4cSJordan Brown 	while (sn != NULL) {
1663faa1795aSjb150015 		ASSERT(sn->s_magic == SMB_SESSION_MAGIC);
1664faa1795aSjb150015 		ulist = &sn->s_user_list;
1665faa1795aSjb150015 		smb_llist_enter(ulist, RW_READER);
1666faa1795aSjb150015 		user = smb_llist_head(ulist);
16671fcced4cSJordan Brown 
16681fcced4cSJordan Brown 		while (user != NULL) {
16691fcced4cSJordan Brown 			if (smb_user_hold(user)) {
16701fcced4cSJordan Brown 				rc = smb_user_enum(user, svcenum);
16711fcced4cSJordan Brown 				smb_user_release(user);
1672faa1795aSjb150015 			}
16731fcced4cSJordan Brown 
1674faa1795aSjb150015 			user = smb_llist_next(ulist, user);
1675faa1795aSjb150015 		}
16761fcced4cSJordan Brown 
16771fcced4cSJordan Brown 		smb_llist_exit(ulist);
16781fcced4cSJordan Brown 
16791fcced4cSJordan Brown 		if (rc != 0)
16801fcced4cSJordan Brown 			break;
16811fcced4cSJordan Brown 
16821fcced4cSJordan Brown 		sn = list_next(&se->se_act.lst, sn);
16831fcced4cSJordan Brown 	}
16841fcced4cSJordan Brown 
16851fcced4cSJordan Brown 	rw_exit(&se->se_lock);
16861fcced4cSJordan Brown }
16871fcced4cSJordan Brown 
16881fcced4cSJordan Brown /*
16891fcced4cSJordan Brown  * Disconnect sessions associated with the specified client and username.
16901fcced4cSJordan Brown  * Empty strings are treated as wildcards.
16911fcced4cSJordan Brown  */
16921fcced4cSJordan Brown static int
16931fcced4cSJordan Brown smb_server_sesion_disconnect(smb_session_list_t *se,
16941fcced4cSJordan Brown     const char *client, const char *name)
16951fcced4cSJordan Brown {
16961fcced4cSJordan Brown 	smb_session_t	*sn;
16971fcced4cSJordan Brown 	smb_llist_t	*ulist;
16981fcced4cSJordan Brown 	smb_user_t	*user;
16991fcced4cSJordan Brown 	boolean_t	match;
17001fcced4cSJordan Brown 	int		count = 0;
17011fcced4cSJordan Brown 
17021fcced4cSJordan Brown 	rw_enter(&se->se_lock, RW_READER);
17031fcced4cSJordan Brown 	sn = list_head(&se->se_act.lst);
17041fcced4cSJordan Brown 
17051fcced4cSJordan Brown 	while (sn != NULL) {
17061fcced4cSJordan Brown 		ASSERT(sn->s_magic == SMB_SESSION_MAGIC);
17071fcced4cSJordan Brown 
17081fcced4cSJordan Brown 		if ((*client != '\0') && (!smb_session_isclient(sn, client))) {
17091fcced4cSJordan Brown 			sn = list_next(&se->se_act.lst, sn);
17101fcced4cSJordan Brown 			continue;
17111fcced4cSJordan Brown 		}
17121fcced4cSJordan Brown 
17131fcced4cSJordan Brown 		ulist = &sn->s_user_list;
17141fcced4cSJordan Brown 		smb_llist_enter(ulist, RW_READER);
17151fcced4cSJordan Brown 		user = smb_llist_head(ulist);
17161fcced4cSJordan Brown 
17171fcced4cSJordan Brown 		while (user != NULL) {
17181fcced4cSJordan Brown 			if (smb_user_hold(user)) {
17191fcced4cSJordan Brown 				match = (*name == '\0');
17201fcced4cSJordan Brown 				if (!match)
17211fcced4cSJordan Brown 					match = smb_user_namecmp(user, name);
17221fcced4cSJordan Brown 
17231fcced4cSJordan Brown 				if (match) {
17241fcced4cSJordan Brown 					smb_llist_exit(ulist);
17251fcced4cSJordan Brown 					smb_user_logoff(user);
17261fcced4cSJordan Brown 					++count;
17271fcced4cSJordan Brown 					smb_user_release(user);
17281fcced4cSJordan Brown 					smb_llist_enter(ulist, RW_READER);
17291fcced4cSJordan Brown 					user = smb_llist_head(ulist);
17301fcced4cSJordan Brown 					continue;
17311fcced4cSJordan Brown 				}
17321fcced4cSJordan Brown 
17331fcced4cSJordan Brown 				smb_user_release(user);
17341fcced4cSJordan Brown 			}
17351fcced4cSJordan Brown 
17361fcced4cSJordan Brown 			user = smb_llist_next(ulist, user);
17371fcced4cSJordan Brown 		}
17381fcced4cSJordan Brown 
1739faa1795aSjb150015 		smb_llist_exit(ulist);
1740b89a8333Snatalie li - Sun Microsystems - Irvine United States 		sn = list_next(&se->se_act.lst, sn);
1741faa1795aSjb150015 	}
17421fcced4cSJordan Brown 
1743faa1795aSjb150015 	rw_exit(&se->se_lock);
17441fcced4cSJordan Brown 	return (count);
17451fcced4cSJordan Brown }
17461fcced4cSJordan Brown 
17471fcced4cSJordan Brown /*
17481fcced4cSJordan Brown  * Close a file by its unique id.
17491fcced4cSJordan Brown  */
17501fcced4cSJordan Brown static int
17511fcced4cSJordan Brown smb_server_fclose(smb_session_list_t *se, uint32_t uniqid)
17521fcced4cSJordan Brown {
17531fcced4cSJordan Brown 	smb_session_t	*sn;
17541fcced4cSJordan Brown 	smb_llist_t	*ulist;
17551fcced4cSJordan Brown 	smb_user_t	*user;
17561fcced4cSJordan Brown 	int		rc = ENOENT;
17571fcced4cSJordan Brown 
17581fcced4cSJordan Brown 	rw_enter(&se->se_lock, RW_READER);
17591fcced4cSJordan Brown 	sn = list_head(&se->se_act.lst);
17601fcced4cSJordan Brown 
17611fcced4cSJordan Brown 	while ((sn != NULL) && (rc == ENOENT)) {
17621fcced4cSJordan Brown 		ASSERT(sn->s_magic == SMB_SESSION_MAGIC);
17631fcced4cSJordan Brown 		ulist = &sn->s_user_list;
17641fcced4cSJordan Brown 		smb_llist_enter(ulist, RW_READER);
17651fcced4cSJordan Brown 		user = smb_llist_head(ulist);
17661fcced4cSJordan Brown 
17671fcced4cSJordan Brown 		while ((user != NULL) && (rc == ENOENT)) {
17681fcced4cSJordan Brown 			if (smb_user_hold(user)) {
17691fcced4cSJordan Brown 				rc = smb_user_fclose(user, uniqid);
17701fcced4cSJordan Brown 				smb_user_release(user);
17711fcced4cSJordan Brown 			}
17721fcced4cSJordan Brown 
17731fcced4cSJordan Brown 			user = smb_llist_next(ulist, user);
17741fcced4cSJordan Brown 		}
17751fcced4cSJordan Brown 
17761fcced4cSJordan Brown 		smb_llist_exit(ulist);
17771fcced4cSJordan Brown 		sn = list_next(&se->se_act.lst, sn);
17781fcced4cSJordan Brown 	}
17791fcced4cSJordan Brown 
17801fcced4cSJordan Brown 	rw_exit(&se->se_lock);
17811fcced4cSJordan Brown 	return (rc);
1782faa1795aSjb150015 }
1783faa1795aSjb150015 
1784faa1795aSjb150015 static void
178529bd2886SAlan Wright smb_server_store_cfg(smb_server_t *sv, smb_ioc_cfg_t *ioc)
1786faa1795aSjb150015 {
178729bd2886SAlan Wright 	if (ioc->maxconnections == 0)
178829bd2886SAlan Wright 		ioc->maxconnections = 0xFFFFFFFF;
1789faa1795aSjb150015 
1790faa1795aSjb150015 	smb_session_correct_keep_alive_values(
179129bd2886SAlan Wright 	    &sv->sv_nbt_daemon.ld_session_list, ioc->keepalive);
1792faa1795aSjb150015 	smb_session_correct_keep_alive_values(
179329bd2886SAlan Wright 	    &sv->sv_tcp_daemon.ld_session_list, ioc->keepalive);
1794faa1795aSjb150015 
179529bd2886SAlan Wright 	sv->sv_cfg.skc_maxworkers = ioc->maxworkers;
179629bd2886SAlan Wright 	sv->sv_cfg.skc_maxconnections = ioc->maxconnections;
179729bd2886SAlan Wright 	sv->sv_cfg.skc_keepalive = ioc->keepalive;
179829bd2886SAlan Wright 	sv->sv_cfg.skc_restrict_anon = ioc->restrict_anon;
179929bd2886SAlan Wright 	sv->sv_cfg.skc_signing_enable = ioc->signing_enable;
180029bd2886SAlan Wright 	sv->sv_cfg.skc_signing_required = ioc->signing_required;
180129bd2886SAlan Wright 	sv->sv_cfg.skc_oplock_enable = ioc->oplock_enable;
180229bd2886SAlan Wright 	sv->sv_cfg.skc_sync_enable = ioc->sync_enable;
180329bd2886SAlan Wright 	sv->sv_cfg.skc_secmode = ioc->secmode;
180429bd2886SAlan Wright 	sv->sv_cfg.skc_ipv6_enable = ioc->ipv6_enable;
180529bd2886SAlan Wright 	(void) strlcpy(sv->sv_cfg.skc_nbdomain, ioc->nbdomain,
180629bd2886SAlan Wright 	    sizeof (sv->sv_cfg.skc_nbdomain));
180729bd2886SAlan Wright 	(void) strlcpy(sv->sv_cfg.skc_fqdn, ioc->fqdn,
180829bd2886SAlan Wright 	    sizeof (sv->sv_cfg.skc_fqdn));
180929bd2886SAlan Wright 	(void) strlcpy(sv->sv_cfg.skc_hostname, ioc->hostname,
181029bd2886SAlan Wright 	    sizeof (sv->sv_cfg.skc_hostname));
181129bd2886SAlan Wright 	(void) strlcpy(sv->sv_cfg.skc_system_comment, ioc->system_comment,
181229bd2886SAlan Wright 	    sizeof (sv->sv_cfg.skc_system_comment));
1813faa1795aSjb150015 }
1814faa1795aSjb150015 
1815faa1795aSjb150015 static int
1816faa1795aSjb150015 smb_server_fsop_start(smb_server_t *sv)
1817faa1795aSjb150015 {
1818faa1795aSjb150015 	int	error;
1819faa1795aSjb150015 
1820faa1795aSjb150015 	error = smb_node_root_init(rootdir, sv, &sv->si_root_smb_node);
1821faa1795aSjb150015 	if (error != 0)
1822faa1795aSjb150015 		sv->si_root_smb_node = NULL;
1823faa1795aSjb150015 
1824faa1795aSjb150015 	return (error);
1825faa1795aSjb150015 }
1826faa1795aSjb150015 
1827faa1795aSjb150015 static void
1828faa1795aSjb150015 smb_server_fsop_stop(smb_server_t *sv)
1829faa1795aSjb150015 {
1830faa1795aSjb150015 	if (sv->si_root_smb_node != NULL) {
1831faa1795aSjb150015 		smb_vfs_rele_all(sv);
1832faa1795aSjb150015 		smb_node_release(sv->si_root_smb_node);
1833faa1795aSjb150015 		sv->si_root_smb_node = NULL;
1834faa1795aSjb150015 	}
1835faa1795aSjb150015 }
18369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
18379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void
18389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_signal_listeners(smb_server_t *sv)
18399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
18409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	SMB_SERVER_VALID(sv);
18419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(sv->sv_state == SMB_SERVER_STATE_STOPPING);
18429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(MUTEX_HELD(&sv->sv_mutex));
18439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
18449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_event_cancel(sv, 0);
18459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
18469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (sv->sv_nbt_daemon.ld_kth != NULL) {
18479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		tsignal(sv->sv_nbt_daemon.ld_kth, SIGINT);
18489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sv->sv_nbt_daemon.ld_kth = NULL;
18499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
18509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
18519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (sv->sv_tcp_daemon.ld_kth != NULL) {
18529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		tsignal(sv->sv_tcp_daemon.ld_kth, SIGINT);
18539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		sv->sv_tcp_daemon.ld_kth = NULL;
18549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
18559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
18569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
18579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_t *
18589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_create(void)
18599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
18609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_server_t	*sv;
18619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_event_t	*event;
18629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
18639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_server_is_stopping())
18649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (NULL);
18659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
18669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_server_lookup(&sv) != 0) {
18679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		cmn_err(CE_NOTE, "smb_event_create failed");
18689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (NULL);
18699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
18709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
18719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	event = kmem_cache_alloc(sv->si_cache_event, KM_SLEEP);
18729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
18739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	bzero(event, sizeof (smb_event_t));
18749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_init(&event->se_mutex, NULL, MUTEX_DEFAULT, NULL);
18759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	cv_init(&event->se_cv, NULL, CV_DEFAULT, NULL);
18769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	event->se_magic = SMB_EVENT_MAGIC;
18779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	event->se_txid = smb_event_alloc_txid();
18789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	event->se_server = sv;
18799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
18809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_llist_enter(&sv->sv_event_list, RW_WRITER);
18819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_llist_insert_tail(&sv->sv_event_list, event);
18829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_llist_exit(&sv->sv_event_list);
18839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
18849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_server_release(sv);
18859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (event);
18869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
18879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
18889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
18899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_destroy(smb_event_t *event)
18909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
18919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_server_t	*sv;
18929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
18939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (event == NULL)
18949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return;
18959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
18969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	SMB_EVENT_VALID(event);
18979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ASSERT(event->se_waittime == 0);
18989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
18999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_server_lookup(&sv) != 0)
19009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return;
19019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
19029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_llist_enter(&sv->sv_event_list, RW_WRITER);
19039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_llist_remove(&sv->sv_event_list, event);
19049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_llist_exit(&sv->sv_event_list);
19059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
19069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	event->se_magic = (uint32_t)~SMB_EVENT_MAGIC;
19079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	cv_destroy(&event->se_cv);
19089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_destroy(&event->se_mutex);
19099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
19109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	kmem_cache_free(sv->si_cache_event, event);
19119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_server_release(sv);
19129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
19139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
19149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
19159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Get the txid for the specified event.
19169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
19179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States uint32_t
19189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_txid(smb_event_t *event)
19199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
19209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (event != NULL) {
19219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		SMB_EVENT_VALID(event);
19229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (event->se_txid);
19239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
19249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
19259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	cmn_err(CE_NOTE, "smb_event_txid failed");
19269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return ((uint32_t)-1);
19279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
19289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
19299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
19309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Wait for event notification.
19319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
19329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int
19339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_wait(smb_event_t *event)
19349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
19359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int	seconds = 1;
19369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int	ticks;
19379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
19389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (event == NULL)
19399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (EINVAL);
19409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
19419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	SMB_EVENT_VALID(event);
19429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
19439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&event->se_mutex);
19449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	event->se_waittime = 1;
19459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	event->se_errno = 0;
19469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
19479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	while (!(event->se_notified)) {
1948*c5866007SKeyur Desai 		if (smb_event_debug && ((event->se_waittime % 30) == 0))
19499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			cmn_err(CE_NOTE, "smb_event_wait[%d] (%d sec)",
19509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			    event->se_txid, event->se_waittime);
19519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
19529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (event->se_errno != 0)
19539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			break;
19549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
19559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (event->se_waittime > SMB_EVENT_TIMEOUT) {
19569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			event->se_errno = ETIME;
19579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			break;
19589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
19599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
19609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		ticks = SEC_TO_TICK(seconds);
19619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) cv_reltimedwait(&event->se_cv,
19629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    &event->se_mutex, (clock_t)ticks, TR_CLOCK_TICK);
19639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		++event->se_waittime;
19649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
19659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
19669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	event->se_waittime = 0;
19679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	event->se_notified = B_FALSE;
19689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	cv_signal(&event->se_cv);
19699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&event->se_mutex);
19709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (event->se_errno);
19719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
19729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
19739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
19749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * If txid is non-zero, cancel the specified event.
19759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Otherwise, cancel all events.
19769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
19779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void
19789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_cancel(smb_server_t *sv, uint32_t txid)
19799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
19809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_event_t	*event;
19819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_llist_t	*event_list;
19829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
19839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	SMB_SERVER_VALID(sv);
19849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
19859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	event_list = &sv->sv_event_list;
19869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_llist_enter(event_list, RW_WRITER);
19879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
19889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	event = smb_llist_head(event_list);
19899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	while (event) {
19909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		SMB_EVENT_VALID(event);
19919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
19929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (txid == 0 || event->se_txid == txid) {
19939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			mutex_enter(&event->se_mutex);
19949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			event->se_errno = ECANCELED;
19959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			event->se_notified = B_TRUE;
19969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			cv_signal(&event->se_cv);
19979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			mutex_exit(&event->se_mutex);
19989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
19999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			if (txid != 0)
20009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				break;
20019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
20029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
20039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		event = smb_llist_next(event_list, event);
20049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
20059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
20069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_llist_exit(event_list);
20079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
20089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
20099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
20109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * If txid is non-zero, notify the specified event.
20119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Otherwise, notify all events.
20129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
20139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void
20149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_notify(smb_server_t *sv, uint32_t txid)
20159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
20169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_event_t	*event;
20179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_llist_t	*event_list;
20189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
20199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	SMB_SERVER_VALID(sv);
20209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
20219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	event_list = &sv->sv_event_list;
20229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_llist_enter(event_list, RW_READER);
20239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
20249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	event = smb_llist_head(event_list);
20259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	while (event) {
20269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		SMB_EVENT_VALID(event);
20279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
20289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (txid == 0 || event->se_txid == txid) {
20299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			mutex_enter(&event->se_mutex);
20309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			event->se_notified = B_TRUE;
20319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			cv_signal(&event->se_cv);
20329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			mutex_exit(&event->se_mutex);
20339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
20349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			if (txid != 0)
20359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				break;
20369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
20379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
20389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		event = smb_llist_next(event_list, event);
20399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
20409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
20419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_llist_exit(event_list);
20429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
20439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
20449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
20459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Allocate a new transaction id (txid).
20469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
20479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * 0 or -1 are not assigned because they are used to detect invalid
20489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * conditions or to indicate all open id's.
20499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
20509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static uint32_t
20519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_alloc_txid(void)
20529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
20539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	static kmutex_t	txmutex;
20549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	static uint32_t	txid;
20559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint32_t	txid_ret;
20569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
20579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_enter(&txmutex);
20589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
20599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (txid == 0)
20609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		txid = ddi_get_lbolt() << 11;
20619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
20629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	do {
20639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		++txid;
20649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	} while (txid == 0 || txid == (uint32_t)-1);
20659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
20669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	txid_ret = txid;
20679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_exit(&txmutex);
20689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
20699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (txid_ret);
20709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
2071