Print this page
NEX-18761 panic in smb_ofile_free with vdbench
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@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-15069 smtorture smb2.create.blob is failed
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-15069 smtorture smb2.create.blob is failed
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-4053 Customer DIR command hangs with smb2 enabled
NEX-4080 SMB_ODIR_FLAG_WILDCARDS can be incorrectly inherited
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
NEX-2058 Access Based Enumeration partially working in 4.0.1
OS-143 Cpqary3 driver does not see drives on P400 Smart-Array
SUP-813 Directory's are not visible or deleteable though CIFS
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-65 SMB server in non-global zones (use zone_kcred())
SMB-65 SMB server in non-global zones (kmem_caches)
common kmem_cache instances across zones
separate GZ-only init from NGZ init
SMB-63 taskq_create_proc ... TQ_DYNAMIC puts tasks in p0
re #11974 CIFS Share - Tree connect fails from Windows 7 Clients
re #7815 SMB server delivers old modification time...
re #6854 FindFirstFile,FindFirstFileEx,... are not working correctly on Nexenta CIFS-shares
re #10733 Windows 7 directory listing keeps restarting (fix lint)
re #10733 Windows 7 directory listing keeps restarting

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/smbsrv/smb_odir.c
          +++ new/usr/src/uts/common/fs/smbsrv/smb_odir.c
↓ 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) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  23      - * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
       23 + * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  24   24   */
  25   25  
  26   26  /*
  27   27   * General Structures Layout
  28   28   * -------------------------
  29   29   *
  30   30   * This is a simplified diagram showing the relationship between most of the
  31   31   * main structures.
  32   32   *
  33   33   * +-------------------+
↓ open down ↓ 223 lines elided ↑ open up ↑
 257  257  static smb_odir_t *smb_odir_create(smb_request_t *, smb_node_t *,
 258  258      const char *, uint16_t, uint16_t, cred_t *);
 259  259  static int smb_odir_single_fileinfo(smb_request_t *, smb_odir_t *,
 260  260      smb_fileinfo_t *);
 261  261  static int smb_odir_wildcard_fileinfo(smb_request_t *, smb_odir_t *,
 262  262      smb_odirent_t *, smb_fileinfo_t *);
 263  263  static int smb_odir_next_odirent(smb_odir_t *, smb_odirent_t *);
 264  264  static boolean_t smb_odir_lookup_link(smb_request_t *, smb_odir_t *,
 265  265      char *, smb_node_t **);
 266  266  static boolean_t smb_odir_match_name(smb_odir_t *, smb_odirent_t *);
      267 +static void smb_odir_delete(void *);
 267  268  
 268  269  
 269  270  /*
 270  271   * smb_odir_openpath
 271  272   *
 272  273   * Create an odir representing the directory specified in pathname.
 273  274   *
 274  275   * Returns:
 275  276   *    NT Status
 276  277   */
 277  278  uint32_t
 278  279  smb_odir_openpath(smb_request_t *sr, char *path, uint16_t sattr,
 279  280          uint32_t flags, smb_odir_t **odp)
 280  281  {
 281  282          int             rc;
 282  283          smb_tree_t      *tree;
 283  284          smb_node_t      *dnode;
 284  285          char            pattern[MAXNAMELEN];
 285      -        uint16_t        odid;
      286 +        uint16_t        odid;
 286  287          cred_t          *cr;
 287  288  
 288  289          ASSERT(sr);
 289  290          ASSERT(sr->sr_magic == SMB_REQ_MAGIC);
 290  291          ASSERT(sr->tid_tree);
 291  292          ASSERT(sr->tid_tree->t_magic == SMB_TREE_MAGIC);
 292  293          *odp = NULL;
 293  294  
 294  295          tree = sr->tid_tree;
 295  296  
↓ open down ↓ 142 lines elided ↑ open up ↑
 438  439  
 439  440  /*
 440  441   * If the odir is in SMB_ODIR_STATE_CLOSING and this release results in
 441  442   * a refcnt of 0, change the state to SMB_ODIR_STATE_CLOSED and post the
 442  443   * object for deletion.  Object deletion is deferred to avoid modifying
 443  444   * a list while an iteration may be in progress.
 444  445   */
 445  446  void
 446  447  smb_odir_release(smb_odir_t *od)
 447  448  {
      449 +        smb_tree_t *tree = od->d_tree;
      450 +
 448  451          SMB_ODIR_VALID(od);
 449  452  
 450  453          mutex_enter(&od->d_mutex);
 451  454          ASSERT(od->d_refcnt > 0);
 452  455  
 453  456          switch (od->d_state) {
 454  457          case SMB_ODIR_STATE_OPEN:
 455  458                  break;
 456  459          case SMB_ODIR_STATE_IN_USE:
 457  460                  od->d_refcnt--;
 458  461                  if (od->d_refcnt == 0)
 459  462                          od->d_state = SMB_ODIR_STATE_OPEN;
 460  463                  break;
 461  464          case SMB_ODIR_STATE_CLOSING:
 462  465                  od->d_refcnt--;
 463  466                  if (od->d_refcnt == 0) {
 464  467                          od->d_state = SMB_ODIR_STATE_CLOSED;
 465      -                        smb_tree_post_odir(od->d_tree, od);
      468 +                        smb_llist_post(&tree->t_odir_list, od,
      469 +                            smb_odir_delete);
 466  470                  }
 467  471                  break;
 468  472          case SMB_ODIR_STATE_CLOSED:
 469  473          default:
 470  474                  break;
 471  475          }
 472  476  
 473  477          mutex_exit(&od->d_mutex);
 474  478  }
 475  479  
↓ open down ↓ 506 lines elided ↑ open up ↑
 982  986  
 983  987          mutex_exit(&od->d_mutex);
 984  988  }
 985  989  
 986  990  /*
 987  991   * Delete an odir.
 988  992   *
 989  993   * Remove the odir from the tree list before freeing resources
 990  994   * associated with the odir.
 991  995   */
 992      -void
      996 +static void
 993  997  smb_odir_delete(void *arg)
 994  998  {
 995  999          smb_tree_t      *tree;
 996 1000          smb_odir_t      *od = (smb_odir_t *)arg;
 997 1001  
 998 1002          SMB_ODIR_VALID(od);
 999 1003          ASSERT(od->d_refcnt == 0);
1000 1004          ASSERT(od->d_state == SMB_ODIR_STATE_CLOSED);
1001 1005  
1002 1006          tree = od->d_tree;
1003 1007          smb_llist_enter(&tree->t_odir_list, RW_WRITER);
1004 1008          smb_llist_remove(&tree->t_odir_list, od);
1005 1009          if (od->d_odid != 0)
1006 1010                  smb_idpool_free(&tree->t_odid_pool, od->d_odid);
1007 1011          atomic_dec_32(&tree->t_session->s_dir_cnt);
1008 1012          smb_llist_exit(&tree->t_odir_list);
1009 1013  
     1014 +        /*
     1015 +         * This ofile is no longer on t_odir_list, however...
     1016 +         *
     1017 +         * This is called via smb_llist_post, which means it may run
     1018 +         * BEFORE smb_odir_release drops d_mutex (if another thread
     1019 +         * flushes the delete queue before we do).  Synchronize.
     1020 +         */
1010 1021          mutex_enter(&od->d_mutex);
1011 1022          mutex_exit(&od->d_mutex);
1012 1023  
1013 1024          od->d_magic = 0;
1014 1025          smb_node_release(od->d_dnode);
1015 1026          smb_user_release(od->d_user);
1016 1027          mutex_destroy(&od->d_mutex);
1017 1028          kmem_cache_free(smb_cache_odir, od);
1018 1029  }
1019 1030  
↓ open down ↓ 21 lines elided ↑ open up ↑
1041 1052   */
1042 1053  static int
1043 1054  smb_odir_next_odirent(smb_odir_t *od, smb_odirent_t *odirent)
1044 1055  {
1045 1056          int             rc;
1046 1057          int             reclen;
1047 1058          int             eof;
1048 1059          dirent64_t      *dp;
1049 1060          edirent_t       *edp;
1050 1061          char            *np;
1051      -        uint32_t        abe_flag = 0;
     1062 +        uint32_t        rddir_flags = 0;
1052 1063  
1053 1064          ASSERT(MUTEX_HELD(&od->d_mutex));
1054 1065  
1055 1066          bzero(odirent, sizeof (smb_odirent_t));
1056 1067  
     1068 +        if (od->d_flags & SMB_ODIR_FLAG_ABE)
     1069 +                rddir_flags |= SMB_ABE;
     1070 +        if (od->d_flags & SMB_ODIR_FLAG_EDIRENT)
     1071 +                rddir_flags |= SMB_EDIRENT;
     1072 +
1057 1073          if (od->d_bufptr != NULL) {
1058 1074                  if (od->d_flags & SMB_ODIR_FLAG_EDIRENT)
1059 1075                          reclen = od->d_edp->ed_reclen;
1060 1076                  else
1061 1077                          reclen = od->d_dp->d_reclen;
1062 1078  
1063 1079                  if (reclen == 0) {
1064 1080                          od->d_bufptr = NULL;
1065 1081                  } else {
1066 1082                          od->d_bufptr += reclen;
↓ open down ↓ 1 lines elided ↑ open up ↑
1068 1084                                  od->d_bufptr = NULL;
1069 1085                  }
1070 1086          }
1071 1087  
1072 1088          if (od->d_bufptr == NULL) {
1073 1089                  if (od->d_eof)
1074 1090                          return (ENOENT);
1075 1091  
1076 1092                  od->d_bufsize = sizeof (od->d_buf);
1077 1093  
1078      -                if (od->d_flags & SMB_ODIR_FLAG_ABE)
1079      -                        abe_flag = SMB_ABE;
1080      -
1081 1094                  rc = smb_vop_readdir(od->d_dnode->vp, od->d_offset,
1082      -                    od->d_buf, &od->d_bufsize, &eof, abe_flag, od->d_cred);
     1095 +                    od->d_buf, &od->d_bufsize, &eof, rddir_flags, od->d_cred);
1083 1096  
1084 1097                  if ((rc == 0) && (od->d_bufsize == 0))
1085 1098                          rc = ENOENT;
1086 1099  
1087 1100                  if (rc != 0) {
1088 1101                          od->d_bufptr = NULL;
1089 1102                          od->d_bufsize = 0;
1090 1103                          return (rc);
1091 1104                  }
1092 1105  
↓ open down ↓ 349 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX