Print this page
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-15958 panic importing CA share after failover
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Include in backports of:
  NEX-9808 SMB3 persistent handles
NEX-15958 panic importing CA share after failover
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Include in backports of:
  NEX-9808 SMB3 persistent handles
NEX-9808 SMB3 persistent handles
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-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-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-7490 read_kstat_data panic in smb_named_kstat_update
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexent.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-6308 namespace collision for per-share kstats when changing sharesmb property
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-6266 SMB kstats namespace collision for share names longer than 28 characters (follow-up)
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-6266 SMB kstats namespace collision for share names longer than 28 characters
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
NEX-5175 want SMB statistics separately for reads, writes, other
Reviewed by: Gordon Ross <gwr@nexenta.com>
Reviewed by: Matt Barden <Matt.Barden@nexenta.com>
NEX-4844 assertion failed: kshare->shr_magic == SMB_SHARE_MAGIC
Reviewed by: Gordon Ross <gwr@nexenta.com>
NEX-4313 want iops, bandwidth, and latency kstats for smb
Portions contributed by: Gordon Ross <gwr@nexenta.com>
Reviewed by: Matt Barden <Matt.Barden@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
NEX-3863 Would like an SMB share property to enable/disable quotas
Reviewed by: Bayard Bell <bayard.bell@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
SMB-74 Process oplock breaks as session requests
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 (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
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

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/smbsrv/smb_kshare.c
          +++ new/usr/src/uts/common/fs/smbsrv/smb_kshare.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  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  /*
  23   23   * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  24      - * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
       24 + * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
  25   25   * Copyright 2017 Joyent, Inc.
  26   26   */
  27   27  
  28   28  #include <smbsrv/smb_door.h>
  29      -#include <smbsrv/smb_kproto.h>
  30   29  #include <smbsrv/smb_ktypes.h>
       30 +#include <smbsrv/smb2_kproto.h>
       31 +#include <smbsrv/smb_kstat.h>
  31   32  
  32   33  typedef struct smb_unshare {
  33   34          list_node_t     us_lnd;
  34   35          char            us_sharename[MAXNAMELEN];
  35   36  } smb_unshare_t;
  36   37  
  37   38  static kmem_cache_t     *smb_kshare_cache_share;
  38   39  static kmem_cache_t     *smb_kshare_cache_unexport;
  39      -kmem_cache_t    *smb_kshare_cache_vfs;
  40   40  
  41   41  static int smb_kshare_cmp(const void *, const void *);
  42   42  static void smb_kshare_hold(const void *);
  43   43  static boolean_t smb_kshare_rele(const void *);
  44   44  static void smb_kshare_destroy(void *);
  45   45  static char *smb_kshare_oemname(const char *);
  46   46  static int smb_kshare_is_special(const char *);
  47   47  static boolean_t smb_kshare_is_admin(const char *);
  48   48  static smb_kshare_t *smb_kshare_decode(nvlist_t *);
  49   49  static uint32_t smb_kshare_decode_bool(nvlist_t *, const char *, uint32_t);
  50   50  static void smb_kshare_unexport_thread(smb_thread_t *, void *);
  51   51  static int smb_kshare_export(smb_server_t *, smb_kshare_t *);
  52   52  static int smb_kshare_unexport(smb_server_t *, const char *);
  53   53  static int smb_kshare_export_trans(smb_server_t *, char *, char *, char *);
  54   54  static void smb_kshare_csc_flags(smb_kshare_t *, const char *);
       55 +static int smb_named_kstat_update(kstat_t *ks, int rw);
       56 +static int smb_kshare_kstat_update(kstat_t *, int);
       57 +void kshare_stats_init(smb_server_t *, smb_kshare_t *);
       58 +void kshare_stats_fini(smb_kshare_t *);
  55   59  
  56   60  static boolean_t smb_export_isready(smb_server_t *);
  57   61  
  58   62  #ifdef  _KERNEL
  59   63  static int smb_kshare_chk_dsrv_status(int, smb_dr_ctx_t *);
  60   64  #endif  /* _KERNEL */
  61   65  
  62   66  static const smb_avl_nops_t smb_kshare_avlops = {
  63   67          smb_kshare_cmp,
  64   68          smb_kshare_hold,
↓ open down ↓ 222 lines elided ↑ open up ↑
 287  291  {
 288  292          mutex_enter(&sv->sv_export.e_mutex);
 289  293          if (!sv->sv_export.e_ready) {
 290  294                  mutex_exit(&sv->sv_export.e_mutex);
 291  295                  return;
 292  296          }
 293  297          sv->sv_export.e_ready = B_FALSE;
 294  298          mutex_exit(&sv->sv_export.e_mutex);
 295  299  
 296  300          smb_avl_destroy(&sv->sv_export.e_share_avl);
 297      -        smb_vfs_rele_all(&sv->sv_export);
 298  301  }
 299  302  
 300  303  void
 301  304  smb_kshare_g_init(void)
 302  305  {
 303  306          smb_kshare_cache_share = kmem_cache_create("smb_share_cache",
 304  307              sizeof (smb_kshare_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 305  308  
 306  309          smb_kshare_cache_unexport = kmem_cache_create("smb_unexport_cache",
 307  310              sizeof (smb_unshare_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 308      -
 309      -        smb_kshare_cache_vfs = kmem_cache_create("smb_vfs_cache",
 310      -            sizeof (smb_vfs_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 311  311  }
 312  312  
 313  313  void
 314  314  smb_kshare_init(smb_server_t *sv)
 315  315  {
 316  316  
 317      -        smb_llist_constructor(&sv->sv_export.e_vfs_list, sizeof (smb_vfs_t),
 318      -            offsetof(smb_vfs_t, sv_lnd));
 319      -
 320  317          smb_slist_constructor(&sv->sv_export.e_unexport_list,
 321  318              sizeof (smb_unshare_t), offsetof(smb_unshare_t, us_lnd));
 322  319  }
 323  320  
 324  321  int
 325  322  smb_kshare_start(smb_server_t *sv)
 326  323  {
 327  324          smb_thread_init(&sv->sv_export.e_unexport_thread, "smb_kshare_unexport",
 328  325              smb_kshare_unexport_thread, sv, smbsrv_base_pri);
 329  326  
↓ open down ↓ 11 lines elided ↑ open up ↑
 341  338  smb_kshare_fini(smb_server_t *sv)
 342  339  {
 343  340          smb_unshare_t *ux;
 344  341  
 345  342          while ((ux = list_head(&sv->sv_export.e_unexport_list.sl_list))
 346  343              != NULL) {
 347  344                  smb_slist_remove(&sv->sv_export.e_unexport_list, ux);
 348  345                  kmem_cache_free(smb_kshare_cache_unexport, ux);
 349  346          }
 350  347          smb_slist_destructor(&sv->sv_export.e_unexport_list);
 351      -
 352      -        smb_vfs_rele_all(&sv->sv_export);
 353      -
 354      -        smb_llist_destructor(&sv->sv_export.e_vfs_list);
 355  348  }
 356  349  
 357  350  void
 358  351  smb_kshare_g_fini(void)
 359  352  {
 360  353          kmem_cache_destroy(smb_kshare_cache_unexport);
 361  354          kmem_cache_destroy(smb_kshare_cache_share);
 362      -        kmem_cache_destroy(smb_kshare_cache_vfs);
 363  355  }
 364  356  
 365  357  /*
 366  358   * A list of shares in nvlist format can be sent down
 367  359   * from userspace thourgh the IOCTL interface. The nvlist
 368  360   * is unpacked here and all the shares in the list will
 369  361   * be exported.
 370  362   */
 371  363  int
 372  364  smb_kshare_export_list(smb_ioc_share_t *ioc)
↓ open down ↓ 303 lines elided ↑ open up ↑
 676  668  smb_kshare_release(smb_server_t *sv, smb_kshare_t *shr)
 677  669  {
 678  670          ASSERT(shr);
 679  671          ASSERT(shr->shr_magic == SMB_SHARE_MAGIC);
 680  672  
 681  673          smb_avl_release(&sv->sv_export.e_share_avl, shr);
 682  674  }
 683  675  
 684  676  /*
 685  677   * Add the given share in the specified server.
 686      - * If the share is a disk share, smb_vfs_hold() is
 687      - * invoked to ensure that there is a hold on the
 688      - * corresponding file system before the share is
 689      - * added to shares AVL.
      678 + * If the share is a disk share, lookup the share path
      679 + * and hold the smb_node_t for the share root.
 690  680   *
 691  681   * If the share is an Autohome share and it is
 692  682   * already in the AVL only a reference count for
 693  683   * that share is incremented.
 694  684   */
 695  685  static int
 696  686  smb_kshare_export(smb_server_t *sv, smb_kshare_t *shr)
 697  687  {
 698  688          smb_avl_t       *share_avl;
 699  689          smb_kshare_t    *auto_shr;
 700      -        vnode_t         *vp;
      690 +        smb_node_t      *snode = NULL;
 701  691          int             rc = 0;
 702  692  
 703  693          share_avl = &sv->sv_export.e_share_avl;
 704  694  
 705  695          if (!STYPE_ISDSK(shr->shr_type)) {
 706  696                  if ((rc = smb_avl_add(share_avl, shr)) != 0) {
 707  697                          cmn_err(CE_WARN, "export[%s]: failed caching (%d)",
 708  698                              shr->shr_name, rc);
 709  699                  }
 710  700  
 711  701                  return (rc);
 712  702          }
 713  703  
 714  704          if ((auto_shr = smb_avl_lookup(share_avl, shr)) != NULL) {
 715      -                if ((auto_shr->shr_flags & SMB_SHRF_AUTOHOME) == 0) {
 716      -                        smb_avl_release(share_avl, auto_shr);
 717      -                        return (EEXIST);
      705 +                rc = EEXIST;
      706 +                if ((auto_shr->shr_flags & SMB_SHRF_AUTOHOME) != 0) {
      707 +                        mutex_enter(&auto_shr->shr_mutex);
      708 +                        auto_shr->shr_autocnt++;
      709 +                        mutex_exit(&auto_shr->shr_mutex);
      710 +                        rc = 0;
 718  711                  }
 719      -
 720      -                mutex_enter(&auto_shr->shr_mutex);
 721      -                auto_shr->shr_autocnt++;
 722      -                mutex_exit(&auto_shr->shr_mutex);
 723  712                  smb_avl_release(share_avl, auto_shr);
 724      -                return (0);
      713 +                return (rc);
 725  714          }
 726  715  
 727      -        if ((rc = smb_server_sharevp(sv, shr->shr_path, &vp)) != 0) {
 728      -                cmn_err(CE_WARN, "export[%s(%s)]: failed obtaining vnode (%d)",
      716 +        /*
      717 +         * Get the root smb_node_t for this share, held.
      718 +         * This hold is normally released during AVL destroy,
      719 +         * via the element destructor:  smb_kshare_destroy
      720 +         */
      721 +        rc = smb_server_share_lookup(sv, shr->shr_path, &snode);
      722 +        if (rc != 0) {
      723 +                cmn_err(CE_WARN, "export[%s(%s)]: lookup failed (%d)",
 729  724                      shr->shr_name, shr->shr_path, rc);
 730  725                  return (rc);
 731  726          }
 732  727  
 733      -        if ((rc = smb_vfs_hold(&sv->sv_export, vp->v_vfsp)) == 0) {
 734      -                if ((rc = smb_avl_add(share_avl, shr)) != 0) {
 735      -                        cmn_err(CE_WARN, "export[%s]: failed caching (%d)",
 736      -                            shr->shr_name, rc);
 737      -                        smb_vfs_rele(&sv->sv_export, vp->v_vfsp);
      728 +        shr->shr_root_node = snode;
      729 +        if ((rc = smb_avl_add(share_avl, shr)) != 0) {
      730 +                cmn_err(CE_WARN, "export[%s]: failed caching (%d)",
      731 +                    shr->shr_name, rc);
      732 +                shr->shr_root_node = NULL;
      733 +                smb_node_release(snode);
      734 +                return (rc);
      735 +        }
      736 +
      737 +        kshare_stats_init(sv, shr);
      738 +
      739 +        /*
      740 +         * For CA shares, find or create the CA handle dir,
      741 +         * and (if restarted) import persistent handles.
      742 +         */
      743 +        if ((shr->shr_flags & SMB_SHRF_CA) != 0) {
      744 +                rc = smb2_dh_new_ca_share(sv, shr);
      745 +                if (rc != 0) {
      746 +                        /* Just make it a non-CA share. */
      747 +                        mutex_enter(&shr->shr_mutex);
      748 +                        shr->shr_flags &= ~SMB_SHRF_CA;
      749 +                        mutex_exit(&shr->shr_mutex);
      750 +                        rc = 0;
 738  751                  }
 739      -        } else {
 740      -                cmn_err(CE_WARN, "export[%s(%s)]: failed holding VFS (%d)",
 741      -                    shr->shr_name, shr->shr_path, rc);
 742  752          }
 743  753  
 744      -        VN_RELE(vp);
 745  754          return (rc);
 746  755  }
 747  756  
      757 +
 748  758  /*
      759 + * Following a pattern somewhat similar to smb_server_kstat_init,
      760 + * but organized a little differently.
      761 + */
      762 +void
      763 +kshare_stats_init(smb_server_t *sv, smb_kshare_t *ks)
      764 +{
      765 +        static const char       *kr_names[] = SMBSRV_CLSH__NAMES;
      766 +        char                    ks_name[KSTAT_STRLEN];
      767 +        smbsrv_clsh_kstats_t    *ksr;
      768 +        int                     idx;
      769 +        smb_named_stats_t       *smbnsp;
      770 +        kstat_t                 *kstat = NULL;
      771 +        int                     namelen;
      772 +
      773 +        /*
      774 +         * Most share names are short, and we'd like to allow consumers like
      775 +         * the smbstat command to compose the kstat names for short share names
      776 +         * directly.  In the (rare) case where we have longer share names, we
      777 +         * need an indirection scheme to get around the limited (31 chars) size
      778 +         * of kstat names. So for share names 24 chars or shorter, we compose
      779 +         * the kstat name directly as "smbsrv:0:sh/sharename" and when the share
      780 +         * name is longer, compose the kstat name using an arbitrary
      781 +         * (but unique) identifier like: "smbsrv:0:sh/:ffffff0009560a98".  To
      782 +         * find the unique identifier given a (long) share name, the consumer
      783 +         * has to enumerate the (fake) "smbsrvshr" kstat module, looking for the
      784 +         * kstat with the sharename element matching the one they want.  Both
      785 +         * direct and indirect names are instantiated under the "smbsrvshr"
      786 +         * module, so a consumer that wants all the share kstats could always
      787 +         * lookup the kstat names using the indirection scheme if that's easier.
      788 +         * (Nothing forces the consumer to directly compose kstat names when the
      789 +         * share name happens to be short -- they can always enumerate to find
      790 +         * it.)
      791 +         *
      792 +         * SMB share names are not allowed to contain a colon.  The naming
      793 +         * scheme here uses a colon at the beginning of what would otherwise be
      794 +         * the share name part of the kstat name to indicate that this name uses
      795 +         * the "indirection" scheme.  With indirection, the part after the colon
      796 +         * is an arbitrary (but unique per share) identifier of some other
      797 +         * kstat, and a consumer needs to fetch that kstat to get the real share
      798 +         * name.
      799 +         */
      800 +        namelen = strlen(ks->shr_name);
      801 +        if (namelen <= 24) {
      802 +                (void) snprintf(ks_name, sizeof (ks_name), "sh/%s",
      803 +                    ks->shr_name);
      804 +
      805 +                kstat = kstat_hold_byname("smbsrvshr", 0, ks_name, sv->sv_zid);
      806 +        }
      807 +
      808 +        if (namelen > 24 || kstat != NULL) {
      809 +                (void) snprintf(ks_name, sizeof (ks_name), "sh/:%p",
      810 +                    (void *)ks);
      811 +
      812 +                if (kstat != NULL)
      813 +                        kstat_rele(kstat);
      814 +        }
      815 +
      816 +        ks->shr_ksp = kstat_create_zone(SMBSRV_KSTAT_MODULE, 0,
      817 +            ks_name, SMBSRV_KSTAT_CLASS, KSTAT_TYPE_RAW,
      818 +            sizeof (smbsrv_clsh_kstats_t), 0, sv->sv_zid);
      819 +
      820 +        if (ks->shr_ksp == NULL)
      821 +                return;
      822 +
      823 +        ks->stats.ksns = kstat_create_zone("smbsrvshr", 0,
      824 +            ks_name, SMBSRV_KSTAT_CLASS, KSTAT_TYPE_NAMED,
      825 +            0, KSTAT_FLAG_VIRTUAL, sv->sv_zid);
      826 +
      827 +        if (ks->stats.ksns == NULL) {
      828 +                kstat_delete(ks->shr_ksp);
      829 +                ks->shr_ksp = NULL;
      830 +                return;
      831 +        }
      832 +
      833 +        ks->shr_ksp->ks_update = smb_kshare_kstat_update;
      834 +        ks->shr_ksp->ks_private = ks;
      835 +
      836 +        /*
      837 +         * In-line equivalent of smb_dispatch_stats_init
      838 +         */
      839 +        ksr = (smbsrv_clsh_kstats_t *)ks->shr_ksp->ks_data;
      840 +        for (idx = 0; idx < SMBSRV_CLSH__NREQ; idx++) {
      841 +                smb_latency_init(&ks->shr_stats[idx].sdt_lat);
      842 +                (void) strlcpy(ksr->ks_clsh[idx].kr_name, kr_names[idx],
      843 +                    KSTAT_STRLEN);
      844 +        }
      845 +
      846 +        /*
      847 +         * SMB named kstats setup for > KSTAT_STRLEN name to short name mapping.
      848 +         */
      849 +        smbnsp = &ks->stats.ks_data;
      850 +        ks->stats.ksns->ks_data = &ks->stats.ks_data;
      851 +        ks->stats.ksns->ks_data_size = sizeof (ks->stats.ks_data);
      852 +        ks->stats.ksns->ks_ndata = 1;
      853 +        kstat_named_init(smbnsp->kn, "share name",
      854 +            KSTAT_DATA_STRING);
      855 +        ks->stats.ksns->ks_update = smb_named_kstat_update;
      856 +        ks->stats.ksns->ks_private = (void *)ks;
      857 +
      858 +        kstat_install(ks->shr_ksp);
      859 +        kstat_install(ks->stats.ksns);
      860 +}
      861 +
      862 +void
      863 +kshare_stats_fini(smb_kshare_t *ks)
      864 +{
      865 +        int idx;
      866 +
      867 +        for (idx = 0; idx < SMBSRV_CLSH__NREQ; idx++)
      868 +                smb_latency_destroy(&ks->shr_stats[idx].sdt_lat);
      869 +}
      870 +
      871 +static int
      872 +smb_named_kstat_update(kstat_t *ks, int rw)
      873 +{
      874 +        smb_kshare_t            *smbksp = (smb_kshare_t *)ks->ks_private;
      875 +        smb_named_stats_t       *smbnsp = &smbksp->stats.ks_data;
      876 +
      877 +        if (rw == KSTAT_READ) {
      878 +                (void) strlcpy(smbnsp->name, smbksp->shr_name,
      879 +                    sizeof (smbnsp->name));
      880 +
      881 +                kstat_named_setstr(&smbnsp->kn[0],
      882 +                    (const char *)smbksp->shr_name);
      883 +        }
      884 +        return (0);
      885 +}
      886 +
      887 +/*
      888 + * Update the kstat data from our private stats.
      889 + */
      890 +static int
      891 +smb_kshare_kstat_update(kstat_t *ksp, int rw)
      892 +{
      893 +        smb_kshare_t *kshare;
      894 +        smb_disp_stats_t *sds;
      895 +        smbsrv_clsh_kstats_t    *clsh;
      896 +        smb_kstat_req_t *ksr;
      897 +        int i;
      898 +
      899 +        if (rw == KSTAT_WRITE)
      900 +                return (EACCES);
      901 +
      902 +        kshare = ksp->ks_private;
      903 +        ASSERT(kshare->shr_magic == SMB_SHARE_MAGIC);
      904 +        sds = kshare->shr_stats;
      905 +
      906 +        clsh = (smbsrv_clsh_kstats_t *)ksp->ks_data;
      907 +        ksr = clsh->ks_clsh;
      908 +
      909 +        for (i = 0; i < SMBSRV_CLSH__NREQ; i++, ksr++, sds++) {
      910 +                ksr->kr_rxb = sds->sdt_rxb;
      911 +                ksr->kr_txb = sds->sdt_txb;
      912 +                mutex_enter(&sds->sdt_lat.ly_mutex);
      913 +                ksr->kr_nreq = sds->sdt_lat.ly_a_nreq;
      914 +                ksr->kr_sum = sds->sdt_lat.ly_a_sum;
      915 +                ksr->kr_a_mean = sds->sdt_lat.ly_a_mean;
      916 +                ksr->kr_a_stddev = sds->sdt_lat.ly_a_stddev;
      917 +                ksr->kr_d_mean = sds->sdt_lat.ly_d_mean;
      918 +                ksr->kr_d_stddev = sds->sdt_lat.ly_d_stddev;
      919 +                sds->sdt_lat.ly_d_mean = 0;
      920 +                sds->sdt_lat.ly_d_nreq = 0;
      921 +                sds->sdt_lat.ly_d_stddev = 0;
      922 +                sds->sdt_lat.ly_d_sum = 0;
      923 +                mutex_exit(&sds->sdt_lat.ly_mutex);
      924 +        }
      925 +
      926 +        return (0);
      927 +}
      928 +
      929 +/*
 749  930   * Removes the share specified by 'shrname' from the AVL
 750  931   * tree of the given server if it's there.
 751  932   *
 752  933   * If the share is an Autohome share, the autohome count
 753  934   * is decremented and the share is only removed if the
 754  935   * count goes to zero.
 755  936   *
 756  937   * If the share is a disk share, the hold on the corresponding
 757  938   * file system is released before removing the share from
 758  939   * the AVL tree.
 759  940   */
 760  941  static int
 761  942  smb_kshare_unexport(smb_server_t *sv, const char *shrname)
 762  943  {
 763  944          smb_avl_t       *share_avl;
 764  945          smb_kshare_t    key;
 765  946          smb_kshare_t    *shr;
 766      -        vnode_t         *vp;
 767      -        int             rc;
 768  947          boolean_t       auto_unexport;
 769  948  
 770  949          share_avl = &sv->sv_export.e_share_avl;
 771  950  
 772  951          key.shr_name = (char *)shrname;
 773  952          if ((shr = smb_avl_lookup(share_avl, &key)) == NULL)
 774  953                  return (ENOENT);
 775  954  
 776  955          if ((shr->shr_flags & SMB_SHRF_AUTOHOME) != 0) {
 777  956                  mutex_enter(&shr->shr_mutex);
 778  957                  shr->shr_autocnt--;
 779  958                  auto_unexport = (shr->shr_autocnt == 0);
 780  959                  mutex_exit(&shr->shr_mutex);
 781  960                  if (!auto_unexport) {
 782  961                          smb_avl_release(share_avl, shr);
 783  962                          return (0);
 784  963                  }
 785  964          }
 786  965  
 787      -        if (STYPE_ISDSK(shr->shr_type)) {
 788      -                if ((rc = smb_server_sharevp(sv, shr->shr_path, &vp)) != 0) {
 789      -                        smb_avl_release(share_avl, shr);
 790      -                        cmn_err(CE_WARN, "unexport[%s]: failed obtaining vnode"
 791      -                            " (%d)", shrname, rc);
 792      -                        return (rc);
 793      -                }
      966 +        smb_avl_remove(share_avl, shr);
 794  967  
 795      -                smb_vfs_rele(&sv->sv_export, vp->v_vfsp);
 796      -                VN_RELE(vp);
 797      -        }
      968 +        mutex_enter(&shr->shr_mutex);
      969 +        shr->shr_flags |= SMB_SHRF_REMOVED;
      970 +        mutex_exit(&shr->shr_mutex);
 798  971  
 799      -        smb_avl_remove(share_avl, shr);
 800  972          smb_avl_release(share_avl, shr);
 801  973  
 802  974          return (0);
 803  975  }
 804  976  
 805  977  /*
 806  978   * Exports IPC$ or Admin shares
 807  979   */
 808  980  static int
 809  981  smb_kshare_export_trans(smb_server_t *sv, char *name, char *path, char *cmnt)
↓ open down ↓ 32 lines elided ↑ open up ↑
 842 1014   *
 843 1015   * This is a temporary function and will be replaced by functions
 844 1016   * provided by libsharev2 code after it's available.
 845 1017   */
 846 1018  static smb_kshare_t *
 847 1019  smb_kshare_decode(nvlist_t *share)
 848 1020  {
 849 1021          smb_kshare_t tmp;
 850 1022          smb_kshare_t *shr;
 851 1023          nvlist_t *smb;
 852      -        char *csc_name = NULL;
     1024 +        char *csc_name = NULL, *strbuf = NULL;
 853 1025          int rc;
 854 1026  
 855 1027          ASSERT(share);
 856 1028  
 857 1029          bzero(&tmp, sizeof (smb_kshare_t));
 858 1030  
 859 1031          rc = nvlist_lookup_string(share, "name", &tmp.shr_name);
 860 1032          rc |= nvlist_lookup_string(share, "path", &tmp.shr_path);
 861 1033          (void) nvlist_lookup_string(share, "desc", &tmp.shr_cmnt);
 862 1034  
↓ open down ↓ 19 lines elided ↑ open up ↑
 882 1054          (void) nvlist_lookup_string(smb, SHOPT_RO, &tmp.shr_access_ro);
 883 1055          (void) nvlist_lookup_string(smb, SHOPT_RW, &tmp.shr_access_rw);
 884 1056  
 885 1057          tmp.shr_flags |= smb_kshare_decode_bool(smb, SHOPT_ABE, SMB_SHRF_ABE);
 886 1058          tmp.shr_flags |= smb_kshare_decode_bool(smb, SHOPT_CATIA,
 887 1059              SMB_SHRF_CATIA);
 888 1060          tmp.shr_flags |= smb_kshare_decode_bool(smb, SHOPT_GUEST,
 889 1061              SMB_SHRF_GUEST_OK);
 890 1062          tmp.shr_flags |= smb_kshare_decode_bool(smb, SHOPT_DFSROOT,
 891 1063              SMB_SHRF_DFSROOT);
 892      -        tmp.shr_flags |= smb_kshare_decode_bool(smb, "Autohome",
     1064 +        tmp.shr_flags |= smb_kshare_decode_bool(smb, SHOPT_QUOTAS,
     1065 +            SMB_SHRF_QUOTAS);
     1066 +        tmp.shr_flags |= smb_kshare_decode_bool(smb, SHOPT_CA, SMB_SHRF_CA);
     1067 +        tmp.shr_flags |= smb_kshare_decode_bool(smb, SHOPT_FSO, SMB_SHRF_FSO);
     1068 +        tmp.shr_flags |= smb_kshare_decode_bool(smb, SHOPT_AUTOHOME,
 893 1069              SMB_SHRF_AUTOHOME);
 894 1070  
 895 1071          if ((tmp.shr_flags & SMB_SHRF_AUTOHOME) == SMB_SHRF_AUTOHOME) {
 896 1072                  rc = nvlist_lookup_uint32(smb, "uid", &tmp.shr_uid);
 897 1073                  rc |= nvlist_lookup_uint32(smb, "gid", &tmp.shr_gid);
 898 1074                  if (rc != 0) {
 899 1075                          cmn_err(CE_WARN, "kshare: failed looking up uid/gid"
 900 1076                              " (%d)", rc);
 901 1077                          return (NULL);
 902 1078                  }
 903 1079          }
 904 1080  
     1081 +        (void) nvlist_lookup_string(smb, SHOPT_ENCRYPT, &strbuf);
     1082 +        smb_cfg_set_require(strbuf, &tmp.shr_encrypt);
     1083 +
 905 1084          (void) nvlist_lookup_string(smb, SHOPT_CSC, &csc_name);
 906 1085          smb_kshare_csc_flags(&tmp, csc_name);
 907 1086  
 908 1087          shr = kmem_cache_alloc(smb_kshare_cache_share, KM_SLEEP);
 909 1088          bzero(shr, sizeof (smb_kshare_t));
 910 1089  
 911 1090          shr->shr_magic = SMB_SHARE_MAGIC;
 912 1091          shr->shr_refcnt = 1;
 913 1092  
 914 1093          shr->shr_name = smb_mem_strdup(tmp.shr_name);
↓ open down ↓ 5 lines elided ↑ open up ↑
 920 1099          if (tmp.shr_access_none)
 921 1100                  shr->shr_access_none = smb_mem_strdup(tmp.shr_access_none);
 922 1101          if (tmp.shr_access_ro)
 923 1102                  shr->shr_access_ro = smb_mem_strdup(tmp.shr_access_ro);
 924 1103          if (tmp.shr_access_rw)
 925 1104                  shr->shr_access_rw = smb_mem_strdup(tmp.shr_access_rw);
 926 1105  
 927 1106          shr->shr_oemname = smb_kshare_oemname(shr->shr_name);
 928 1107          shr->shr_flags = tmp.shr_flags | smb_kshare_is_admin(shr->shr_name);
 929 1108          shr->shr_type = tmp.shr_type | smb_kshare_is_special(shr->shr_name);
     1109 +        shr->shr_encrypt = tmp.shr_encrypt;
 930 1110  
 931 1111          shr->shr_uid = tmp.shr_uid;
 932 1112          shr->shr_gid = tmp.shr_gid;
 933 1113  
 934 1114          if ((shr->shr_flags & SMB_SHRF_AUTOHOME) == SMB_SHRF_AUTOHOME)
 935 1115                  shr->shr_autocnt = 1;
 936      -
 937 1116          return (shr);
 938 1117  }
 939 1118  
 940 1119  #if 0
 941 1120  static void
 942 1121  smb_kshare_log(smb_kshare_t *shr)
 943 1122  {
 944 1123          cmn_err(CE_NOTE, "Share info:");
 945 1124          cmn_err(CE_NOTE, "\tname: %s", (shr->shr_name) ? shr->shr_name : "");
 946 1125          cmn_err(CE_NOTE, "\tpath: %s", (shr->shr_path) ? shr->shr_path : "");
↓ open down ↓ 79 lines elided ↑ open up ↑
1026 1205   * from the share cache.
1027 1206   */
1028 1207  static void
1029 1208  smb_kshare_destroy(void *p)
1030 1209  {
1031 1210          smb_kshare_t *shr = (smb_kshare_t *)p;
1032 1211  
1033 1212          ASSERT(shr);
1034 1213          ASSERT(shr->shr_magic == SMB_SHARE_MAGIC);
1035 1214  
     1215 +        if (shr->shr_ksp != NULL) {
     1216 +                kstat_delete(shr->shr_ksp);
     1217 +                shr->shr_ksp = NULL;
     1218 +                kshare_stats_fini(shr);
     1219 +        }
     1220 +
     1221 +        if (shr->stats.ksns != NULL) {
     1222 +                kstat_delete(shr->stats.ksns);
     1223 +        }
     1224 +
     1225 +        if (shr->shr_ca_dir != NULL)
     1226 +                smb_node_release(shr->shr_ca_dir);
     1227 +        if (shr->shr_root_node)
     1228 +                smb_node_release(shr->shr_root_node);
     1229 +
1036 1230          smb_mem_free(shr->shr_name);
1037 1231          smb_mem_free(shr->shr_path);
1038 1232          smb_mem_free(shr->shr_cmnt);
1039 1233          smb_mem_free(shr->shr_container);
1040 1234          smb_mem_free(shr->shr_oemname);
1041 1235          smb_mem_free(shr->shr_access_none);
1042 1236          smb_mem_free(shr->shr_access_ro);
1043 1237          smb_mem_free(shr->shr_access_rw);
1044 1238  
1045 1239          kmem_cache_free(smb_kshare_cache_share, shr);
↓ open down ↓ 203 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX