Print this page
    
NEX-17669 SMB shares missing after CA share import
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
NEX-16519 Panic while running IOmeter to a pool through an SMB share
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
NEX-17095 illumos 8935 SMB ioctl fixes incomplete
8935 SMB ioctl fixes incomplete
Reviewed by: Alex Wilson <alex.wilson@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Rui Loura <rui.loura@joyent.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Dominik Hassler <hasslerd@gmx.li>
Approved by: Garrett D'Amore <garrett@damore.org>
NEX-9808 SMB3 persistent handles
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-15578 SMB2 durable handle redesign
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-15581 SMB keep-alive feature is just noise
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-5665 SMB2 oplock leases
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-9808 SMB3 persistent handles
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-15578 SMB2 durable handle redesign
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-15581 SMB keep-alive feature is just noise
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-5665 SMB2 oplock leases
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-10019 SMB server min_protocol setting
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-5273 SMB 3 Encryption
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-6096 Enable compile warnings re. parentheses in smbsrv
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Jean McCormack <jean.mccormack@nexenta.com>
NEX-6041 Should pass the smbtorture lock tests
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
NEX-4541 SMB server listener stops after a SYN-ACK flood (fksmbd noise)
NEX-4541 SMB server listener stops after a SYN-ACK flood (lint fix)
NEX-5983 remove post-merge cruft in usr/src/uts/intel/io/vmxnet3s
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
NEX-4541 SMB server listener stops after a SYN-ACK flood
Reviewed by: Gordon Ross <gwr@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
NEX-3553 SMB2/3 durable handles
Reviewed by: Gordon Ross <gwr@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
NEX-3776 SMB should handle PreviousSessionID
Reviewed by: Gordon Ross <gwr@nexenta.com>
NEX-5537 Want reference counts for users, trees...
Reviewed by: Gordon Ross <gwr@nexenta.com>
NEX-5330 SMB server should combine TCP+NBT session lists
Reviewed by: Gordon Ross <gwr@nexenta.com>
NEX-4811 SMB needs to export a header for kstats
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Jeffry Molanus <jeffry.molanus@nexenta.com>
NEX-2522 svcadm disable network/smb/server may hang
Reviewed by: Matt Barden <Matt.Barden@nexenta.com>
NEX-4083 Upstream changes from illumos 5917 and 5995
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-3738 Should support SMB2_CAP_LARGE_MTU
Reviewed by: Alek Pinchuk <alek@nexenta.com>
Reviewed by: Bayard Bell <bayard.bell@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Matt Barden <Matt.Barden@nexenta.com>
NEX-3620 need upstream cleanups for smbsrv
Reviewed by: Hans Rosenfeld <hans.rosenfeld@nexenta.com>
NEX-3611 CLONE NEX-3550 Replace smb2_enable with max_protocol
Reviewed by: Yuri Pankov <Yuri.Pankov@nexenta.com>
NEX-2485 SMB authentication flood handled poorly
SUP-866 smbd lwps stuck in libsocket recv() for no apparent reason
NEX-1050 enable_smb2 should be smb2_enable
SMB-11 SMB2 message parse & dispatch
SMB-12 SMB2 Negotiate Protocol
SMB-13 SMB2 Session Setup
SMB-14 SMB2 Logoff
SMB-15 SMB2 Tree Connect
SMB-16 SMB2 Tree Disconnect
SMB-17 SMB2 Create
SMB-18 SMB2 Close
SMB-19 SMB2 Flush
SMB-20 SMB2 Read
SMB-21 SMB2 Write
SMB-22 SMB2 Lock/Unlock
SMB-23 SMB2 Ioctl
SMB-24 SMB2 Cancel
SMB-25 SMB2 Echo
SMB-26 SMB2 Query Dir
SMB-27 SMB2 Change Notify
SMB-28 SMB2 Query Info
SMB-29 SMB2 Set Info
SMB-30 SMB2 Oplocks
SMB-53 SMB2 Create Context options
(SMB2 code review cleanup 1, 2, 3)
SMB-39 Use AF_UNIX pipes for RPC (fix a leak)
SMB-75 smb_session_timers way too frequent
SMB-74 Process oplock breaks as session requests
SMB-69 read-raw, write-raw are dead code
SMB-50 User-mode SMB server (oops)
SMB-56 extended security NTLMSSP, inbound
SMB-39 Use AF_UNIX pipes for RPC
SMB-50 User-mode SMB server
 Includes work by these authors:
 Thomas Keiser <thomas.keiser@nexenta.com>
 Albert Lee <trisk@nexenta.com>
SMB-65 SMB server in non-global zones (use zone_kcred())
SUP-694 panic on bad mutex in smb_event_wait()
SMB-65 SMB server in non-global zones (data structure changes)
Many things move to the smb_server_t object, and
many functions gain an sv arg (which server).
SMB-65 SMB server in non-global zones (kmem_caches)
common kmem_cache instances across zones
separate GZ-only init from NGZ init
SMB-64 smbsrv workers run at excessively high priority
SMB-63 taskq_create_proc ... TQ_DYNAMIC puts tasks in p0
re #11974 CIFS Share - Tree connect fails from Windows 7 Clients
re #11215 rb3676 sesctl to SGI JBOD hangs in biowait() with a command stuck in mptsas driver
re #10734 NT Trans. Notify returning too quickly
re #9812 rb3153 System panic'd with assertion failed: sl->sl_count == 0 in smb_slist_destructor after hostname change, smbd restart and attempts to rejoin active directory domain
re #6813 rb1757 port 2976 Child folder visibility through shares
re #6812 rb1753 backport illumos 1604 smbd print_enable doesn't really work
re #6811 rb1752 backport illumos 1603 smbsrv raw mode is ill-advised
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/fs/smbsrv/smb_server.c
          +++ new/usr/src/uts/common/fs/smbsrv/smb_server.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  
    | 
      ↓ open down ↓ | 
    12 lines elided | 
    
      ↑ open up ↑ | 
  
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  23      - * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  24   23   * Copyright (c) 2017 by Delphix. All rights reserved.
       24 + * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  25   25   */
  26   26  
  27   27  /*
  28   28   * General Structures Layout
  29   29   * -------------------------
  30   30   *
  31   31   * This is a simplified diagram showing the relationship between most of the
  32   32   * main structures.
  33   33   *
  34   34   * +-------------------+
  35   35   * |     SMB_SERVER    |
  36   36   * +-------------------+
  37   37   *          |
  38   38   *          |
  39   39   *          v
  40   40   * +-------------------+       +-------------------+      +-------------------+
  41   41   * |     SESSION       |<----->|     SESSION       |......|      SESSION      |
  42   42   * +-------------------+       +-------------------+      +-------------------+
  43   43   *          |
  44   44   *          |
  45   45   *          v
  46   46   * +-------------------+       +-------------------+      +-------------------+
  47   47   * |       USER        |<----->|       USER        |......|       USER        |
  48   48   * +-------------------+       +-------------------+      +-------------------+
  49   49   *          |
  50   50   *          |
  51   51   *          v
  52   52   * +-------------------+       +-------------------+      +-------------------+
  53   53   * |       TREE        |<----->|       TREE        |......|       TREE        |
  54   54   * +-------------------+       +-------------------+      +-------------------+
  55   55   *      |         |
  56   56   *      |         |
  57   57   *      |         v
  58   58   *      |     +-------+       +-------+      +-------+
  59   59   *      |     | OFILE |<----->| OFILE |......| OFILE |
  60   60   *      |     +-------+       +-------+      +-------+
  61   61   *      |
  62   62   *      |
  63   63   *      v
  64   64   *  +-------+       +------+      +------+
  65   65   *  | ODIR  |<----->| ODIR |......| ODIR |
  66   66   *  +-------+       +------+      +------+
  67   67   *
  68   68   *
  69   69   * Module Interface Overview
  70   70   * -------------------------
  71   71   *
  72   72   *
  73   73   *          +===================================+
  74   74   *          |            smbd daemon            |
  75   75   *          +===================================+
  76   76   *            |              |                ^
  77   77   *            |              |                |
  78   78   * User       |              |                |
  79   79   * -----------|--------------|----------------|--------------------------------
  80   80   * Kernel     |              |                |
  81   81   *            |              |                |
  82   82   *            |              |                |
  83   83   *  +=========|==============|================|=================+
  84   84   *  |         v              v                |                 |
  85   85   *  | +-----------+ +--------------------+ +------------------+ |
  86   86   *  | |     IO    | | Kernel Door Server | | User Door Servers| |
  87   87   *  | | Interface | |     Interface      | |   Interface      | |
  88   88   *  | +-----------+ +--------------------+ +------------------+ |
  89   89   *  |           |            |                ^         ^       |
  90   90   *  |           v            v                |         |       |    +=========+
  91   91   *  |        +-----------------------------------+      |       |    |         |
  92   92   *  |        + SMB Server Management (this file) |<------------------|   ZFS   |
  93   93   *  |        +-----------------------------------+      |       |    |         |
  94   94   *  |                                                   |       |    |  Module |
  95   95   *  |        +-----------------------------------+      |       |    |         |
  96   96   *  |        +     SMB Server Internal Layers    |------+       |    +=========+
  97   97   *  |        +-----------------------------------+              |
  98   98   *  |                                                           |
  99   99   *  |                                                           |
 100  100   *  +===========================================================+
 101  101   *
 102  102   *
 103  103   * Server State Machine
 104  104   * --------------------
 105  105   *                                  |
 106  106   *                                  | T0
 107  107   *                                  |
 108  108   *                                  v
 109  109   *                    +-----------------------------+
 110  110   *                    |   SMB_SERVER_STATE_CREATED  |
 111  111   *                    +-----------------------------+
 112  112   *                                  |
 113  113   *                                  | T1
 114  114   *                                  |
 115  115   *                                  v
 116  116   *                    +-----------------------------+
 117  117   *                    | SMB_SERVER_STATE_CONFIGURED |
 118  118   *                    +-----------------------------+
 119  119   *                                  |
 120  120   *                                  | T2
 121  121   *                                  |
 122  122   *                                  v
 123  123   *                    +-----------------------------+
 124  124   *                    |  SMB_SERVER_STATE_RUNNING / |
 125  125   *                    |  SMB_SERVER_STATE_STOPPING  |
 126  126   *                    +-----------------------------+
 127  127   *                                  |
 128  128   *                                  | T3
 129  129   *                                  |
 130  130   *                                  v
 131  131   *                    +-----------------------------+
 132  132   *                    |  SMB_SERVER_STATE_DELETING  |
 133  133   *                    +-----------------------------+
 134  134   *                                  |
 135  135   *                                  |
 136  136   *                                  |
 137  137   *                                  v
 138  138   *
 139  139   * States
 140  140   * ------
 141  141   *
 142  142   * SMB_SERVER_STATE_CREATED
 143  143   *
 144  144   *    This is the state of the server just after creation.
 145  145   *
 146  146   * SMB_SERVER_STATE_CONFIGURED
 147  147   *
 148  148   *    The server has been configured.
 149  149   *
 150  150   * SMB_SERVER_STATE_RUNNING
 151  151   *
 152  152   *    The server has been started. While in this state the threads listening on
 153  153   *    the sockets are started.
 154  154   *
 155  155   *    When a client establishes a connection the thread listening dispatches
 156  156   *    a task with the new session as an argument. If the dispatch fails the new
 157  157   *    session context is destroyed.
 158  158   *
 159  159   * SMB_SERVER_STATE_STOPPING
 160  160   *
 161  161   *    The threads listening on the NBT and TCP sockets are being terminated.
 162  162   *
 163  163   *
 164  164   * Transitions
 165  165   * -----------
 166  166   *
 167  167   * Transition T0
 168  168   *
 169  169   *    The daemon smbd triggers its creation by opening the smbsrv device. If
 170  170   *    the zone where the daemon lives doesn't have an smb server yet it is
 171  171   *    created.
 172  172   *
 173  173   *              smb_drv_open() --> smb_server_create()
 174  174   *
 175  175   * Transition T1
 176  176   *
 177  177   *    This transition occurs in smb_server_configure(). It is triggered by the
 178  178   *    daemon through an Ioctl.
 179  179   *
 180  180   *      smb_drv_ioctl(SMB_IOC_CONFIG) --> smb_server_configure()
 181  181   *
 182  182   * Transition T2
 183  183   *
 184  184   *    This transition occurs in smb_server_start(). It is triggered by the
 185  185   *    daemon through an Ioctl.
 186  186   *
 187  187   *      smb_drv_ioctl(SMB_IOC_START) --> smb_server_start()
 188  188   *
 189  189   * Transition T3
 190  190   *
 191  191   *    This transition occurs in smb_server_delete(). It is triggered by the
 192  192   *    daemon when closing the smbsrv device
 193  193   *
 194  194   *              smb_drv_close() --> smb_server_delete()
 195  195   *
 196  196   * Comments
 197  197   * --------
 198  198   *
 199  199   * This files assumes that there will one SMB server per zone. For now the
 200  200   * smb server works only in global zone. There's nothing in this file preventing
 201  201   * an smb server from being created in a non global zone. That limitation is
 202  202   * enforced in user space.
 203  203   */
 204  204  
 205  205  #include <sys/cmn_err.h>
 206  206  #include <sys/priv.h>
 207  207  #include <sys/zone.h>
 208  208  #include <netinet/in.h>
 209  209  #include <netinet/in_systm.h>
 210  210  #include <netinet/ip.h>
 211  211  #include <netinet/ip_icmp.h>
  
    | 
      ↓ open down ↓ | 
    177 lines elided | 
    
      ↑ open up ↑ | 
  
 212  212  #include <netinet/ip_var.h>
 213  213  #include <netinet/tcp.h>
 214  214  #include <smbsrv/smb2_kproto.h>
 215  215  #include <smbsrv/string.h>
 216  216  #include <smbsrv/netbios.h>
 217  217  #include <smbsrv/smb_fsops.h>
 218  218  #include <smbsrv/smb_share.h>
 219  219  #include <smbsrv/smb_door.h>
 220  220  #include <smbsrv/smb_kstat.h>
 221  221  
 222      -extern void smb_reply_notify_change_request(smb_request_t *);
 223      -
 224      -typedef struct {
 225      -        smb_listener_daemon_t   *ra_listener;
 226      -        smb_session_t           *ra_session;
 227      -} smb_receiver_arg_t;
 228      -
 229  222  static void smb_server_kstat_init(smb_server_t *);
 230  223  static void smb_server_kstat_fini(smb_server_t *);
 231  224  static void smb_server_timers(smb_thread_t *, void *);
 232  225  static void smb_server_store_cfg(smb_server_t *, smb_ioc_cfg_t *);
 233  226  static void smb_server_shutdown(smb_server_t *);
 234  227  static int smb_server_fsop_start(smb_server_t *);
 235  228  static void smb_server_fsop_stop(smb_server_t *);
 236  229  static void smb_event_cancel(smb_server_t *, uint32_t);
 237  230  static uint32_t smb_event_alloc_txid(void);
 238  231  
 239      -static void smb_server_disconnect_share(smb_llist_t *, const char *);
 240      -static void smb_server_enum_users(smb_llist_t *, smb_svcenum_t *);
 241      -static void smb_server_enum_trees(smb_llist_t *, smb_svcenum_t *);
 242      -static int smb_server_session_disconnect(smb_llist_t *, const char *,
      232 +static void smb_server_disconnect_share(smb_server_t *, const char *);
      233 +static void smb_server_enum_users(smb_server_t *, smb_svcenum_t *);
      234 +static void smb_server_enum_trees(smb_server_t *, smb_svcenum_t *);
      235 +static int smb_server_session_disconnect(smb_server_t *, const char *,
 243  236      const char *);
 244      -static int smb_server_fclose(smb_llist_t *, uint32_t);
      237 +static int smb_server_fclose(smb_server_t *, uint32_t);
 245  238  static int smb_server_kstat_update(kstat_t *, int);
 246  239  static int smb_server_legacy_kstat_update(kstat_t *, int);
 247  240  static void smb_server_listener_init(smb_server_t *, smb_listener_daemon_t *,
 248  241      char *, in_port_t, int);
 249  242  static void smb_server_listener_destroy(smb_listener_daemon_t *);
 250  243  static int smb_server_listener_start(smb_listener_daemon_t *);
 251  244  static void smb_server_listener_stop(smb_listener_daemon_t *);
 252  245  static void smb_server_listener(smb_thread_t *, void *);
 253  246  static void smb_server_receiver(void *);
 254  247  static void smb_server_create_session(smb_listener_daemon_t *, ksocket_t);
 255      -static void smb_server_destroy_session(smb_listener_daemon_t *,
 256      -    smb_session_t *);
      248 +static void smb_server_destroy_session(smb_session_t *);
 257  249  static uint16_t smb_spool_get_fid(smb_server_t *);
 258  250  static boolean_t smb_spool_lookup_doc_byfid(smb_server_t *, uint16_t,
 259  251      smb_kspooldoc_t *);
 260  252  
      253 +/*
      254 + * How many "buckets" should our hash tables use?  On a "real" server,
      255 + * make them much larger than the number of CPUs we're likely to have.
      256 + * On "fksmbd" make it smaller so dtrace logs are shorter.
      257 + * These must be powers of two.
      258 + */
      259 +#ifdef  _KERNEL
      260 +#define DEFAULT_HASH_NBUCKETS   256     /* real server */
      261 +#else
      262 +#define DEFAULT_HASH_NBUCKETS   16      /* for "fksmbd" */
      263 +#endif
      264 +uint32_t SMB_OFILE_HASH_NBUCKETS = DEFAULT_HASH_NBUCKETS;
      265 +uint32_t SMB_LEASE_HASH_NBUCKETS = DEFAULT_HASH_NBUCKETS;
      266 +
 261  267  int smb_event_debug = 0;
 262  268  
 263  269  static smb_llist_t      smb_servers;
 264  270  
 265  271  kmem_cache_t            *smb_cache_request;
 266  272  kmem_cache_t            *smb_cache_session;
 267  273  kmem_cache_t            *smb_cache_user;
 268  274  kmem_cache_t            *smb_cache_tree;
 269  275  kmem_cache_t            *smb_cache_ofile;
 270  276  kmem_cache_t            *smb_cache_odir;
 271  277  kmem_cache_t            *smb_cache_opipe;
 272  278  kmem_cache_t            *smb_cache_event;
      279 +kmem_cache_t            *smb_cache_lock;
 273  280  
 274  281  /*
 275  282   * *****************************************************************************
 276  283   * **************** Functions called from the device interface *****************
 277  284   * *****************************************************************************
 278  285   *
 279  286   * These functions typically have to determine the relevant smb server
 280  287   * to which the call applies.
 281  288   */
 282  289  
 283  290  /*
 284  291   * How many zones have an SMB server active?
 285  292   */
 286  293  int
 287  294  smb_server_get_count(void)
 288  295  {
 289  296          return (smb_llist_get_count(&smb_servers));
 290  297  }
 291  298  
 292  299  /*
 293  300   * smb_server_g_init
 294  301   *
 295  302   * This function must be called from smb_drv_attach().
 296  303   */
 297  304  int
 298  305  smb_server_g_init(void)
 299  306  {
 300  307          int rc;
  
    | 
      ↓ open down ↓ | 
    18 lines elided | 
    
      ↑ open up ↑ | 
  
 301  308  
 302  309          if ((rc = smb_vop_init()) != 0)
 303  310                  goto errout;
 304  311          if ((rc = smb_fem_init()) != 0)
 305  312                  goto errout;
 306  313  
 307  314          smb_kshare_g_init();
 308  315          smb_codepage_init();
 309  316          smb_mbc_init();         /* smb_mbc_cache */
 310  317          smb_node_init();        /* smb_node_cache, lists */
      318 +        smb2_lease_init();
 311  319  
 312  320          smb_cache_request = kmem_cache_create("smb_request_cache",
 313  321              sizeof (smb_request_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 314  322          smb_cache_session = kmem_cache_create("smb_session_cache",
 315  323              sizeof (smb_session_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 316  324          smb_cache_user = kmem_cache_create("smb_user_cache",
 317  325              sizeof (smb_user_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 318  326          smb_cache_tree = kmem_cache_create("smb_tree_cache",
 319  327              sizeof (smb_tree_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 320  328          smb_cache_ofile = kmem_cache_create("smb_ofile_cache",
 321  329              sizeof (smb_ofile_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 322  330          smb_cache_odir = kmem_cache_create("smb_odir_cache",
 323  331              sizeof (smb_odir_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 324  332          smb_cache_opipe = kmem_cache_create("smb_opipe_cache",
 325  333              sizeof (smb_opipe_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 326  334          smb_cache_event = kmem_cache_create("smb_event_cache",
 327  335              sizeof (smb_event_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
      336 +        smb_cache_lock = kmem_cache_create("smb_lock_cache",
      337 +            sizeof (smb_lock_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 328  338  
 329  339          smb_llist_init();
 330  340          smb_llist_constructor(&smb_servers, sizeof (smb_server_t),
 331  341              offsetof(smb_server_t, sv_lnd));
 332  342  
 333  343          return (0);
 334  344  
 335  345  errout:
 336  346          smb_fem_fini();
 337  347          smb_vop_fini();
 338  348          return (rc);
 339  349  }
 340  350  
 341  351  /*
 342  352   * smb_server_g_fini
 343  353   *
 344  354   * This function must called from smb_drv_detach(). It will fail if servers
 345  355   * still exist.
 346  356   */
 347  357  void
 348  358  smb_server_g_fini(void)
 349  359  {
 350  360  
 351  361          ASSERT(smb_llist_get_count(&smb_servers) == 0);
 352  362  
  
    | 
      ↓ open down ↓ | 
    15 lines elided | 
    
      ↑ open up ↑ | 
  
 353  363          smb_llist_fini();
 354  364  
 355  365          kmem_cache_destroy(smb_cache_request);
 356  366          kmem_cache_destroy(smb_cache_session);
 357  367          kmem_cache_destroy(smb_cache_user);
 358  368          kmem_cache_destroy(smb_cache_tree);
 359  369          kmem_cache_destroy(smb_cache_ofile);
 360  370          kmem_cache_destroy(smb_cache_odir);
 361  371          kmem_cache_destroy(smb_cache_opipe);
 362  372          kmem_cache_destroy(smb_cache_event);
      373 +        kmem_cache_destroy(smb_cache_lock);
 363  374  
      375 +        smb2_lease_fini();
 364  376          smb_node_fini();
 365  377          smb_mbc_fini();
 366  378          smb_codepage_fini();
 367  379          smb_kshare_g_fini();
 368  380  
 369  381          smb_fem_fini();
 370  382          smb_vop_fini();
 371  383  
 372  384          smb_llist_destructor(&smb_servers);
 373  385  }
 374  386  
 375  387  /*
 376  388   * smb_server_create
 377  389   *
 378  390   * This function will fail if there's already a server associated with the
 379  391   * caller's zone.
 380  392   */
 381  393  int
 382  394  smb_server_create(void)
 383  395  {
 384  396          zoneid_t        zid;
 385  397          smb_server_t    *sv;
 386  398  
 387  399          zid = getzoneid();
 388  400  
 389  401          smb_llist_enter(&smb_servers, RW_WRITER);
 390  402          sv = smb_llist_head(&smb_servers);
 391  403          while (sv) {
 392  404                  SMB_SERVER_VALID(sv);
 393  405                  if (sv->sv_zid == zid) {
 394  406                          smb_llist_exit(&smb_servers);
 395  407                          return (EPERM);
 396  408                  }
 397  409                  sv = smb_llist_next(&smb_servers, sv);
 398  410          }
 399  411  
 400  412          sv = kmem_zalloc(sizeof (smb_server_t), KM_SLEEP);
  
    | 
      ↓ open down ↓ | 
    27 lines elided | 
    
      ↑ open up ↑ | 
  
 401  413  
 402  414          sv->sv_magic = SMB_SERVER_MAGIC;
 403  415          sv->sv_state = SMB_SERVER_STATE_CREATED;
 404  416          sv->sv_zid = zid;
 405  417          sv->sv_pid = ddi_get_pid();
 406  418  
 407  419          mutex_init(&sv->sv_mutex, NULL, MUTEX_DEFAULT, NULL);
 408  420          cv_init(&sv->sv_cv, NULL, CV_DEFAULT, NULL);
 409  421          cv_init(&sv->sp_info.sp_cv, NULL, CV_DEFAULT, NULL);
 410  422  
      423 +        sv->sv_persistid_ht = smb_hash_create(sizeof (smb_ofile_t),
      424 +            offsetof(smb_ofile_t, f_dh_lnd), SMB_OFILE_HASH_NBUCKETS);
      425 +
      426 +        sv->sv_lease_ht = smb_hash_create(sizeof (smb_lease_t),
      427 +            offsetof(smb_lease_t, ls_lnd), SMB_LEASE_HASH_NBUCKETS);
      428 +
      429 +        smb_llist_constructor(&sv->sv_session_list, sizeof (smb_session_t),
      430 +            offsetof(smb_session_t, s_lnd));
      431 +
 411  432          smb_llist_constructor(&sv->sv_event_list, sizeof (smb_event_t),
 412  433              offsetof(smb_event_t, se_lnd));
 413  434  
 414  435          smb_llist_constructor(&sv->sp_info.sp_list, sizeof (smb_kspooldoc_t),
 415  436              offsetof(smb_kspooldoc_t, sd_lnd));
 416  437  
 417  438          smb_llist_constructor(&sv->sp_info.sp_fidlist,
 418  439              sizeof (smb_spoolfid_t), offsetof(smb_spoolfid_t, sf_lnd));
 419  440  
 420  441          sv->sv_disp_stats1 = kmem_zalloc(SMB_COM_NUM *
 421  442              sizeof (smb_disp_stats_t), KM_SLEEP);
 422  443  
 423  444          sv->sv_disp_stats2 = kmem_zalloc(SMB2__NCMDS *
 424  445              sizeof (smb_disp_stats_t), KM_SLEEP);
 425  446  
 426  447          smb_thread_init(&sv->si_thread_timers, "smb_timers",
 427  448              smb_server_timers, sv, smbsrv_timer_pri);
 428  449  
 429  450          smb_srqueue_init(&sv->sv_srqueue);
 430  451  
 431  452          smb_kdoor_init(sv);
 432  453          smb_kshare_init(sv);
 433  454          smb_server_kstat_init(sv);
 434  455  
 435  456          smb_threshold_init(&sv->sv_ssetup_ct, SMB_SSETUP_CMD,
 436  457              smb_ssetup_threshold, smb_ssetup_timeout);
 437  458          smb_threshold_init(&sv->sv_tcon_ct, SMB_TCON_CMD,
 438  459              smb_tcon_threshold, smb_tcon_timeout);
 439  460          smb_threshold_init(&sv->sv_opipe_ct, SMB_OPIPE_CMD,
 440  461              smb_opipe_threshold, smb_opipe_timeout);
 441  462  
 442  463          smb_llist_insert_tail(&smb_servers, sv);
 443  464          smb_llist_exit(&smb_servers);
 444  465  
  
    | 
      ↓ open down ↓ | 
    24 lines elided | 
    
      ↑ open up ↑ | 
  
 445  466          return (0);
 446  467  }
 447  468  
 448  469  /*
 449  470   * smb_server_delete
 450  471   *
 451  472   * This function will delete the server passed in. It will make sure that all
 452  473   * activity associated that server has ceased before destroying it.
 453  474   */
 454  475  int
 455      -smb_server_delete(void)
      476 +smb_server_delete(smb_server_t  *sv)
 456  477  {
 457      -        smb_server_t    *sv;
 458      -        int             rc;
 459  478  
 460      -        rc = smb_server_lookup(&sv);
 461      -        if (rc != 0)
 462      -                return (rc);
 463      -
 464  479          mutex_enter(&sv->sv_mutex);
 465  480          switch (sv->sv_state) {
 466  481          case SMB_SERVER_STATE_RUNNING:
 467  482                  sv->sv_state = SMB_SERVER_STATE_STOPPING;
 468  483                  mutex_exit(&sv->sv_mutex);
 469  484                  smb_server_shutdown(sv);
 470  485                  mutex_enter(&sv->sv_mutex);
 471  486                  cv_broadcast(&sv->sp_info.sp_cv);
 472  487                  sv->sv_state = SMB_SERVER_STATE_DELETING;
 473  488                  break;
 474  489          case SMB_SERVER_STATE_STOPPING:
 475  490                  sv->sv_state = SMB_SERVER_STATE_DELETING;
 476  491                  break;
 477  492          case SMB_SERVER_STATE_CONFIGURED:
 478  493          case SMB_SERVER_STATE_CREATED:
 479  494                  sv->sv_state = SMB_SERVER_STATE_DELETING;
 480  495                  break;
 481  496          default:
 482  497                  SMB_SERVER_STATE_VALID(sv->sv_state);
 483  498                  mutex_exit(&sv->sv_mutex);
 484  499                  smb_server_release(sv);
 485  500                  return (ENOTTY);
 486  501          }
 487  502  
 488  503          ASSERT(sv->sv_state == SMB_SERVER_STATE_DELETING);
 489  504  
 490  505          sv->sv_refcnt--;
 491  506          while (sv->sv_refcnt)
 492  507                  cv_wait(&sv->sv_cv, &sv->sv_mutex);
 493  508  
 494  509          mutex_exit(&sv->sv_mutex);
 495  510  
 496  511          smb_llist_enter(&smb_servers, RW_WRITER);
 497  512          smb_llist_remove(&smb_servers, sv);
 498  513          smb_llist_exit(&smb_servers);
 499  514  
 500  515          smb_threshold_fini(&sv->sv_ssetup_ct);
  
    | 
      ↓ open down ↓ | 
    27 lines elided | 
    
      ↑ open up ↑ | 
  
 501  516          smb_threshold_fini(&sv->sv_tcon_ct);
 502  517          smb_threshold_fini(&sv->sv_opipe_ct);
 503  518  
 504  519          smb_server_listener_destroy(&sv->sv_nbt_daemon);
 505  520          smb_server_listener_destroy(&sv->sv_tcp_daemon);
 506  521          rw_destroy(&sv->sv_cfg_lock);
 507  522          smb_server_kstat_fini(sv);
 508  523          smb_kshare_fini(sv);
 509  524          smb_kdoor_fini(sv);
 510  525          smb_llist_destructor(&sv->sv_event_list);
      526 +        smb_llist_destructor(&sv->sv_session_list);
 511  527  
 512  528          kmem_free(sv->sv_disp_stats1,
 513  529              SMB_COM_NUM * sizeof (smb_disp_stats_t));
 514  530  
 515  531          kmem_free(sv->sv_disp_stats2,
 516  532              SMB2__NCMDS * sizeof (smb_disp_stats_t));
 517  533  
 518  534          smb_srqueue_destroy(&sv->sv_srqueue);
 519  535          smb_thread_destroy(&sv->si_thread_timers);
 520  536  
 521  537          mutex_destroy(&sv->sv_mutex);
      538 +        smb_hash_destroy(sv->sv_lease_ht);
      539 +        smb_hash_destroy(sv->sv_persistid_ht);
 522  540          cv_destroy(&sv->sv_cv);
 523  541          sv->sv_magic = 0;
 524  542          kmem_free(sv, sizeof (smb_server_t));
 525  543  
 526  544          return (0);
 527  545  }
 528  546  
 529  547  /*
 530  548   * smb_server_configure
 531  549   */
 532  550  int
 533  551  smb_server_configure(smb_ioc_cfg_t *ioc)
 534  552  {
 535  553          int             rc = 0;
 536  554          smb_server_t    *sv;
 537  555  
 538  556          /*
 539  557           * Reality check negotiation token length vs. #define'd maximum.
 540  558           */
 541  559          if (ioc->negtok_len > SMB_PI_MAX_NEGTOK)
 542  560                  return (EINVAL);
 543  561  
 544  562          rc = smb_server_lookup(&sv);
 545  563          if (rc)
 546  564                  return (rc);
 547  565  
 548  566          mutex_enter(&sv->sv_mutex);
 549  567          switch (sv->sv_state) {
 550  568          case SMB_SERVER_STATE_CREATED:
 551  569                  smb_server_store_cfg(sv, ioc);
 552  570                  sv->sv_state = SMB_SERVER_STATE_CONFIGURED;
 553  571                  break;
 554  572  
 555  573          case SMB_SERVER_STATE_CONFIGURED:
 556  574                  smb_server_store_cfg(sv, ioc);
 557  575                  break;
 558  576  
 559  577          case SMB_SERVER_STATE_RUNNING:
 560  578          case SMB_SERVER_STATE_STOPPING:
 561  579                  rw_enter(&sv->sv_cfg_lock, RW_WRITER);
 562  580                  smb_server_store_cfg(sv, ioc);
 563  581                  rw_exit(&sv->sv_cfg_lock);
 564  582                  break;
 565  583  
 566  584          default:
 567  585                  SMB_SERVER_STATE_VALID(sv->sv_state);
 568  586                  rc = EFAULT;
 569  587                  break;
 570  588          }
 571  589          mutex_exit(&sv->sv_mutex);
 572  590  
 573  591          smb_server_release(sv);
 574  592  
 575  593          return (rc);
 576  594  }
  
    | 
      ↓ open down ↓ | 
    45 lines elided | 
    
      ↑ open up ↑ | 
  
 577  595  
 578  596  /*
 579  597   * smb_server_start
 580  598   */
 581  599  int
 582  600  smb_server_start(smb_ioc_start_t *ioc)
 583  601  {
 584  602          int             rc = 0;
 585  603          int             family;
 586  604          smb_server_t    *sv;
      605 +        cred_t          *ucr;
 587  606  
 588  607          rc = smb_server_lookup(&sv);
 589  608          if (rc)
 590  609                  return (rc);
 591  610  
 592  611          mutex_enter(&sv->sv_mutex);
 593  612          switch (sv->sv_state) {
 594  613          case SMB_SERVER_STATE_CONFIGURED:
 595  614  
 596  615                  if ((rc = smb_server_fsop_start(sv)) != 0)
 597  616                          break;
 598  617  
      618 +                /*
      619 +                 * Note: smb_kshare_start needs sv_session.
      620 +                 */
      621 +                sv->sv_session = smb_session_create(NULL, 0, sv, 0);
      622 +                if (sv->sv_session == NULL) {
      623 +                        rc = ENOMEM;
      624 +                        break;
      625 +                }
      626 +
      627 +                /*
      628 +                 * Create a logon on the server session,
      629 +                 * used when importing CA shares.
      630 +                 */
      631 +                sv->sv_rootuser = smb_user_new(sv->sv_session);
      632 +                ucr = smb_kcred_create();
      633 +                rc = smb_user_logon(sv->sv_rootuser, ucr, "", "root",
      634 +                    SMB_USER_FLAG_ADMIN, 0, 0);
      635 +                crfree(ucr);
      636 +                ucr = NULL;
      637 +                if (rc != 0) {
      638 +                        cmn_err(CE_NOTE, "smb_server_start: "
      639 +                            "failed to create root user");
      640 +                        break;
      641 +                }
      642 +
 599  643                  if ((rc = smb_kshare_start(sv)) != 0)
 600  644                          break;
 601  645  
 602  646                  /*
 603  647                   * NB: the proc passed here has to be a "system" one.
 604  648                   * Normally that's p0, or the NGZ eqivalent.
 605  649                   */
 606  650                  sv->sv_worker_pool = taskq_create_proc("smb_workers",
 607  651                      sv->sv_cfg.skc_maxworkers, smbsrv_worker_pri,
 608  652                      sv->sv_cfg.skc_maxworkers, INT_MAX,
 609  653                      curzone->zone_zsched, TASKQ_DYNAMIC);
 610  654  
 611  655                  sv->sv_receiver_pool = taskq_create_proc("smb_receivers",
 612  656                      sv->sv_cfg.skc_maxconnections, smbsrv_receive_pri,
 613  657                      sv->sv_cfg.skc_maxconnections, INT_MAX,
 614  658                      curzone->zone_zsched, TASKQ_DYNAMIC);
 615  659  
 616      -                sv->sv_session = smb_session_create(NULL, 0, sv, 0);
 617      -
 618      -                if (sv->sv_worker_pool == NULL || sv->sv_session == NULL) {
      660 +                if (sv->sv_worker_pool == NULL ||
      661 +                    sv->sv_receiver_pool == NULL) {
 619  662                          rc = ENOMEM;
 620  663                          break;
 621  664                  }
 622  665  
 623  666  #ifdef  _KERNEL
 624  667                  ASSERT(sv->sv_lmshrd == NULL);
 625  668                  sv->sv_lmshrd = smb_kshare_door_init(ioc->lmshrd);
 626  669                  if (sv->sv_lmshrd == NULL)
 627  670                          break;
 628      -                if (rc = smb_kdoor_open(sv, ioc->udoor)) {
      671 +                if ((rc = smb_kdoor_open(sv, ioc->udoor)) != 0) {
 629  672                          cmn_err(CE_WARN, "Cannot open smbd door");
 630  673                          break;
 631  674                  }
 632  675  #else   /* _KERNEL */
 633  676                  /* Fake kernel does not use the kshare_door */
 634  677                  fksmb_kdoor_open(sv, ioc->udoor_func);
 635  678  #endif  /* _KERNEL */
 636  679  
 637      -                if (rc = smb_thread_start(&sv->si_thread_timers))
      680 +                if ((rc = smb_thread_start(&sv->si_thread_timers)) != 0)
 638  681                          break;
 639  682  
 640  683                  family = AF_INET;
 641  684                  smb_server_listener_init(sv, &sv->sv_nbt_daemon,
 642  685                      "smb_nbt_listener", IPPORT_NETBIOS_SSN, family);
 643  686                  if (sv->sv_cfg.skc_ipv6_enable)
 644  687                          family = AF_INET6;
 645  688                  smb_server_listener_init(sv, &sv->sv_tcp_daemon,
 646  689                      "smb_tcp_listener", IPPORT_SMB, family);
 647  690                  rc = smb_server_listener_start(&sv->sv_tcp_daemon);
 648  691                  if (rc != 0)
 649  692                          break;
 650  693                  if (sv->sv_cfg.skc_netbios_enable)
 651  694                          (void) smb_server_listener_start(&sv->sv_nbt_daemon);
 652  695  
 653  696                  sv->sv_state = SMB_SERVER_STATE_RUNNING;
 654  697                  sv->sv_start_time = gethrtime();
 655  698                  mutex_exit(&sv->sv_mutex);
 656  699                  smb_server_release(sv);
 657  700                  smb_export_start(sv);
 658  701                  return (0);
 659  702          default:
 660  703                  SMB_SERVER_STATE_VALID(sv->sv_state);
 661  704                  mutex_exit(&sv->sv_mutex);
 662  705                  smb_server_release(sv);
 663  706                  return (ENOTTY);
 664  707          }
 665  708  
 666  709          mutex_exit(&sv->sv_mutex);
 667  710          smb_server_shutdown(sv);
 668  711          smb_server_release(sv);
 669  712          return (rc);
 670  713  }
 671  714  
 672  715  /*
 673  716   * An smbd is shutting down.
 674  717   */
 675  718  int
 676  719  smb_server_stop(void)
 677  720  {
 678  721          smb_server_t    *sv;
 679  722          int             rc;
 680  723  
 681  724          if ((rc = smb_server_lookup(&sv)) != 0)
 682  725                  return (rc);
 683  726  
 684  727          mutex_enter(&sv->sv_mutex);
 685  728          switch (sv->sv_state) {
 686  729          case SMB_SERVER_STATE_RUNNING:
 687  730                  sv->sv_state = SMB_SERVER_STATE_STOPPING;
 688  731                  mutex_exit(&sv->sv_mutex);
 689  732                  smb_server_shutdown(sv);
 690  733                  mutex_enter(&sv->sv_mutex);
 691  734                  cv_broadcast(&sv->sp_info.sp_cv);
 692  735                  break;
 693  736          default:
 694  737                  SMB_SERVER_STATE_VALID(sv->sv_state);
 695  738                  break;
 696  739          }
 697  740          mutex_exit(&sv->sv_mutex);
 698  741  
 699  742          smb_server_release(sv);
 700  743          return (0);
 701  744  }
 702  745  
 703  746  boolean_t
 704  747  smb_server_is_stopping(smb_server_t *sv)
 705  748  {
 706  749          boolean_t       status;
 707  750  
 708  751          SMB_SERVER_VALID(sv);
 709  752  
 710  753          mutex_enter(&sv->sv_mutex);
 711  754  
 712  755          switch (sv->sv_state) {
 713  756          case SMB_SERVER_STATE_STOPPING:
 714  757          case SMB_SERVER_STATE_DELETING:
 715  758                  status = B_TRUE;
 716  759                  break;
 717  760          default:
 718  761                  status = B_FALSE;
 719  762                  break;
 720  763          }
 721  764  
 722  765          mutex_exit(&sv->sv_mutex);
 723  766          return (status);
 724  767  }
 725  768  
 726  769  void
 727  770  smb_server_cancel_event(smb_server_t *sv, uint32_t txid)
 728  771  {
 729  772          smb_event_cancel(sv, txid);
 730  773  }
 731  774  
 732  775  int
 733  776  smb_server_notify_event(smb_ioc_event_t *ioc)
 734  777  {
 735  778          smb_server_t    *sv;
 736  779          int             rc;
 737  780  
 738  781          if ((rc = smb_server_lookup(&sv)) == 0) {
 739  782                  smb_event_notify(sv, ioc->txid);
 740  783                  smb_server_release(sv);
 741  784          }
 742  785  
 743  786          return (rc);
 744  787  }
 745  788  
 746  789  /*
 747  790   * smb_server_spooldoc
 748  791   *
 749  792   * Waits for print file close broadcast.
 750  793   * Gets the head of the fid list,
 751  794   * then searches the spooldoc list and returns
 752  795   * this info via the ioctl to user land.
 753  796   *
 754  797   * rc - 0 success
 755  798   */
 756  799  
 757  800  int
 758  801  smb_server_spooldoc(smb_ioc_spooldoc_t *ioc)
 759  802  {
 760  803          smb_server_t    *sv;
 761  804          int             rc;
 762  805          smb_kspooldoc_t *spdoc;
 763  806          uint16_t        fid;
 764  807  
 765  808          if ((rc = smb_server_lookup(&sv)) != 0)
 766  809                  return (rc);
 767  810  
 768  811          if (sv->sv_cfg.skc_print_enable == 0) {
 769  812                  rc = ENOTTY;
 770  813                  goto out;
 771  814          }
 772  815  
 773  816          mutex_enter(&sv->sv_mutex);
 774  817          for (;;) {
 775  818                  if (sv->sv_state != SMB_SERVER_STATE_RUNNING) {
 776  819                          rc = ECANCELED;
 777  820                          break;
 778  821                  }
 779  822                  if ((fid = smb_spool_get_fid(sv)) != 0) {
 780  823                          rc = 0;
 781  824                          break;
 782  825                  }
 783  826                  if (cv_wait_sig(&sv->sp_info.sp_cv, &sv->sv_mutex) == 0) {
 784  827                          rc = EINTR;
 785  828                          break;
 786  829                  }
 787  830          }
 788  831          mutex_exit(&sv->sv_mutex);
 789  832          if (rc != 0)
 790  833                  goto out;
 791  834  
 792  835          spdoc = kmem_zalloc(sizeof (*spdoc), KM_SLEEP);
 793  836          if (smb_spool_lookup_doc_byfid(sv, fid, spdoc)) {
 794  837                  ioc->spool_num = spdoc->sd_spool_num;
 795  838                  ioc->ipaddr = spdoc->sd_ipaddr;
 796  839                  (void) strlcpy(ioc->path, spdoc->sd_path,
 797  840                      MAXPATHLEN);
 798  841                  (void) strlcpy(ioc->username,
 799  842                      spdoc->sd_username, MAXNAMELEN);
 800  843          } else {
 801  844                  /* Did not find that print job. */
 802  845                  rc = EAGAIN;
 803  846          }
 804  847          kmem_free(spdoc, sizeof (*spdoc));
 805  848  
 806  849  out:
 807  850          smb_server_release(sv);
 808  851          return (rc);
 809  852  }
 810  853  
 811  854  int
 812  855  smb_server_set_gmtoff(smb_ioc_gmt_t *ioc)
 813  856  {
 814  857          int             rc;
 815  858          smb_server_t    *sv;
 816  859  
 817  860          if ((rc = smb_server_lookup(&sv)) == 0) {
 818  861                  sv->si_gmtoff = ioc->offset;
 819  862                  smb_server_release(sv);
 820  863          }
 821  864  
 822  865          return (rc);
 823  866  }
 824  867  
 825  868  int
 826  869  smb_server_numopen(smb_ioc_opennum_t *ioc)
 827  870  {
 828  871          smb_server_t    *sv;
 829  872          int             rc;
 830  873  
 831  874          if ((rc = smb_server_lookup(&sv)) == 0) {
 832  875                  ioc->open_users = sv->sv_users;
 833  876                  ioc->open_trees = sv->sv_trees;
 834  877                  ioc->open_files = sv->sv_files + sv->sv_pipes;
 835  878                  smb_server_release(sv);
 836  879          }
 837  880          return (rc);
 838  881  }
 839  882  
 840  883  /*
 841  884   * Enumerate objects within the server.  The svcenum provides the
 842  885   * enumeration context, i.e. what the caller want to get back.
 843  886   */
 844  887  int
 845  888  smb_server_enum(smb_ioc_svcenum_t *ioc)
 846  889  {
 847  890          smb_svcenum_t   *svcenum = &ioc->svcenum;
 848  891          smb_server_t    *sv;
 849  892          int             rc;
 850  893  
 851  894          /*
 852  895           * Reality check that the buffer-length insize the enum doesn't
 853  896           * overrun the ioctl's total length.
 854  897           */
 855  898          if (svcenum->se_buflen + sizeof (*ioc) > ioc->hdr.len)
 856  899                  return (EINVAL);
  
    | 
      ↓ open down ↓ | 
    209 lines elided | 
    
      ↑ open up ↑ | 
  
 857  900  
 858  901          if ((rc = smb_server_lookup(&sv)) != 0)
 859  902                  return (rc);
 860  903  
 861  904          svcenum->se_bavail = svcenum->se_buflen;
 862  905          svcenum->se_bused = 0;
 863  906          svcenum->se_nitems = 0;
 864  907  
 865  908          switch (svcenum->se_type) {
 866  909          case SMB_SVCENUM_TYPE_USER:
 867      -                smb_server_enum_users(&sv->sv_nbt_daemon.ld_session_list,
 868      -                    svcenum);
 869      -                smb_server_enum_users(&sv->sv_tcp_daemon.ld_session_list,
 870      -                    svcenum);
      910 +                smb_server_enum_users(sv, svcenum);
 871  911                  break;
 872  912          case SMB_SVCENUM_TYPE_TREE:
 873  913          case SMB_SVCENUM_TYPE_FILE:
 874      -                smb_server_enum_trees(&sv->sv_nbt_daemon.ld_session_list,
 875      -                    svcenum);
 876      -                smb_server_enum_trees(&sv->sv_tcp_daemon.ld_session_list,
 877      -                    svcenum);
      914 +                smb_server_enum_trees(sv, svcenum);
 878  915                  break;
 879  916          default:
 880  917                  rc = EINVAL;
 881  918          }
 882  919  
 883  920          smb_server_release(sv);
 884  921          return (rc);
 885  922  }
 886  923  
 887  924  /*
 888  925   * Look for sessions to disconnect by client and user name.
 889  926   */
 890  927  int
 891  928  smb_server_session_close(smb_ioc_session_t *ioc)
 892  929  {
 893      -        smb_llist_t     *ll;
 894  930          smb_server_t    *sv;
 895      -        int             nbt_cnt;
 896      -        int             tcp_cnt;
      931 +        int             cnt;
 897  932          int             rc;
 898  933  
 899  934          if ((rc = smb_server_lookup(&sv)) != 0)
 900  935                  return (rc);
 901  936  
 902      -        ll = &sv->sv_nbt_daemon.ld_session_list;
 903      -        nbt_cnt = smb_server_session_disconnect(ll, ioc->client, ioc->username);
      937 +        cnt = smb_server_session_disconnect(sv, ioc->client, ioc->username);
 904  938  
 905      -        ll = &sv->sv_tcp_daemon.ld_session_list;
 906      -        tcp_cnt = smb_server_session_disconnect(ll, ioc->client, ioc->username);
 907      -
 908  939          smb_server_release(sv);
 909  940  
 910      -        if ((nbt_cnt == 0) && (tcp_cnt == 0))
      941 +        if (cnt == 0)
 911  942                  return (ENOENT);
 912  943          return (0);
 913  944  }
 914  945  
 915  946  /*
 916  947   * Close a file by uniqid.
 917  948   */
 918  949  int
 919  950  smb_server_file_close(smb_ioc_fileid_t *ioc)
 920  951  {
 921  952          uint32_t        uniqid = ioc->uniqid;
 922      -        smb_llist_t     *ll;
 923  953          smb_server_t    *sv;
 924  954          int             rc;
 925  955  
 926  956          if ((rc = smb_server_lookup(&sv)) != 0)
 927  957                  return (rc);
 928  958  
 929      -        ll = &sv->sv_nbt_daemon.ld_session_list;
 930      -        rc = smb_server_fclose(ll, uniqid);
      959 +        rc = smb_server_fclose(sv, uniqid);
 931  960  
 932      -        if (rc == ENOENT) {
 933      -                ll = &sv->sv_tcp_daemon.ld_session_list;
 934      -                rc = smb_server_fclose(ll, uniqid);
 935      -        }
 936      -
 937  961          smb_server_release(sv);
 938  962          return (rc);
 939  963  }
 940  964  
 941  965  /*
 942  966   * These functions determine the relevant smb server to which the call apply.
 943  967   */
 944  968  
 945  969  uint32_t
 946  970  smb_server_get_session_count(smb_server_t *sv)
 947  971  {
 948  972          uint32_t        counter = 0;
 949  973  
 950      -        counter = smb_llist_get_count(&sv->sv_nbt_daemon.ld_session_list);
 951      -        counter += smb_llist_get_count(&sv->sv_tcp_daemon.ld_session_list);
      974 +        counter = smb_llist_get_count(&sv->sv_session_list);
 952  975  
 953  976          return (counter);
 954  977  }
 955  978  
 956  979  /*
 957      - * Gets the vnode of the specified share path.
 958      - *
 959      - * A hold on the returned vnode pointer is taken so the caller
 960      - * must call VN_RELE.
      980 + * Gets the smb_node of the specified share path.
      981 + * Node is returned held (caller must rele.)
 961  982   */
 962  983  int
 963      -smb_server_sharevp(smb_server_t *sv, const char *shr_path, vnode_t **vp)
      984 +smb_server_share_lookup(smb_server_t *sv, const char *shr_path,
      985 +    smb_node_t **nodepp)
 964  986  {
 965  987          smb_request_t   *sr;
 966  988          smb_node_t      *fnode = NULL;
 967      -        smb_node_t      *dnode;
      989 +        smb_node_t      *dnode = NULL;
 968  990          char            last_comp[MAXNAMELEN];
 969  991          int             rc = 0;
 970  992  
 971  993          ASSERT(shr_path);
 972  994  
 973  995          mutex_enter(&sv->sv_mutex);
 974  996          switch (sv->sv_state) {
 975  997          case SMB_SERVER_STATE_RUNNING:
 976  998                  break;
 977  999          default:
 978 1000                  mutex_exit(&sv->sv_mutex);
 979 1001                  return (ENOTACTIVE);
 980 1002          }
 981 1003          mutex_exit(&sv->sv_mutex);
 982 1004  
 983 1005          if ((sr = smb_request_alloc(sv->sv_session, 0)) == NULL) {
 984      -                return (ENOMEM);
     1006 +                return (ENOTCONN);
 985 1007          }
 986 1008          sr->user_cr = zone_kcred();
 987 1009  
 988 1010          rc = smb_pathname_reduce(sr, sr->user_cr, shr_path,
 989 1011              NULL, NULL, &dnode, last_comp);
 990 1012  
 991 1013          if (rc == 0) {
 992 1014                  rc = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS,
 993 1015                      sv->si_root_smb_node, dnode, last_comp, &fnode);
 994 1016                  smb_node_release(dnode);
 995 1017          }
 996 1018  
 997 1019          smb_request_free(sr);
 998 1020  
 999 1021          if (rc != 0)
1000 1022                  return (rc);
1001 1023  
1002 1024          ASSERT(fnode->vp && fnode->vp->v_vfsp);
1003 1025  
1004      -        VN_HOLD(fnode->vp);
1005      -        *vp = fnode->vp;
     1026 +        *nodepp = fnode;
1006 1027  
1007      -        smb_node_release(fnode);
1008      -
1009 1028          return (0);
1010 1029  }
1011 1030  
1012 1031  #ifdef  _KERNEL
1013 1032  /*
1014 1033   * This is a special interface that will be utilized by ZFS to cause a share to
1015 1034   * be added/removed.
1016 1035   *
1017 1036   * arg is either a lmshare_info_t or share_name from userspace.
1018 1037   * It will need to be copied into the kernel.   It is lmshare_info_t
1019 1038   * for add operations and share_name for delete operations.
1020 1039   */
1021 1040  int
1022 1041  smb_server_share(void *arg, boolean_t add_share)
1023 1042  {
1024 1043          smb_server_t    *sv;
1025 1044          int             rc;
1026 1045  
1027 1046          if ((rc = smb_server_lookup(&sv)) == 0) {
1028 1047                  mutex_enter(&sv->sv_mutex);
1029 1048                  switch (sv->sv_state) {
1030 1049                  case SMB_SERVER_STATE_RUNNING:
1031 1050                          mutex_exit(&sv->sv_mutex);
1032 1051                          (void) smb_kshare_upcall(sv->sv_lmshrd, arg, add_share);
1033 1052                          break;
1034 1053                  default:
1035 1054                          mutex_exit(&sv->sv_mutex);
1036 1055                          break;
1037 1056                  }
1038 1057                  smb_server_release(sv);
  
    | 
      ↓ open down ↓ | 
    20 lines elided | 
    
      ↑ open up ↑ | 
  
1039 1058          }
1040 1059  
1041 1060          return (rc);
1042 1061  }
1043 1062  #endif  /* _KERNEL */
1044 1063  
1045 1064  int
1046 1065  smb_server_unshare(const char *sharename)
1047 1066  {
1048 1067          smb_server_t    *sv;
1049      -        smb_llist_t     *ll;
1050 1068          int             rc;
1051 1069  
1052 1070          if ((rc = smb_server_lookup(&sv)))
1053 1071                  return (rc);
1054 1072  
1055 1073          mutex_enter(&sv->sv_mutex);
1056 1074          switch (sv->sv_state) {
1057 1075          case SMB_SERVER_STATE_RUNNING:
1058 1076          case SMB_SERVER_STATE_STOPPING:
1059 1077                  break;
1060 1078          default:
1061 1079                  mutex_exit(&sv->sv_mutex);
1062 1080                  smb_server_release(sv);
1063 1081                  return (ENOTACTIVE);
1064 1082          }
1065 1083          mutex_exit(&sv->sv_mutex);
1066 1084  
1067      -        ll = &sv->sv_nbt_daemon.ld_session_list;
1068      -        smb_server_disconnect_share(ll, sharename);
     1085 +        smb_server_disconnect_share(sv, sharename);
1069 1086  
1070      -        ll = &sv->sv_tcp_daemon.ld_session_list;
1071      -        smb_server_disconnect_share(ll, sharename);
1072      -
1073 1087          smb_server_release(sv);
1074 1088          return (0);
1075 1089  }
1076 1090  
1077 1091  /*
1078 1092   * Disconnect the specified share.
1079 1093   * Typically called when a share has been removed.
1080 1094   */
1081 1095  static void
1082      -smb_server_disconnect_share(smb_llist_t *ll, const char *sharename)
     1096 +smb_server_disconnect_share(smb_server_t *sv, const char *sharename)
1083 1097  {
     1098 +        smb_llist_t     *ll;
1084 1099          smb_session_t   *session;
1085 1100  
     1101 +        ll = &sv->sv_session_list;
1086 1102          smb_llist_enter(ll, RW_READER);
1087 1103  
1088 1104          session = smb_llist_head(ll);
1089 1105          while (session) {
1090 1106                  SMB_SESSION_VALID(session);
1091 1107                  smb_rwx_rwenter(&session->s_lock, RW_READER);
1092 1108                  switch (session->s_state) {
1093 1109                  case SMB_SESSION_STATE_NEGOTIATED:
     1110 +                        smb_rwx_rwexit(&session->s_lock);
1094 1111                          smb_session_disconnect_share(session, sharename);
1095 1112                          break;
1096 1113                  default:
     1114 +                        smb_rwx_rwexit(&session->s_lock);
1097 1115                          break;
1098 1116                  }
1099      -                smb_rwx_rwexit(&session->s_lock);
1100 1117                  session = smb_llist_next(ll, session);
1101 1118          }
1102 1119  
1103 1120          smb_llist_exit(ll);
1104 1121  }
1105 1122  
1106 1123  /*
1107 1124   * *****************************************************************************
1108 1125   * **************** Functions called from the internal layers ******************
1109 1126   * *****************************************************************************
1110 1127   *
1111 1128   * These functions are provided the relevant smb server by the caller.
1112 1129   */
1113 1130  
1114 1131  void
1115 1132  smb_server_get_cfg(smb_server_t *sv, smb_kmod_cfg_t *cfg)
1116 1133  {
1117 1134          rw_enter(&sv->sv_cfg_lock, RW_READER);
1118 1135          bcopy(&sv->sv_cfg, cfg, sizeof (*cfg));
1119 1136          rw_exit(&sv->sv_cfg_lock);
1120 1137  }
1121 1138  
1122 1139  /*
1123 1140   *
1124 1141   */
1125 1142  void
1126 1143  smb_server_inc_nbt_sess(smb_server_t *sv)
1127 1144  {
1128 1145          SMB_SERVER_VALID(sv);
1129 1146          atomic_inc_32(&sv->sv_nbt_sess);
1130 1147  }
1131 1148  
1132 1149  void
1133 1150  smb_server_dec_nbt_sess(smb_server_t *sv)
1134 1151  {
1135 1152          SMB_SERVER_VALID(sv);
1136 1153          atomic_dec_32(&sv->sv_nbt_sess);
1137 1154  }
1138 1155  
1139 1156  void
1140 1157  smb_server_inc_tcp_sess(smb_server_t *sv)
1141 1158  {
1142 1159          SMB_SERVER_VALID(sv);
1143 1160          atomic_inc_32(&sv->sv_tcp_sess);
1144 1161  }
1145 1162  
1146 1163  void
1147 1164  smb_server_dec_tcp_sess(smb_server_t *sv)
1148 1165  {
1149 1166          SMB_SERVER_VALID(sv);
1150 1167          atomic_dec_32(&sv->sv_tcp_sess);
1151 1168  }
1152 1169  
1153 1170  void
1154 1171  smb_server_inc_users(smb_server_t *sv)
1155 1172  {
1156 1173          SMB_SERVER_VALID(sv);
1157 1174          atomic_inc_32(&sv->sv_users);
1158 1175  }
1159 1176  
1160 1177  void
1161 1178  smb_server_dec_users(smb_server_t *sv)
1162 1179  {
1163 1180          SMB_SERVER_VALID(sv);
1164 1181          atomic_dec_32(&sv->sv_users);
1165 1182  }
1166 1183  
1167 1184  void
1168 1185  smb_server_inc_trees(smb_server_t *sv)
1169 1186  {
1170 1187          SMB_SERVER_VALID(sv);
1171 1188          atomic_inc_32(&sv->sv_trees);
1172 1189  }
1173 1190  
1174 1191  void
1175 1192  smb_server_dec_trees(smb_server_t *sv)
1176 1193  {
1177 1194          SMB_SERVER_VALID(sv);
1178 1195          atomic_dec_32(&sv->sv_trees);
1179 1196  }
1180 1197  
1181 1198  void
1182 1199  smb_server_inc_files(smb_server_t *sv)
1183 1200  {
1184 1201          SMB_SERVER_VALID(sv);
1185 1202          atomic_inc_32(&sv->sv_files);
1186 1203  }
1187 1204  
1188 1205  void
1189 1206  smb_server_dec_files(smb_server_t *sv)
1190 1207  {
1191 1208          SMB_SERVER_VALID(sv);
1192 1209          atomic_dec_32(&sv->sv_files);
1193 1210  }
1194 1211  
1195 1212  void
1196 1213  smb_server_inc_pipes(smb_server_t *sv)
1197 1214  {
1198 1215          SMB_SERVER_VALID(sv);
1199 1216          atomic_inc_32(&sv->sv_pipes);
1200 1217  }
1201 1218  
1202 1219  void
1203 1220  smb_server_dec_pipes(smb_server_t *sv)
1204 1221  {
1205 1222          SMB_SERVER_VALID(sv);
1206 1223          atomic_dec_32(&sv->sv_pipes);
1207 1224  }
1208 1225  
1209 1226  void
1210 1227  smb_server_add_rxb(smb_server_t *sv, int64_t value)
1211 1228  {
1212 1229          SMB_SERVER_VALID(sv);
1213 1230          atomic_add_64(&sv->sv_rxb, value);
1214 1231  }
1215 1232  
1216 1233  void
1217 1234  smb_server_add_txb(smb_server_t *sv, int64_t value)
1218 1235  {
1219 1236          SMB_SERVER_VALID(sv);
1220 1237          atomic_add_64(&sv->sv_txb, value);
1221 1238  }
1222 1239  
1223 1240  void
1224 1241  smb_server_inc_req(smb_server_t *sv)
1225 1242  {
1226 1243          SMB_SERVER_VALID(sv);
1227 1244          atomic_inc_64(&sv->sv_nreq);
1228 1245  }
1229 1246  
1230 1247  /*
1231 1248   * *****************************************************************************
1232 1249   * *************************** Static Functions ********************************
1233 1250   * *****************************************************************************
  
    | 
      ↓ open down ↓ | 
    124 lines elided | 
    
      ↑ open up ↑ | 
  
1234 1251   */
1235 1252  
1236 1253  static void
1237 1254  smb_server_timers(smb_thread_t *thread, void *arg)
1238 1255  {
1239 1256          smb_server_t    *sv = (smb_server_t *)arg;
1240 1257  
1241 1258          ASSERT(sv != NULL);
1242 1259  
1243 1260          /*
1244      -         * This just kills old inactive sessions.  No urgency.
1245      -         * The session code expects one call per minute.
     1261 +         * This kills old inactive sessions and expired durable
     1262 +         * handles. The session code expects one call per minute.
1246 1263           */
1247 1264          while (smb_thread_continue_timedwait(thread, 60 /* Seconds */)) {
1248      -                smb_session_timers(&sv->sv_nbt_daemon.ld_session_list);
1249      -                smb_session_timers(&sv->sv_tcp_daemon.ld_session_list);
     1265 +                if (sv->sv_cfg.skc_keepalive != 0)
     1266 +                        smb_session_timers(sv);
     1267 +                smb2_durable_timers(sv);
1250 1268          }
1251 1269  }
1252 1270  
1253 1271  /*
1254 1272   * smb_server_kstat_init
1255 1273   */
1256 1274  static void
1257 1275  smb_server_kstat_init(smb_server_t *sv)
1258 1276  {
1259 1277  
1260 1278          sv->sv_ksp = kstat_create_zone(SMBSRV_KSTAT_MODULE, 0,
1261 1279              SMBSRV_KSTAT_STATISTICS, SMBSRV_KSTAT_CLASS, KSTAT_TYPE_RAW,
1262 1280              sizeof (smbsrv_kstats_t), 0, sv->sv_zid);
1263 1281  
1264 1282          if (sv->sv_ksp != NULL) {
1265 1283                  sv->sv_ksp->ks_update = smb_server_kstat_update;
1266 1284                  sv->sv_ksp->ks_private = sv;
1267 1285                  ((smbsrv_kstats_t *)sv->sv_ksp->ks_data)->ks_start_time =
1268 1286                      sv->sv_start_time;
1269 1287                  smb_dispatch_stats_init(sv);
1270 1288                  smb2_dispatch_stats_init(sv);
1271 1289                  kstat_install(sv->sv_ksp);
1272 1290          } else {
1273 1291                  cmn_err(CE_WARN, "SMB Server: Statistics unavailable");
1274 1292          }
1275 1293  
1276 1294          sv->sv_legacy_ksp = kstat_create_zone(SMBSRV_KSTAT_MODULE, 0,
1277 1295              SMBSRV_KSTAT_NAME, SMBSRV_KSTAT_CLASS, KSTAT_TYPE_NAMED,
1278 1296              sizeof (smb_server_legacy_kstat_t) / sizeof (kstat_named_t),
1279 1297              0, sv->sv_zid);
1280 1298  
1281 1299          if (sv->sv_legacy_ksp != NULL) {
1282 1300                  smb_server_legacy_kstat_t *ksd;
1283 1301  
1284 1302                  ksd = sv->sv_legacy_ksp->ks_data;
1285 1303  
1286 1304                  (void) strlcpy(ksd->ls_files.name, "open_files",
1287 1305                      sizeof (ksd->ls_files.name));
1288 1306                  ksd->ls_files.data_type = KSTAT_DATA_UINT32;
1289 1307  
1290 1308                  (void) strlcpy(ksd->ls_trees.name, "connections",
1291 1309                      sizeof (ksd->ls_trees.name));
1292 1310                  ksd->ls_trees.data_type = KSTAT_DATA_UINT32;
1293 1311  
1294 1312                  (void) strlcpy(ksd->ls_users.name, "connections",
1295 1313                      sizeof (ksd->ls_users.name));
1296 1314                  ksd->ls_users.data_type = KSTAT_DATA_UINT32;
1297 1315  
1298 1316                  mutex_init(&sv->sv_legacy_ksmtx, NULL, MUTEX_DEFAULT, NULL);
1299 1317                  sv->sv_legacy_ksp->ks_lock = &sv->sv_legacy_ksmtx;
1300 1318                  sv->sv_legacy_ksp->ks_update = smb_server_legacy_kstat_update;
1301 1319                  kstat_install(sv->sv_legacy_ksp);
1302 1320          }
1303 1321  }
1304 1322  
1305 1323  /*
1306 1324   * smb_server_kstat_fini
1307 1325   */
1308 1326  static void
1309 1327  smb_server_kstat_fini(smb_server_t *sv)
1310 1328  {
1311 1329          if (sv->sv_legacy_ksp != NULL) {
1312 1330                  kstat_delete(sv->sv_legacy_ksp);
1313 1331                  mutex_destroy(&sv->sv_legacy_ksmtx);
1314 1332                  sv->sv_legacy_ksp = NULL;
1315 1333          }
  
    | 
      ↓ open down ↓ | 
    56 lines elided | 
    
      ↑ open up ↑ | 
  
1316 1334  
1317 1335          if (sv->sv_ksp != NULL) {
1318 1336                  kstat_delete(sv->sv_ksp);
1319 1337                  sv->sv_ksp = NULL;
1320 1338                  smb_dispatch_stats_fini(sv);
1321 1339                  smb2_dispatch_stats_fini(sv);
1322 1340          }
1323 1341  }
1324 1342  
1325 1343  /*
     1344 + * Verify the defines in smb_kstat.h used by ks_reqs1 ks_reqs2
     1345 + */
     1346 +CTASSERT(SMBSRV_KS_NREQS1 == SMB_COM_NUM);
     1347 +CTASSERT(SMBSRV_KS_NREQS2 == SMB2__NCMDS);
     1348 +
     1349 +/*
1326 1350   * smb_server_kstat_update
1327 1351   */
1328 1352  static int
1329 1353  smb_server_kstat_update(kstat_t *ksp, int rw)
1330 1354  {
1331 1355          smb_server_t    *sv;
1332 1356          smbsrv_kstats_t *ksd;
1333 1357  
1334 1358          if (rw == KSTAT_READ) {
1335 1359                  sv = ksp->ks_private;
1336 1360                  SMB_SERVER_VALID(sv);
1337 1361                  ksd = (smbsrv_kstats_t *)ksp->ks_data;
1338 1362                  /*
1339 1363                   * Counters
1340 1364                   */
1341 1365                  ksd->ks_nbt_sess = sv->sv_nbt_sess;
1342 1366                  ksd->ks_tcp_sess = sv->sv_tcp_sess;
1343 1367                  ksd->ks_users = sv->sv_users;
1344 1368                  ksd->ks_trees = sv->sv_trees;
1345 1369                  ksd->ks_files = sv->sv_files;
1346 1370                  ksd->ks_pipes = sv->sv_pipes;
1347 1371                  /*
1348 1372                   * Throughput
1349 1373                   */
1350 1374                  ksd->ks_txb = sv->sv_txb;
1351 1375                  ksd->ks_rxb = sv->sv_rxb;
1352 1376                  ksd->ks_nreq = sv->sv_nreq;
1353 1377                  /*
1354 1378                   * Busyness
1355 1379                   */
1356 1380                  ksd->ks_maxreqs = sv->sv_cfg.skc_maxworkers;
1357 1381                  smb_srqueue_update(&sv->sv_srqueue,
1358 1382                      &ksd->ks_utilization);
1359 1383                  /*
1360 1384                   * Latency & Throughput of the requests
1361 1385                   */
1362 1386                  smb_dispatch_stats_update(sv, ksd->ks_reqs1, 0, SMB_COM_NUM);
1363 1387                  smb2_dispatch_stats_update(sv, ksd->ks_reqs2, 0, SMB2__NCMDS);
1364 1388                  return (0);
1365 1389          }
1366 1390          if (rw == KSTAT_WRITE)
1367 1391                  return (EACCES);
1368 1392  
1369 1393          return (EIO);
1370 1394  }
1371 1395  
1372 1396  static int
1373 1397  smb_server_legacy_kstat_update(kstat_t *ksp, int rw)
1374 1398  {
1375 1399          smb_server_t                    *sv;
1376 1400          smb_server_legacy_kstat_t       *ksd;
1377 1401          int                             rc;
1378 1402  
1379 1403          switch (rw) {
1380 1404          case KSTAT_WRITE:
1381 1405                  rc = EACCES;
1382 1406                  break;
1383 1407          case KSTAT_READ:
1384 1408                  if (!smb_server_lookup(&sv)) {
1385 1409                          ASSERT(MUTEX_HELD(ksp->ks_lock));
1386 1410                          ASSERT(sv->sv_legacy_ksp == ksp);
1387 1411                          ksd = (smb_server_legacy_kstat_t *)ksp->ks_data;
1388 1412                          ksd->ls_files.value.ui32 = sv->sv_files + sv->sv_pipes;
1389 1413                          ksd->ls_trees.value.ui32 = sv->sv_trees;
1390 1414                          ksd->ls_users.value.ui32 = sv->sv_users;
1391 1415                          smb_server_release(sv);
1392 1416                          rc = 0;
1393 1417                          break;
1394 1418                  }
1395 1419                  _NOTE(FALLTHRU)
1396 1420          default:
1397 1421                  rc = EIO;
1398 1422                  break;
1399 1423          }
  
    | 
      ↓ open down ↓ | 
    64 lines elided | 
    
      ↑ open up ↑ | 
  
1400 1424          return (rc);
1401 1425  
1402 1426  }
1403 1427  
1404 1428  /*
1405 1429   * smb_server_shutdown
1406 1430   */
1407 1431  static void
1408 1432  smb_server_shutdown(smb_server_t *sv)
1409 1433  {
     1434 +        smb_llist_t *sl = &sv->sv_session_list;
     1435 +        smb_session_t *session;
     1436 +        clock_t time;
     1437 +
1410 1438          SMB_SERVER_VALID(sv);
1411 1439  
1412 1440          /*
1413 1441           * Stop the listeners first, so we don't get any more
1414 1442           * new work while we're trying to shut down.
1415 1443           */
1416 1444          smb_server_listener_stop(&sv->sv_nbt_daemon);
1417 1445          smb_server_listener_stop(&sv->sv_tcp_daemon);
1418 1446          smb_thread_stop(&sv->si_thread_timers);
1419 1447  
     1448 +        /* Disconnect all of the sessions */
     1449 +        smb_llist_enter(sl, RW_READER);
     1450 +        session = smb_llist_head(sl);
     1451 +        while (session != NULL) {
     1452 +                smb_session_disconnect(session);
     1453 +                session = smb_llist_next(sl, session);
     1454 +        }
     1455 +        smb_llist_exit(sl);
     1456 +
1420 1457          /*
1421 1458           * Wake up any threads we might have blocked.
1422 1459           * Must precede kdoor_close etc. because those will
1423 1460           * wait for such threads to get out.
1424 1461           */
1425 1462          smb_event_cancel(sv, 0);
1426 1463          smb_threshold_wake_all(&sv->sv_ssetup_ct);
1427 1464          smb_threshold_wake_all(&sv->sv_tcon_ct);
1428 1465          smb_threshold_wake_all(&sv->sv_opipe_ct);
1429 1466  
     1467 +        /*
     1468 +         * Wait for the session list to empty.
     1469 +         * (cv_signal in smb_server_destroy_session)
     1470 +         *
     1471 +         * This should not take long, but if there are any leaked
     1472 +         * references to ofiles, trees, or users, there could be a
     1473 +         * session hanging around.  If that happens, the ll_count
     1474 +         * never gets to zero and we'll never get the sv_signal.
     1475 +         * Defend against that problem using timed wait, then
     1476 +         * complain if we find sessions left over and continue
     1477 +         * with shutdown in spite of any leaked sessions.
     1478 +         * That's better than a server that won't reboot.
     1479 +         */
     1480 +        time = SEC_TO_TICK(10) + ddi_get_lbolt();
     1481 +        mutex_enter(&sv->sv_mutex);
     1482 +        while (sv->sv_session_list.ll_count != 0) {
     1483 +                if (cv_timedwait(&sv->sv_cv, &sv->sv_mutex, time) < 0)
     1484 +                        break;
     1485 +        }
     1486 +        mutex_exit(&sv->sv_mutex);
     1487 +#ifdef  DEBUG
     1488 +        if (sv->sv_session_list.ll_count != 0) {
     1489 +                cmn_err(CE_NOTE, "shutdown leaked sessions");
     1490 +                debug_enter("shutdown leaked sessions");
     1491 +        }
     1492 +#endif
     1493 +
     1494 +        /*
     1495 +         * Clean out any durable handles.  After this we should
     1496 +         * have no ofiles remaining (and no more oplock breaks).
     1497 +         */
     1498 +        smb2_dh_shutdown(sv);
     1499 +
1430 1500          smb_kdoor_close(sv);
1431 1501  #ifdef  _KERNEL
1432 1502          smb_kshare_door_fini(sv->sv_lmshrd);
1433 1503  #endif  /* _KERNEL */
1434 1504          sv->sv_lmshrd = NULL;
1435 1505  
1436 1506          smb_export_stop(sv);
     1507 +        smb_kshare_stop(sv);
1437 1508  
     1509 +        /*
     1510 +         * Both kshare and the oplock break sub-systems may have
     1511 +         * taskq jobs on the spcial "server" session, until we've
     1512 +         * closed all ofiles and stopped the kshare exporter.
     1513 +         * Now it's safe to destroy the server session, but first
     1514 +         * wait for any requests on it to finish.  Note that for
     1515 +         * normal sessions, this happens in smb_session_cancel,
     1516 +         * but that's not called for the server session.
     1517 +         */
     1518 +        if (sv->sv_rootuser != NULL) {
     1519 +                smb_user_logoff(sv->sv_rootuser);
     1520 +                smb_user_release(sv->sv_rootuser);
     1521 +                sv->sv_rootuser = NULL;
     1522 +        }
1438 1523          if (sv->sv_session != NULL) {
1439      -                /*
1440      -                 * smb_kshare_export may have a request on here.
1441      -                 * Normal sessions do this in smb_session_cancel()
1442      -                 * but this is a "fake" session used only for the
1443      -                 * requests used by the kshare thread(s).
1444      -                 */
1445 1524                  smb_slist_wait_for_empty(&sv->sv_session->s_req_list);
1446 1525  
     1526 +                /* Just in case import left users and trees */
     1527 +                smb_session_logoff(sv->sv_session);
     1528 +
1447 1529                  smb_session_delete(sv->sv_session);
1448 1530                  sv->sv_session = NULL;
1449 1531          }
1450 1532  
1451 1533          if (sv->sv_receiver_pool != NULL) {
1452 1534                  taskq_destroy(sv->sv_receiver_pool);
1453 1535                  sv->sv_receiver_pool = NULL;
1454 1536          }
1455 1537  
1456 1538          if (sv->sv_worker_pool != NULL) {
1457 1539                  taskq_destroy(sv->sv_worker_pool);
1458 1540                  sv->sv_worker_pool = NULL;
1459 1541          }
1460 1542  
1461      -        smb_kshare_stop(sv);
1462 1543          smb_server_fsop_stop(sv);
1463 1544  }
1464 1545  
1465 1546  /*
1466 1547   * smb_server_listener_init
1467 1548   *
1468 1549   * Initializes listener contexts.
1469 1550   */
1470 1551  static void
1471 1552  smb_server_listener_init(
1472 1553      smb_server_t                *sv,
1473 1554      smb_listener_daemon_t       *ld,
1474 1555      char                        *name,
1475 1556      in_port_t                   port,
1476 1557      int                         family)
1477 1558  {
1478 1559          ASSERT(ld->ld_magic != SMB_LISTENER_MAGIC);
1479 1560  
1480 1561          bzero(ld, sizeof (*ld));
1481 1562  
1482 1563          ld->ld_sv = sv;
1483 1564          ld->ld_family = family;
1484 1565          ld->ld_port = port;
1485 1566  
1486 1567          if (family == AF_INET) {
  
    | 
      ↓ open down ↓ | 
    15 lines elided | 
    
      ↑ open up ↑ | 
  
1487 1568                  ld->ld_sin.sin_family = (uint32_t)family;
1488 1569                  ld->ld_sin.sin_port = htons(port);
1489 1570                  ld->ld_sin.sin_addr.s_addr = htonl(INADDR_ANY);
1490 1571          } else {
1491 1572                  ld->ld_sin6.sin6_family = (uint32_t)family;
1492 1573                  ld->ld_sin6.sin6_port = htons(port);
1493 1574                  (void) memset(&ld->ld_sin6.sin6_addr.s6_addr, 0,
1494 1575                      sizeof (ld->ld_sin6.sin6_addr.s6_addr));
1495 1576          }
1496 1577  
1497      -        smb_llist_constructor(&ld->ld_session_list, sizeof (smb_session_t),
1498      -            offsetof(smb_session_t, s_lnd));
1499 1578          smb_thread_init(&ld->ld_thread, name, smb_server_listener, ld,
1500 1579              smbsrv_listen_pri);
1501 1580          ld->ld_magic = SMB_LISTENER_MAGIC;
1502 1581  }
1503 1582  
1504 1583  /*
1505 1584   * smb_server_listener_destroy
1506 1585   *
1507 1586   * Destroyes listener contexts.
1508 1587   */
1509 1588  static void
1510 1589  smb_server_listener_destroy(smb_listener_daemon_t *ld)
1511 1590  {
  
    | 
      ↓ open down ↓ | 
    3 lines elided | 
    
      ↑ open up ↑ | 
  
1512 1591          /*
1513 1592           * Note that if startup fails early, we can legitimately
1514 1593           * get here with an all-zeros object.
1515 1594           */
1516 1595          if (ld->ld_magic == 0)
1517 1596                  return;
1518 1597  
1519 1598          SMB_LISTENER_VALID(ld);
1520 1599          ASSERT(ld->ld_so == NULL);
1521 1600          smb_thread_destroy(&ld->ld_thread);
1522      -        smb_llist_destructor(&ld->ld_session_list);
1523 1601          ld->ld_magic = 0;
1524 1602  }
1525 1603  
1526 1604  /*
1527 1605   * smb_server_listener_start
1528 1606   *
1529 1607   * Starts the listener associated with the context passed in.
1530 1608   *
1531 1609   * Return:      0       Success
1532 1610   *              not 0   Failure
1533 1611   */
1534 1612  static int
1535 1613  smb_server_listener_start(smb_listener_daemon_t *ld)
1536 1614  {
1537 1615          int             rc;
1538 1616          uint32_t        on;
1539 1617          uint32_t        off;
1540 1618  
1541 1619          SMB_LISTENER_VALID(ld);
1542 1620  
1543 1621          if (ld->ld_so != NULL)
1544 1622                  return (EINVAL);
1545 1623  
1546 1624          ld->ld_so = smb_socreate(ld->ld_family, SOCK_STREAM, 0);
1547 1625          if (ld->ld_so == NULL) {
1548 1626                  cmn_err(CE_WARN, "port %d: socket create failed", ld->ld_port);
1549 1627                  return (ENOMEM);
1550 1628          }
1551 1629  
1552 1630          off = 0;
1553 1631          (void) ksocket_setsockopt(ld->ld_so, SOL_SOCKET,
1554 1632              SO_MAC_EXEMPT, &off, sizeof (off), CRED());
1555 1633  
1556 1634          on = 1;
1557 1635          (void) ksocket_setsockopt(ld->ld_so, SOL_SOCKET,
1558 1636              SO_REUSEADDR, &on, sizeof (on), CRED());
1559 1637  
1560 1638          if (ld->ld_family == AF_INET) {
1561 1639                  rc = ksocket_bind(ld->ld_so,
1562 1640                      (struct sockaddr *)&ld->ld_sin,
1563 1641                      sizeof (ld->ld_sin), CRED());
1564 1642          } else {
1565 1643                  rc = ksocket_bind(ld->ld_so,
1566 1644                      (struct sockaddr *)&ld->ld_sin6,
1567 1645                      sizeof (ld->ld_sin6), CRED());
1568 1646          }
1569 1647  
1570 1648          if (rc != 0) {
1571 1649                  cmn_err(CE_WARN, "port %d: bind failed", ld->ld_port);
1572 1650                  return (rc);
1573 1651          }
1574 1652  
1575 1653          rc =  ksocket_listen(ld->ld_so, 20, CRED());
1576 1654          if (rc < 0) {
1577 1655                  cmn_err(CE_WARN, "port %d: listen failed", ld->ld_port);
1578 1656                  return (rc);
1579 1657          }
1580 1658  
1581 1659          ksocket_hold(ld->ld_so);
1582 1660          rc = smb_thread_start(&ld->ld_thread);
1583 1661          if (rc != 0) {
1584 1662                  ksocket_rele(ld->ld_so);
1585 1663                  cmn_err(CE_WARN, "port %d: listener failed to start",
1586 1664                      ld->ld_port);
1587 1665                  return (rc);
1588 1666          }
1589 1667          return (0);
1590 1668  }
1591 1669  
1592 1670  /*
1593 1671   * smb_server_listener_stop
1594 1672   *
1595 1673   * Stops the listener associated with the context passed in.
1596 1674   */
1597 1675  static void
1598 1676  smb_server_listener_stop(smb_listener_daemon_t *ld)
1599 1677  {
1600 1678          SMB_LISTENER_VALID(ld);
1601 1679  
1602 1680          if (ld->ld_so != NULL) {
1603 1681                  smb_soshutdown(ld->ld_so);
1604 1682                  smb_sodestroy(ld->ld_so);
1605 1683                  smb_thread_stop(&ld->ld_thread);
1606 1684                  ld->ld_so = NULL;
1607 1685          }
1608 1686  }
1609 1687  
  
    | 
      ↓ open down ↓ | 
    77 lines elided | 
    
      ↑ open up ↑ | 
  
1610 1688  /*
1611 1689   * smb_server_listener
1612 1690   *
1613 1691   * Entry point of the listeners.
1614 1692   */
1615 1693  static void
1616 1694  smb_server_listener(smb_thread_t *thread, void *arg)
1617 1695  {
1618 1696          _NOTE(ARGUNUSED(thread))
1619 1697          smb_listener_daemon_t   *ld;
1620      -        smb_session_t           *session;
1621 1698          ksocket_t               s_so;
1622 1699          int                     on;
1623 1700          int                     txbuf_size;
1624 1701  
1625 1702          ld = (smb_listener_daemon_t *)arg;
1626 1703  
1627 1704          SMB_LISTENER_VALID(ld);
1628 1705  
1629 1706          DTRACE_PROBE1(so__wait__accept, struct sonode *, ld->ld_so);
1630 1707  
1631      -        while (ksocket_accept(ld->ld_so, NULL, NULL, &s_so, CRED())
1632      -            == 0) {
     1708 +        for (;;) {
     1709 +                int ret = ksocket_accept(ld->ld_so, NULL, NULL, &s_so, CRED());
     1710 +
     1711 +                switch (ret) {
     1712 +                case 0:
     1713 +                        break;
     1714 +                case ECONNABORTED:
     1715 +                        continue;
     1716 +                case EINTR:
     1717 +                case EBADF:     /* libfakekernel */
     1718 +                        goto out;
     1719 +                default:
     1720 +                        cmn_err(CE_WARN,
     1721 +                            "smb_server_listener: ksocket_accept(%d)",
     1722 +                            ret);
     1723 +                        goto out;
     1724 +                }
     1725 +
1633 1726                  DTRACE_PROBE1(so__accept, struct sonode *, s_so);
1634 1727  
1635 1728                  on = 1;
1636 1729                  (void) ksocket_setsockopt(s_so, IPPROTO_TCP, TCP_NODELAY,
1637 1730                      &on, sizeof (on), CRED());
1638 1731  
1639 1732                  on = 1;
1640 1733                  (void) ksocket_setsockopt(s_so, SOL_SOCKET, SO_KEEPALIVE,
1641 1734                      &on, sizeof (on), CRED());
1642 1735  
1643 1736                  txbuf_size = 128*1024;
1644 1737                  (void) ksocket_setsockopt(s_so, SOL_SOCKET, SO_SNDBUF,
1645 1738                      (const void *)&txbuf_size, sizeof (txbuf_size), CRED());
1646 1739  
1647 1740                  /*
1648 1741                   * Create a session for this connection.
1649 1742                   */
1650 1743                  smb_server_create_session(ld, s_so);
1651 1744          }
1652      -        /* Disconnect all the sessions this listener created. */
1653      -        smb_llist_enter(&ld->ld_session_list, RW_READER);
1654      -        session = smb_llist_head(&ld->ld_session_list);
1655      -        while (session != NULL) {
1656      -                smb_session_disconnect(session);
1657      -                session = smb_llist_next(&ld->ld_session_list, session);
1658      -        }
1659      -        smb_llist_exit(&ld->ld_session_list);
     1745 +out:
1660 1746          ksocket_rele(ld->ld_so);
1661 1747  }
1662 1748  
1663 1749  /*
1664 1750   * smb_server_receiver
1665 1751   *
1666 1752   * Entry point of the receiver threads.
     1753 + * Also does cleanup when socket disconnected.
1667 1754   */
1668 1755  static void
1669 1756  smb_server_receiver(void *arg)
1670 1757  {
1671      -        smb_listener_daemon_t   *ld;
1672      -        smb_session_t           *session;
     1758 +        smb_session_t   *session;
1673 1759  
1674      -        ld = ((smb_receiver_arg_t *)arg)->ra_listener;
1675      -        session = ((smb_receiver_arg_t *)arg)->ra_session;
1676      -        smb_mem_free(arg);
     1760 +        session = (smb_session_t *)arg;
     1761 +
     1762 +        /* We stay in here until socket disconnect. */
1677 1763          smb_session_receiver(session);
1678      -        smb_server_destroy_session(ld, session);
     1764 +
     1765 +        ASSERT(session->s_state == SMB_SESSION_STATE_SHUTDOWN);
     1766 +        smb_server_destroy_session(session);
1679 1767  }
1680 1768  
1681 1769  /*
1682 1770   * smb_server_lookup
1683 1771   *
1684 1772   * This function finds the server associated with the zone of the
1685 1773   * caller.  Note: requires a fix in the dynamic taskq code:
1686 1774   * 1501 taskq_create_proc ... TQ_DYNAMIC puts tasks in p0
1687 1775   */
1688 1776  int
1689 1777  smb_server_lookup(smb_server_t **psv)
1690 1778  {
1691 1779          zoneid_t        zid;
1692 1780          smb_server_t    *sv;
1693 1781  
1694 1782          zid = getzoneid();
1695 1783  
1696 1784          smb_llist_enter(&smb_servers, RW_READER);
1697 1785          sv = smb_llist_head(&smb_servers);
1698 1786          while (sv) {
1699 1787                  SMB_SERVER_VALID(sv);
1700 1788                  if (sv->sv_zid == zid) {
1701 1789                          mutex_enter(&sv->sv_mutex);
1702 1790                          if (sv->sv_state != SMB_SERVER_STATE_DELETING) {
1703 1791                                  sv->sv_refcnt++;
1704 1792                                  mutex_exit(&sv->sv_mutex);
1705 1793                                  smb_llist_exit(&smb_servers);
1706 1794                                  *psv = sv;
1707 1795                                  return (0);
1708 1796                          }
1709 1797                          mutex_exit(&sv->sv_mutex);
1710 1798                          break;
1711 1799                  }
1712 1800                  sv = smb_llist_next(&smb_servers, sv);
1713 1801          }
1714 1802          smb_llist_exit(&smb_servers);
1715 1803          return (EPERM);
1716 1804  }
1717 1805  
1718 1806  /*
1719 1807   * smb_server_release
1720 1808   *
1721 1809   * This function decrements the reference count of the server and signals its
1722 1810   * condition variable if the state of the server is SMB_SERVER_STATE_DELETING.
1723 1811   */
1724 1812  void
1725 1813  smb_server_release(smb_server_t *sv)
1726 1814  {
1727 1815          SMB_SERVER_VALID(sv);
1728 1816  
1729 1817          mutex_enter(&sv->sv_mutex);
1730 1818          ASSERT(sv->sv_refcnt);
  
    | 
      ↓ open down ↓ | 
    42 lines elided | 
    
      ↑ open up ↑ | 
  
1731 1819          sv->sv_refcnt--;
1732 1820          if ((sv->sv_refcnt == 0) && (sv->sv_state == SMB_SERVER_STATE_DELETING))
1733 1821                  cv_signal(&sv->sv_cv);
1734 1822          mutex_exit(&sv->sv_mutex);
1735 1823  }
1736 1824  
1737 1825  /*
1738 1826   * Enumerate the users associated with a session list.
1739 1827   */
1740 1828  static void
1741      -smb_server_enum_users(smb_llist_t *ll, smb_svcenum_t *svcenum)
     1829 +smb_server_enum_users(smb_server_t *sv, smb_svcenum_t *svcenum)
1742 1830  {
     1831 +        smb_llist_t     *ll = &sv->sv_session_list;
1743 1832          smb_session_t   *sn;
1744 1833          smb_llist_t     *ulist;
1745 1834          smb_user_t      *user;
1746 1835          int             rc = 0;
1747 1836  
1748 1837          smb_llist_enter(ll, RW_READER);
1749 1838          sn = smb_llist_head(ll);
1750 1839  
1751 1840          while (sn != NULL) {
1752 1841                  SMB_SESSION_VALID(sn);
1753 1842                  ulist = &sn->s_user_list;
1754 1843                  smb_llist_enter(ulist, RW_READER);
1755 1844                  user = smb_llist_head(ulist);
1756 1845  
1757 1846                  while (user != NULL) {
1758 1847                          if (smb_user_hold(user)) {
1759 1848                                  rc = smb_user_enum(user, svcenum);
1760 1849                                  smb_user_release(user);
1761 1850                                  if (rc != 0)
1762 1851                                          break;
1763 1852                          }
1764 1853  
1765 1854                          user = smb_llist_next(ulist, user);
1766 1855                  }
1767 1856  
1768 1857                  smb_llist_exit(ulist);
1769 1858  
1770 1859                  if (rc != 0)
1771 1860                          break;
1772 1861  
  
    | 
      ↓ open down ↓ | 
    20 lines elided | 
    
      ↑ open up ↑ | 
  
1773 1862                  sn = smb_llist_next(ll, sn);
1774 1863          }
1775 1864  
1776 1865          smb_llist_exit(ll);
1777 1866  }
1778 1867  
1779 1868  /*
1780 1869   * Enumerate the trees/files associated with a session list.
1781 1870   */
1782 1871  static void
1783      -smb_server_enum_trees(smb_llist_t *ll, smb_svcenum_t *svcenum)
     1872 +smb_server_enum_trees(smb_server_t *sv, smb_svcenum_t *svcenum)
1784 1873  {
     1874 +        smb_llist_t     *ll = &sv->sv_session_list;
1785 1875          smb_session_t   *sn;
1786 1876          smb_llist_t     *tlist;
1787 1877          smb_tree_t      *tree;
1788 1878          int             rc = 0;
1789 1879  
1790 1880          smb_llist_enter(ll, RW_READER);
1791 1881          sn = smb_llist_head(ll);
1792 1882  
1793 1883          while (sn != NULL) {
1794 1884                  SMB_SESSION_VALID(sn);
1795 1885                  tlist = &sn->s_tree_list;
1796 1886                  smb_llist_enter(tlist, RW_READER);
1797 1887                  tree = smb_llist_head(tlist);
1798 1888  
1799 1889                  while (tree != NULL) {
1800 1890                          if (smb_tree_hold(tree)) {
1801 1891                                  rc = smb_tree_enum(tree, svcenum);
1802 1892                                  smb_tree_release(tree);
1803 1893                                  if (rc != 0)
1804 1894                                          break;
1805 1895                          }
1806 1896  
1807 1897                          tree = smb_llist_next(tlist, tree);
1808 1898                  }
1809 1899  
1810 1900                  smb_llist_exit(tlist);
1811 1901  
1812 1902                  if (rc != 0)
1813 1903                          break;
1814 1904  
1815 1905                  sn = smb_llist_next(ll, sn);
  
    | 
      ↓ open down ↓ | 
    21 lines elided | 
    
      ↑ open up ↑ | 
  
1816 1906          }
1817 1907  
1818 1908          smb_llist_exit(ll);
1819 1909  }
1820 1910  
1821 1911  /*
1822 1912   * Disconnect sessions associated with the specified client and username.
1823 1913   * Empty strings are treated as wildcards.
1824 1914   */
1825 1915  static int
1826      -smb_server_session_disconnect(smb_llist_t *ll,
     1916 +smb_server_session_disconnect(smb_server_t *sv,
1827 1917      const char *client, const char *name)
1828 1918  {
     1919 +        smb_llist_t     *ll = &sv->sv_session_list;
1829 1920          smb_session_t   *sn;
1830 1921          smb_llist_t     *ulist;
1831 1922          smb_user_t      *user;
1832      -        boolean_t       match;
1833 1923          int             count = 0;
1834 1924  
1835 1925          smb_llist_enter(ll, RW_READER);
1836      -        sn = smb_llist_head(ll);
1837 1926  
1838      -        while (sn != NULL) {
     1927 +        for (sn = smb_llist_head(ll);
     1928 +            sn != NULL;
     1929 +            sn = smb_llist_next(ll, sn)) {
1839 1930                  SMB_SESSION_VALID(sn);
1840 1931  
1841      -                if ((*client != '\0') && (!smb_session_isclient(sn, client))) {
1842      -                        sn = smb_llist_next(ll, sn);
     1932 +                if (*client != '\0' && !smb_session_isclient(sn, client))
1843 1933                          continue;
1844      -                }
1845 1934  
1846 1935                  ulist = &sn->s_user_list;
1847 1936                  smb_llist_enter(ulist, RW_READER);
1848      -                user = smb_llist_head(ulist);
1849 1937  
1850      -                while (user != NULL) {
1851      -                        if (smb_user_hold(user)) {
1852      -                                match = (*name == '\0');
1853      -                                if (!match)
1854      -                                        match = smb_user_namecmp(user, name);
     1938 +                for (user = smb_llist_head(ulist);
     1939 +                    user != NULL;
     1940 +                    user = smb_llist_next(ulist, user)) {
     1941 +                        SMB_USER_VALID(user);
1855 1942  
1856      -                                if (match) {
1857      -                                        smb_llist_exit(ulist);
1858      -                                        smb_user_logoff(user);
1859      -                                        ++count;
1860      -                                        smb_user_release(user);
1861      -                                        smb_llist_enter(ulist, RW_READER);
1862      -                                        user = smb_llist_head(ulist);
1863      -                                        continue;
1864      -                                }
     1943 +                        if (*name != '\0' && !smb_user_namecmp(user, name))
     1944 +                                continue;
1865 1945  
     1946 +                        if (smb_user_hold(user)) {
     1947 +                                smb_user_logoff(user);
1866 1948                                  smb_user_release(user);
     1949 +                                count++;
1867 1950                          }
1868      -
1869      -                        user = smb_llist_next(ulist, user);
1870 1951                  }
1871 1952  
1872 1953                  smb_llist_exit(ulist);
1873      -                sn = smb_llist_next(ll, sn);
1874 1954          }
1875 1955  
1876 1956          smb_llist_exit(ll);
1877 1957          return (count);
1878 1958  }
1879 1959  
1880 1960  /*
1881 1961   * Close a file by its unique id.
1882 1962   */
1883 1963  static int
1884      -smb_server_fclose(smb_llist_t *ll, uint32_t uniqid)
     1964 +smb_server_fclose(smb_server_t *sv, uint32_t uniqid)
1885 1965  {
     1966 +        smb_llist_t     *ll;
1886 1967          smb_session_t   *sn;
1887 1968          smb_llist_t     *tlist;
1888 1969          smb_tree_t      *tree;
1889 1970          int             rc = ENOENT;
1890 1971  
     1972 +        ll = &sv->sv_session_list;
1891 1973          smb_llist_enter(ll, RW_READER);
1892 1974          sn = smb_llist_head(ll);
1893 1975  
1894 1976          while ((sn != NULL) && (rc == ENOENT)) {
1895 1977                  SMB_SESSION_VALID(sn);
1896 1978                  tlist = &sn->s_tree_list;
1897 1979                  smb_llist_enter(tlist, RW_READER);
1898 1980                  tree = smb_llist_head(tlist);
1899 1981  
1900 1982                  while ((tree != NULL) && (rc == ENOENT)) {
1901 1983                          if (smb_tree_hold(tree)) {
1902 1984                                  rc = smb_tree_fclose(tree, uniqid);
1903 1985                                  smb_tree_release(tree);
1904 1986                          }
1905 1987  
1906 1988                          tree = smb_llist_next(tlist, tree);
  
    | 
      ↓ open down ↓ | 
    6 lines elided | 
    
      ↑ open up ↑ | 
  
1907 1989                  }
1908 1990  
1909 1991                  smb_llist_exit(tlist);
1910 1992                  sn = smb_llist_next(ll, sn);
1911 1993          }
1912 1994  
1913 1995          smb_llist_exit(ll);
1914 1996          return (rc);
1915 1997  }
1916 1998  
     1999 +/*
     2000 + * This is used by SMB2 session setup to find a previous session,
     2001 + * so it can force a logoff that we haven't noticed yet.
     2002 + * This is not called frequently, so we just walk the list of
     2003 + * connections searching for the user.
     2004 + */
     2005 +smb_user_t *
     2006 +smb_server_lookup_ssnid(smb_server_t *sv, uint64_t ssnid)
     2007 +{
     2008 +        smb_llist_t *sl;
     2009 +        smb_session_t *sess;
     2010 +        smb_user_t *user = NULL;
     2011 +
     2012 +        sl = &sv->sv_session_list;
     2013 +        smb_llist_enter(sl, RW_READER);
     2014 +
     2015 +        for (sess = smb_llist_head(sl);
     2016 +            sess != NULL;
     2017 +            sess = smb_llist_next(sl, sess)) {
     2018 +
     2019 +                SMB_SESSION_VALID(sess);
     2020 +
     2021 +                if (sess->dialect < SMB_VERS_2_BASE)
     2022 +                        continue;
     2023 +
     2024 +                /*
     2025 +                 * Only look in sessions that are still active.
     2026 +                 * Avoid doing an smb_rwx_rwenter sess->s_lock
     2027 +                 * on every session here, but re-check below
     2028 +                 * with s_lock held.
     2029 +                 */
     2030 +                if (sess->s_state != SMB_SESSION_STATE_NEGOTIATED)
     2031 +                        continue;
     2032 +
     2033 +                user = smb_session_lookup_ssnid(sess, ssnid);
     2034 +                if (user != NULL) {
     2035 +                        break;
     2036 +                }
     2037 +        }
     2038 +
     2039 +        smb_llist_exit(sl);
     2040 +
     2041 +        /* The sess check is warning avoidance. */
     2042 +        if (user != NULL && sess != NULL) {
     2043 +                /*
     2044 +                 * Re-check the state with s_lock held.
     2045 +                 */
     2046 +                smb_rwx_rwenter(&sess->s_lock, RW_READER);
     2047 +                if (sess->s_state != SMB_SESSION_STATE_NEGOTIATED) {
     2048 +                        smb_user_release(user);
     2049 +                        user = NULL;
     2050 +                }
     2051 +                smb_rwx_rwexit(&sess->s_lock);
     2052 +        }
     2053 +
     2054 +        return (user);
     2055 +}
     2056 +
1917 2057  /* See also: libsmb smb_kmod_setcfg */
1918 2058  static void
1919 2059  smb_server_store_cfg(smb_server_t *sv, smb_ioc_cfg_t *ioc)
1920 2060  {
1921 2061          if (ioc->maxconnections == 0)
1922 2062                  ioc->maxconnections = 0xFFFFFFFF;
1923 2063  
1924      -        smb_session_correct_keep_alive_values(
1925      -            &sv->sv_nbt_daemon.ld_session_list, ioc->keepalive);
1926      -        smb_session_correct_keep_alive_values(
1927      -            &sv->sv_tcp_daemon.ld_session_list, ioc->keepalive);
     2064 +        if (ioc->encrypt == SMB_CONFIG_REQUIRED &&
     2065 +            ioc->max_protocol < SMB_VERS_3_0) {
     2066 +                cmn_err(CE_WARN, "Server set to require encryption; "
     2067 +                    "forcing max_protocol to 3.0");
     2068 +                ioc->max_protocol = SMB_VERS_3_0;
     2069 +        }
1928 2070  
1929 2071          sv->sv_cfg.skc_maxworkers = ioc->maxworkers;
1930 2072          sv->sv_cfg.skc_maxconnections = ioc->maxconnections;
1931 2073          sv->sv_cfg.skc_keepalive = ioc->keepalive;
1932 2074          sv->sv_cfg.skc_restrict_anon = ioc->restrict_anon;
1933 2075          sv->sv_cfg.skc_signing_enable = ioc->signing_enable;
1934 2076          sv->sv_cfg.skc_signing_required = ioc->signing_required;
1935 2077          sv->sv_cfg.skc_oplock_enable = ioc->oplock_enable;
1936 2078          sv->sv_cfg.skc_sync_enable = ioc->sync_enable;
1937 2079          sv->sv_cfg.skc_secmode = ioc->secmode;
1938 2080          sv->sv_cfg.skc_netbios_enable = ioc->netbios_enable;
1939 2081          sv->sv_cfg.skc_ipv6_enable = ioc->ipv6_enable;
1940 2082          sv->sv_cfg.skc_print_enable = ioc->print_enable;
1941 2083          sv->sv_cfg.skc_traverse_mounts = ioc->traverse_mounts;
1942 2084          sv->sv_cfg.skc_max_protocol = ioc->max_protocol;
     2085 +        sv->sv_cfg.skc_min_protocol = ioc->min_protocol;
     2086 +        sv->sv_cfg.skc_encrypt = ioc->encrypt;
1943 2087          sv->sv_cfg.skc_execflags = ioc->exec_flags;
1944 2088          sv->sv_cfg.skc_negtok_len = ioc->negtok_len;
1945 2089          sv->sv_cfg.skc_version = ioc->version;
1946 2090          sv->sv_cfg.skc_initial_credits = ioc->initial_credits;
1947 2091          sv->sv_cfg.skc_maximum_credits = ioc->maximum_credits;
1948 2092  
1949 2093          (void) memcpy(sv->sv_cfg.skc_machine_uuid, ioc->machine_uuid,
1950 2094              sizeof (uuid_t));
1951 2095          (void) memcpy(sv->sv_cfg.skc_negtok, ioc->negtok,
1952 2096              sizeof (sv->sv_cfg.skc_negtok));
1953 2097          (void) memcpy(sv->sv_cfg.skc_native_os, ioc->native_os,
1954 2098              sizeof (sv->sv_cfg.skc_native_os));
1955 2099          (void) memcpy(sv->sv_cfg.skc_native_lm, ioc->native_lm,
1956 2100              sizeof (sv->sv_cfg.skc_native_lm));
1957 2101  
1958 2102          (void) strlcpy(sv->sv_cfg.skc_nbdomain, ioc->nbdomain,
1959 2103              sizeof (sv->sv_cfg.skc_nbdomain));
1960 2104          (void) strlcpy(sv->sv_cfg.skc_fqdn, ioc->fqdn,
1961 2105              sizeof (sv->sv_cfg.skc_fqdn));
1962 2106          (void) strlcpy(sv->sv_cfg.skc_hostname, ioc->hostname,
1963 2107              sizeof (sv->sv_cfg.skc_hostname));
1964 2108          (void) strlcpy(sv->sv_cfg.skc_system_comment, ioc->system_comment,
1965 2109              sizeof (sv->sv_cfg.skc_system_comment));
1966 2110  }
1967 2111  
1968 2112  static int
1969 2113  smb_server_fsop_start(smb_server_t *sv)
1970 2114  {
1971 2115          int     error;
1972 2116  
1973 2117          error = smb_node_root_init(sv, &sv->si_root_smb_node);
1974 2118          if (error != 0)
1975 2119                  sv->si_root_smb_node = NULL;
1976 2120  
1977 2121          return (error);
1978 2122  }
1979 2123  
1980 2124  static void
1981 2125  smb_server_fsop_stop(smb_server_t *sv)
1982 2126  {
1983 2127          if (sv->si_root_smb_node != NULL) {
1984 2128                  smb_node_release(sv->si_root_smb_node);
1985 2129                  sv->si_root_smb_node = NULL;
1986 2130          }
1987 2131  }
1988 2132  
1989 2133  smb_event_t *
1990 2134  smb_event_create(smb_server_t *sv, int timeout)
1991 2135  {
1992 2136          smb_event_t     *event;
1993 2137  
1994 2138          if (smb_server_is_stopping(sv))
1995 2139                  return (NULL);
1996 2140  
1997 2141          event = kmem_cache_alloc(smb_cache_event, KM_SLEEP);
1998 2142  
1999 2143          bzero(event, sizeof (smb_event_t));
2000 2144          mutex_init(&event->se_mutex, NULL, MUTEX_DEFAULT, NULL);
2001 2145          cv_init(&event->se_cv, NULL, CV_DEFAULT, NULL);
2002 2146          event->se_magic = SMB_EVENT_MAGIC;
2003 2147          event->se_txid = smb_event_alloc_txid();
2004 2148          event->se_server = sv;
2005 2149          event->se_timeout = timeout;
2006 2150  
2007 2151          smb_llist_enter(&sv->sv_event_list, RW_WRITER);
2008 2152          smb_llist_insert_tail(&sv->sv_event_list, event);
2009 2153          smb_llist_exit(&sv->sv_event_list);
2010 2154  
2011 2155          return (event);
2012 2156  }
2013 2157  
2014 2158  void
2015 2159  smb_event_destroy(smb_event_t *event)
2016 2160  {
2017 2161          smb_server_t    *sv;
2018 2162  
2019 2163          if (event == NULL)
2020 2164                  return;
2021 2165  
2022 2166          SMB_EVENT_VALID(event);
2023 2167          ASSERT(event->se_waittime == 0);
2024 2168          sv = event->se_server;
2025 2169          SMB_SERVER_VALID(sv);
2026 2170  
2027 2171          smb_llist_enter(&sv->sv_event_list, RW_WRITER);
2028 2172          smb_llist_remove(&sv->sv_event_list, event);
2029 2173          smb_llist_exit(&sv->sv_event_list);
2030 2174  
2031 2175          event->se_magic = (uint32_t)~SMB_EVENT_MAGIC;
2032 2176          cv_destroy(&event->se_cv);
2033 2177          mutex_destroy(&event->se_mutex);
2034 2178  
2035 2179          kmem_cache_free(smb_cache_event, event);
2036 2180  }
2037 2181  
2038 2182  /*
2039 2183   * Get the txid for the specified event.
2040 2184   */
2041 2185  uint32_t
2042 2186  smb_event_txid(smb_event_t *event)
2043 2187  {
2044 2188          if (event != NULL) {
2045 2189                  SMB_EVENT_VALID(event);
2046 2190                  return (event->se_txid);
2047 2191          }
2048 2192  
2049 2193          cmn_err(CE_NOTE, "smb_event_txid failed");
2050 2194          return ((uint32_t)-1);
2051 2195  }
2052 2196  
2053 2197  /*
2054 2198   * Wait for event notification.
2055 2199   */
2056 2200  int
2057 2201  smb_event_wait(smb_event_t *event)
2058 2202  {
2059 2203          int     seconds = 1;
2060 2204          int     ticks;
2061 2205          int     err;
2062 2206  
2063 2207          if (event == NULL)
2064 2208                  return (EINVAL);
2065 2209  
2066 2210          SMB_EVENT_VALID(event);
2067 2211  
2068 2212          mutex_enter(&event->se_mutex);
2069 2213          event->se_waittime = 1;
2070 2214          event->se_errno = 0;
2071 2215  
2072 2216          while (!(event->se_notified)) {
2073 2217                  if (smb_event_debug && ((event->se_waittime % 30) == 0))
2074 2218                          cmn_err(CE_NOTE, "smb_event_wait[%d] (%d sec)",
2075 2219                              event->se_txid, event->se_waittime);
2076 2220  
2077 2221                  if (event->se_errno != 0)
2078 2222                          break;
2079 2223  
2080 2224                  if (event->se_waittime > event->se_timeout) {
2081 2225                          event->se_errno = ETIME;
2082 2226                          break;
2083 2227                  }
2084 2228  
2085 2229                  ticks = SEC_TO_TICK(seconds);
2086 2230                  (void) cv_reltimedwait(&event->se_cv,
2087 2231                      &event->se_mutex, (clock_t)ticks, TR_CLOCK_TICK);
2088 2232                  ++event->se_waittime;
2089 2233          }
2090 2234  
2091 2235          err = event->se_errno;
2092 2236          event->se_waittime = 0;
2093 2237          event->se_notified = B_FALSE;
2094 2238          cv_signal(&event->se_cv);
2095 2239          mutex_exit(&event->se_mutex);
2096 2240          return (err);
2097 2241  }
2098 2242  
2099 2243  /*
2100 2244   * If txid is non-zero, cancel the specified event.
2101 2245   * Otherwise, cancel all events.
2102 2246   */
2103 2247  static void
2104 2248  smb_event_cancel(smb_server_t *sv, uint32_t txid)
2105 2249  {
2106 2250          smb_event_t     *event;
2107 2251          smb_llist_t     *event_list;
2108 2252  
2109 2253          SMB_SERVER_VALID(sv);
2110 2254  
2111 2255          event_list = &sv->sv_event_list;
2112 2256          smb_llist_enter(event_list, RW_WRITER);
2113 2257  
2114 2258          event = smb_llist_head(event_list);
2115 2259          while (event) {
2116 2260                  SMB_EVENT_VALID(event);
2117 2261  
2118 2262                  if (txid == 0 || event->se_txid == txid) {
2119 2263                          mutex_enter(&event->se_mutex);
2120 2264                          event->se_errno = ECANCELED;
2121 2265                          event->se_notified = B_TRUE;
2122 2266                          cv_signal(&event->se_cv);
2123 2267                          mutex_exit(&event->se_mutex);
2124 2268  
2125 2269                          if (txid != 0)
2126 2270                                  break;
2127 2271                  }
2128 2272  
2129 2273                  event = smb_llist_next(event_list, event);
2130 2274          }
2131 2275  
2132 2276          smb_llist_exit(event_list);
2133 2277  }
2134 2278  
2135 2279  /*
2136 2280   * If txid is non-zero, notify the specified event.
2137 2281   * Otherwise, notify all events.
2138 2282   */
2139 2283  void
2140 2284  smb_event_notify(smb_server_t *sv, uint32_t txid)
2141 2285  {
2142 2286          smb_event_t     *event;
2143 2287          smb_llist_t     *event_list;
2144 2288  
2145 2289          SMB_SERVER_VALID(sv);
2146 2290  
2147 2291          event_list = &sv->sv_event_list;
2148 2292          smb_llist_enter(event_list, RW_READER);
2149 2293  
2150 2294          event = smb_llist_head(event_list);
2151 2295          while (event) {
2152 2296                  SMB_EVENT_VALID(event);
2153 2297  
2154 2298                  if (txid == 0 || event->se_txid == txid) {
2155 2299                          mutex_enter(&event->se_mutex);
2156 2300                          event->se_notified = B_TRUE;
2157 2301                          cv_signal(&event->se_cv);
2158 2302                          mutex_exit(&event->se_mutex);
2159 2303  
2160 2304                          if (txid != 0)
2161 2305                                  break;
2162 2306                  }
2163 2307  
2164 2308                  event = smb_llist_next(event_list, event);
2165 2309          }
2166 2310  
2167 2311          smb_llist_exit(event_list);
2168 2312  }
2169 2313  
2170 2314  /*
2171 2315   * Allocate a new transaction id (txid).
2172 2316   *
2173 2317   * 0 or -1 are not assigned because they are used to detect invalid
2174 2318   * conditions or to indicate all open id's.
2175 2319   */
2176 2320  static uint32_t
2177 2321  smb_event_alloc_txid(void)
2178 2322  {
2179 2323          static kmutex_t txmutex;
2180 2324          static uint32_t txid;
2181 2325          uint32_t        txid_ret;
2182 2326  
2183 2327          mutex_enter(&txmutex);
2184 2328  
2185 2329          if (txid == 0)
2186 2330                  txid = ddi_get_lbolt() << 11;
2187 2331  
2188 2332          do {
2189 2333                  ++txid;
2190 2334          } while (txid == 0 || txid == (uint32_t)-1);
2191 2335  
2192 2336          txid_ret = txid;
2193 2337          mutex_exit(&txmutex);
2194 2338  
2195 2339          return (txid_ret);
2196 2340  }
2197 2341  
2198 2342  /*
2199 2343   * Called by the ioctl to find the corresponding
2200 2344   * spooldoc node.  removes node on success
2201 2345   *
2202 2346   * Return values
2203 2347   * rc
2204 2348   * B_FALSE - not found
2205 2349   * B_TRUE  - found
2206 2350   *
2207 2351   */
2208 2352  
2209 2353  static boolean_t
2210 2354  smb_spool_lookup_doc_byfid(smb_server_t *sv, uint16_t fid,
2211 2355      smb_kspooldoc_t *spdoc)
2212 2356  {
2213 2357          smb_kspooldoc_t *sp;
2214 2358          smb_llist_t     *splist;
2215 2359  
2216 2360          splist = &sv->sp_info.sp_list;
2217 2361          smb_llist_enter(splist, RW_WRITER);
2218 2362          sp = smb_llist_head(splist);
2219 2363          while (sp != NULL) {
2220 2364                  /*
2221 2365                   * check for a matching fid
2222 2366                   */
2223 2367                  if (sp->sd_fid == fid) {
2224 2368                          *spdoc = *sp;
2225 2369                          smb_llist_remove(splist, sp);
2226 2370                          smb_llist_exit(splist);
2227 2371                          kmem_free(sp, sizeof (smb_kspooldoc_t));
2228 2372                          return (B_TRUE);
2229 2373                  }
2230 2374                  sp = smb_llist_next(splist, sp);
2231 2375          }
2232 2376          cmn_err(CE_WARN, "smb_spool_lookup_user_byfid: no fid:%d", fid);
2233 2377          smb_llist_exit(splist);
2234 2378          return (B_FALSE);
2235 2379  }
2236 2380  
2237 2381  /*
2238 2382   * Adds the spool fid to a linked list to be used
2239 2383   * as a search key in the spooldoc queue
2240 2384   *
2241 2385   * Return values
2242 2386   *      rc non-zero error
2243 2387   *      rc zero success
2244 2388   *
2245 2389   */
2246 2390  
2247 2391  void
2248 2392  smb_spool_add_fid(smb_server_t *sv, uint16_t fid)
2249 2393  {
2250 2394          smb_llist_t     *fidlist;
2251 2395          smb_spoolfid_t  *sf;
2252 2396  
2253 2397          if (sv->sv_cfg.skc_print_enable == 0)
2254 2398                  return;
2255 2399  
2256 2400          sf = kmem_zalloc(sizeof (smb_spoolfid_t), KM_SLEEP);
2257 2401          fidlist = &sv->sp_info.sp_fidlist;
2258 2402          smb_llist_enter(fidlist, RW_WRITER);
2259 2403          sf->sf_fid = fid;
2260 2404          smb_llist_insert_tail(fidlist, sf);
2261 2405          smb_llist_exit(fidlist);
2262 2406          cv_broadcast(&sv->sp_info.sp_cv);
2263 2407  }
2264 2408  
2265 2409  /*
2266 2410   * Called by the ioctl to get and remove the head of the fid list
2267 2411   *
2268 2412   * Return values
2269 2413   * int fd
2270 2414   * greater than 0 success
2271 2415   * 0 - error
2272 2416   *
2273 2417   */
2274 2418  
2275 2419  static uint16_t
2276 2420  smb_spool_get_fid(smb_server_t *sv)
2277 2421  {
2278 2422          smb_spoolfid_t  *spfid;
2279 2423          smb_llist_t     *splist;
2280 2424          uint16_t        fid;
2281 2425  
2282 2426          splist = &sv->sp_info.sp_fidlist;
2283 2427          smb_llist_enter(splist, RW_WRITER);
2284 2428          spfid = smb_llist_head(splist);
2285 2429          if (spfid != NULL) {
2286 2430                  fid = spfid->sf_fid;
2287 2431                  smb_llist_remove(&sv->sp_info.sp_fidlist, spfid);
2288 2432                  kmem_free(spfid, sizeof (smb_spoolfid_t));
2289 2433          } else {
2290 2434                  fid = 0;
2291 2435          }
2292 2436          smb_llist_exit(splist);
2293 2437          return (fid);
2294 2438  }
2295 2439  
2296 2440  /*
2297 2441   * Adds the spooldoc to the tail of the spooldoc list
2298 2442   *
2299 2443   * Return values
2300 2444   *      rc non-zero error
2301 2445   *      rc zero success
2302 2446   */
2303 2447  int
2304 2448  smb_spool_add_doc(smb_tree_t *tree, smb_kspooldoc_t *sp)
2305 2449  {
2306 2450          smb_llist_t     *splist;
2307 2451          smb_server_t    *sv = tree->t_server;
2308 2452          int rc = 0;
2309 2453  
2310 2454          splist = &sv->sp_info.sp_list;
2311 2455          smb_llist_enter(splist, RW_WRITER);
2312 2456          sp->sd_spool_num = atomic_inc_32_nv(&sv->sp_info.sp_cnt);
2313 2457          smb_llist_insert_tail(splist, sp);
2314 2458          smb_llist_exit(splist);
2315 2459  
  
    | 
      ↓ open down ↓ | 
    363 lines elided | 
    
      ↑ open up ↑ | 
  
2316 2460          return (rc);
2317 2461  }
2318 2462  
2319 2463  /*
2320 2464   * smb_server_create_session
2321 2465   */
2322 2466  static void
2323 2467  smb_server_create_session(smb_listener_daemon_t *ld, ksocket_t s_so)
2324 2468  {
2325 2469          smb_session_t           *session;
2326      -        smb_receiver_arg_t      *rarg;
2327 2470          taskqid_t               tqid;
     2471 +        smb_llist_t             *sl;
     2472 +        smb_server_t            *sv = ld->ld_sv;
2328 2473  
2329      -        session = smb_session_create(s_so, ld->ld_port, ld->ld_sv,
     2474 +        session = smb_session_create(s_so, ld->ld_port, sv,
2330 2475              ld->ld_family);
2331 2476  
2332 2477          if (session == NULL) {
2333 2478                  smb_soshutdown(s_so);
2334 2479                  smb_sodestroy(s_so);
2335 2480                  cmn_err(CE_WARN, "SMB Session: alloc failed");
2336 2481                  return;
2337 2482          }
2338 2483  
2339      -        smb_llist_enter(&ld->ld_session_list, RW_WRITER);
2340      -        smb_llist_insert_tail(&ld->ld_session_list, session);
2341      -        smb_llist_exit(&ld->ld_session_list);
     2484 +        sl = &sv->sv_session_list;
     2485 +        smb_llist_enter(sl, RW_WRITER);
     2486 +        smb_llist_insert_tail(sl, session);
     2487 +        smb_llist_exit(sl);
2342 2488  
2343      -        rarg = (smb_receiver_arg_t *)smb_mem_alloc(
2344      -            sizeof (smb_receiver_arg_t));
2345      -        rarg->ra_listener = ld;
2346      -        rarg->ra_session = session;
2347      -
2348 2489          /*
2349 2490           * These taskq entries must run independently of one another,
2350 2491           * so TQ_NOQUEUE.  TQ_SLEEP (==0) just for clarity.
2351 2492           */
2352      -        tqid = taskq_dispatch(ld->ld_sv->sv_receiver_pool,
2353      -            smb_server_receiver, rarg, TQ_NOQUEUE | TQ_SLEEP);
     2493 +        tqid = taskq_dispatch(sv->sv_receiver_pool,
     2494 +            smb_server_receiver, session, TQ_NOQUEUE | TQ_SLEEP);
2354 2495          if (tqid == 0) {
2355      -                smb_mem_free(rarg);
2356 2496                  smb_session_disconnect(session);
2357      -                smb_server_destroy_session(ld, session);
     2497 +                smb_server_destroy_session(session);
2358 2498                  cmn_err(CE_WARN, "SMB Session: taskq_dispatch failed");
2359 2499                  return;
2360 2500          }
2361 2501          /* handy for debugging */
2362 2502          session->s_receiver_tqid = tqid;
2363 2503  }
2364 2504  
2365 2505  static void
2366      -smb_server_destroy_session(smb_listener_daemon_t *ld, smb_session_t *session)
     2506 +smb_server_destroy_session(smb_session_t *session)
2367 2507  {
2368      -        smb_llist_enter(&ld->ld_session_list, RW_WRITER);
2369      -        smb_llist_remove(&ld->ld_session_list, session);
2370      -        smb_llist_exit(&ld->ld_session_list);
     2508 +        smb_server_t *sv;
     2509 +        smb_llist_t *ll;
     2510 +        uint32_t count;
     2511 +
     2512 +        ASSERT(session->s_server != NULL);
     2513 +        sv = session->s_server;
     2514 +        ll = &sv->sv_session_list;
     2515 +
     2516 +        smb_llist_flush(&session->s_tree_list);
     2517 +        smb_llist_flush(&session->s_user_list);
     2518 +
     2519 +        /*
     2520 +         * The user and tree lists should be empty now.
     2521 +         */
     2522 +#ifdef DEBUG
     2523 +        if (session->s_user_list.ll_count != 0) {
     2524 +                cmn_err(CE_WARN, "user list not empty?");
     2525 +                debug_enter("s_user_list");
     2526 +        }
     2527 +        if (session->s_tree_list.ll_count != 0) {
     2528 +                cmn_err(CE_WARN, "tree list not empty?");
     2529 +                debug_enter("s_tree_list");
     2530 +        }
     2531 +#endif
     2532 +
     2533 +        smb_llist_enter(ll, RW_WRITER);
     2534 +        smb_llist_remove(ll, session);
     2535 +        count = ll->ll_count;
     2536 +        smb_llist_exit(ll);
     2537 +
2371 2538          smb_session_delete(session);
     2539 +        if (count == 0) {
     2540 +                /* See smb_server_shutdown */
     2541 +                cv_signal(&sv->sv_cv);
     2542 +        }
2372 2543  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX