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
        
*** 18,28 ****
   *
   * CDDL HEADER END
   */
  /*
   * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
!  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
   */
  
  /*
   * General Structures Layout
   * -------------------------
--- 18,28 ----
   *
   * CDDL HEADER END
   */
  /*
   * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
!  * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
   */
  
  /*
   * General Structures Layout
   * -------------------------
*** 262,271 ****
--- 262,272 ----
      smb_odirent_t *, smb_fileinfo_t *);
  static int smb_odir_next_odirent(smb_odir_t *, smb_odirent_t *);
  static boolean_t smb_odir_lookup_link(smb_request_t *, smb_odir_t *,
      char *, smb_node_t **);
  static boolean_t smb_odir_match_name(smb_odir_t *, smb_odirent_t *);
+ static void smb_odir_delete(void *);
  
  
  /*
   * smb_odir_openpath
   *
*** 443,452 ****
--- 444,455 ----
   * a list while an iteration may be in progress.
   */
  void
  smb_odir_release(smb_odir_t *od)
  {
+         smb_tree_t *tree = od->d_tree;
+ 
          SMB_ODIR_VALID(od);
  
          mutex_enter(&od->d_mutex);
          ASSERT(od->d_refcnt > 0);
  
*** 460,470 ****
                  break;
          case SMB_ODIR_STATE_CLOSING:
                  od->d_refcnt--;
                  if (od->d_refcnt == 0) {
                          od->d_state = SMB_ODIR_STATE_CLOSED;
!                         smb_tree_post_odir(od->d_tree, od);
                  }
                  break;
          case SMB_ODIR_STATE_CLOSED:
          default:
                  break;
--- 463,474 ----
                  break;
          case SMB_ODIR_STATE_CLOSING:
                  od->d_refcnt--;
                  if (od->d_refcnt == 0) {
                          od->d_state = SMB_ODIR_STATE_CLOSED;
!                         smb_llist_post(&tree->t_odir_list, od,
!                             smb_odir_delete);
                  }
                  break;
          case SMB_ODIR_STATE_CLOSED:
          default:
                  break;
*** 987,997 ****
   * Delete an odir.
   *
   * Remove the odir from the tree list before freeing resources
   * associated with the odir.
   */
! void
  smb_odir_delete(void *arg)
  {
          smb_tree_t      *tree;
          smb_odir_t      *od = (smb_odir_t *)arg;
  
--- 991,1001 ----
   * Delete an odir.
   *
   * Remove the odir from the tree list before freeing resources
   * associated with the odir.
   */
! static void
  smb_odir_delete(void *arg)
  {
          smb_tree_t      *tree;
          smb_odir_t      *od = (smb_odir_t *)arg;
  
*** 1005,1014 ****
--- 1009,1025 ----
          if (od->d_odid != 0)
                  smb_idpool_free(&tree->t_odid_pool, od->d_odid);
          atomic_dec_32(&tree->t_session->s_dir_cnt);
          smb_llist_exit(&tree->t_odir_list);
  
+         /*
+          * This ofile is no longer on t_odir_list, however...
+          *
+          * This is called via smb_llist_post, which means it may run
+          * BEFORE smb_odir_release drops d_mutex (if another thread
+          * flushes the delete queue before we do).  Synchronize.
+          */
          mutex_enter(&od->d_mutex);
          mutex_exit(&od->d_mutex);
  
          od->d_magic = 0;
          smb_node_release(od->d_dnode);
*** 1046,1061 ****
          int             reclen;
          int             eof;
          dirent64_t      *dp;
          edirent_t       *edp;
          char            *np;
!         uint32_t        abe_flag = 0;
  
          ASSERT(MUTEX_HELD(&od->d_mutex));
  
          bzero(odirent, sizeof (smb_odirent_t));
  
          if (od->d_bufptr != NULL) {
                  if (od->d_flags & SMB_ODIR_FLAG_EDIRENT)
                          reclen = od->d_edp->ed_reclen;
                  else
                          reclen = od->d_dp->d_reclen;
--- 1057,1077 ----
          int             reclen;
          int             eof;
          dirent64_t      *dp;
          edirent_t       *edp;
          char            *np;
!         uint32_t        rddir_flags = 0;
  
          ASSERT(MUTEX_HELD(&od->d_mutex));
  
          bzero(odirent, sizeof (smb_odirent_t));
  
+         if (od->d_flags & SMB_ODIR_FLAG_ABE)
+                 rddir_flags |= SMB_ABE;
+         if (od->d_flags & SMB_ODIR_FLAG_EDIRENT)
+                 rddir_flags |= SMB_EDIRENT;
+ 
          if (od->d_bufptr != NULL) {
                  if (od->d_flags & SMB_ODIR_FLAG_EDIRENT)
                          reclen = od->d_edp->ed_reclen;
                  else
                          reclen = od->d_dp->d_reclen;
*** 1073,1087 ****
                  if (od->d_eof)
                          return (ENOENT);
  
                  od->d_bufsize = sizeof (od->d_buf);
  
-                 if (od->d_flags & SMB_ODIR_FLAG_ABE)
-                         abe_flag = SMB_ABE;
- 
                  rc = smb_vop_readdir(od->d_dnode->vp, od->d_offset,
!                     od->d_buf, &od->d_bufsize, &eof, abe_flag, od->d_cred);
  
                  if ((rc == 0) && (od->d_bufsize == 0))
                          rc = ENOENT;
  
                  if (rc != 0) {
--- 1089,1100 ----
                  if (od->d_eof)
                          return (ENOENT);
  
                  od->d_bufsize = sizeof (od->d_buf);
  
                  rc = smb_vop_readdir(od->d_dnode->vp, od->d_offset,
!                     od->d_buf, &od->d_bufsize, &eof, rddir_flags, od->d_cred);
  
                  if ((rc == 0) && (od->d_bufsize == 0))
                          rc = ENOENT;
  
                  if (rc != 0) {