Print this page
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-15069 smtorture smb2.create.blob is failed
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-15069 smtorture smb2.create.blob is failed
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-1643 dtrace provider for smbsrv
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
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-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())
SMB-63 taskq_create_proc ... TQ_DYNAMIC puts tasks in p0
re #11974 CIFS Share - Tree connect fails from Windows 7 Clients
SUP-599 smb_oplock_acquire thread deadlock
re #7815 SMB server delivers old modification time...
re #6854 FindFirstFile,FindFirstFileEx,... are not working correctly on Nexenta CIFS-shares

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/smbsrv/smb_delete.c
          +++ new/usr/src/uts/common/fs/smbsrv/smb_delete.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   */
  26   26  
  27   27  #include <sys/sunddi.h>
  28   28  #include <sys/nbmlock.h>
  29   29  
  30   30  #include <smbsrv/smb_kproto.h>
  31   31  #include <smbsrv/smb_fsops.h>
  32   32  #include <smbsrv/smbinfo.h>
  33   33  
  34   34  static int smb_delete_check_path(smb_request_t *);
↓ open down ↓ 62 lines elided ↑ open up ↑
  97   97  smb_pre_delete(smb_request_t *sr)
  98   98  {
  99   99          int rc;
 100  100          smb_fqi_t *fqi;
 101  101  
 102  102          fqi = &sr->arg.dirop.fqi;
 103  103  
 104  104          if ((rc = smbsr_decode_vwv(sr, "w", &fqi->fq_sattr)) == 0)
 105  105                  rc = smbsr_decode_data(sr, "%S", sr, &fqi->fq_path.pn_path);
 106  106  
 107      -        DTRACE_SMB_2(op__Delete__start, smb_request_t *, sr, smb_fqi_t *, fqi);
      107 +        DTRACE_SMB_START(op__Delete, smb_request_t *, sr); /* arg.dirop */
 108  108  
 109  109          return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 110  110  }
 111  111  
 112  112  void
 113  113  smb_post_delete(smb_request_t *sr)
 114  114  {
 115      -        DTRACE_SMB_1(op__Delete__done, smb_request_t *, sr);
      115 +        DTRACE_SMB_DONE(op__Delete, smb_request_t *, sr);
 116  116  }
 117  117  
 118  118  /*
 119  119   * smb_com_delete
 120  120   *
 121  121   * 1. intialize, pre-process and validate pathname
 122  122   *
 123  123   * 2. process the path to get directory node & last_comp,
 124  124   *    store these in fqi
 125  125   *    - If smb_pathname_reduce cannot find the specified path,
↓ open down ↓ 337 lines elided ↑ open up ↑
 463  463   * than one), and the file doesn't get deleted. Breaking the oplock
 464  464   * before share and lock checking gives the client a chance to
 465  465   * close the file.
 466  466   *
 467  467   * Returns: 0 - success
 468  468   *         -1 - error, err populated with error details
 469  469   */
 470  470  static int
 471  471  smb_delete_remove_file(smb_request_t *sr, smb_error_t *err)
 472  472  {
 473      -        int rc, count;
      473 +        int rc;
 474  474          uint32_t status;
 475  475          smb_fqi_t *fqi;
 476  476          smb_node_t *node;
 477  477          uint32_t flags = 0;
 478  478  
 479  479          fqi = &sr->arg.dirop.fqi;
 480  480          node = fqi->fq_fnode;
 481  481  
 482  482          /*
 483  483           * Break BATCH oplock before ofile checks. If a client
 484  484           * has a file open, this will force a flush or close,
 485  485           * which may affect the outcome of any share checking.
 486  486           */
 487      -        (void) smb_oplock_break(sr, node,
 488      -            SMB_OPLOCK_BREAK_TO_LEVEL_II | SMB_OPLOCK_BREAK_BATCH);
      487 +        status = smb_oplock_break_DELETE(node, NULL);
      488 +        if (status == NT_STATUS_OPLOCK_BREAK_IN_PROGRESS) {
      489 +                (void) smb_oplock_wait_break(node, 0);
      490 +                status = 0;
      491 +        }
      492 +        if (status != 0) {
      493 +                err->status = status;
      494 +                return (-1);
      495 +        }
 489  496  
 490      -        /*
 491      -         * Wait (a little) for the oplock break to be
 492      -         * responded to by clients closing handles.
 493      -         * Hold node->n_lock as reader to keep new
 494      -         * ofiles from showing up after we check.
 495      -         */
 496  497          smb_node_rdlock(node);
 497      -        for (count = 0; count <= 12; count++) {
 498      -                status = smb_node_delete_check(node);
 499      -                if (status != NT_STATUS_SHARING_VIOLATION)
 500      -                        break;
 501      -                smb_node_unlock(node);
 502      -                delay(MSEC_TO_TICK(100));
 503      -                smb_node_rdlock(node);
 504      -        }
      498 +        status = smb_node_delete_check(node);
 505  499          if (status != NT_STATUS_SUCCESS) {
      500 +                smb_node_unlock(node);
 506  501                  smb_delete_error(err, NT_STATUS_SHARING_VIOLATION,
 507  502                      ERRDOS, ERROR_SHARING_VIOLATION);
 508      -                smb_node_unlock(node);
 509  503                  return (-1);
 510  504          }
 511  505  
 512  506          /*
 513  507           * Note, the combination of these two:
 514  508           *      smb_node_rdlock(node);
 515  509           *      nbl_start_crit(node->vp, RW_READER);
 516  510           * is equivalent to this call:
 517  511           *      smb_node_start_crit(node, RW_READER)
 518  512           *
↓ open down ↓ 18 lines elided ↑ open up ↑
 537  531                      ERRDOS, ERROR_ACCESS_DENIED);
 538  532                  return (-1);
 539  533          }
 540  534  
 541  535          if (SMB_TREE_SUPPORTS_CATIA(sr))
 542  536                  flags |= SMB_CATIA;
 543  537  
 544  538          rc = smb_fsop_remove(sr, sr->user_cr, node->n_dnode,
 545  539              node->od_name, flags);
 546  540          if (rc != 0) {
 547      -                if (rc == ENOENT)
 548      -                        smb_delete_error(err, NT_STATUS_OBJECT_NAME_NOT_FOUND,
 549      -                            ERRDOS, ERROR_FILE_NOT_FOUND);
 550      -                else
 551      -                        smbsr_map_errno(rc, err);
 552      -
 553      -                smb_node_end_crit(node);
 554      -                return (-1);
      541 +                smbsr_map_errno(rc, err);
      542 +                rc = -1;
 555  543          }
 556  544  
 557  545          smb_node_end_crit(node);
 558      -        return (0);
      546 +        return (rc);
 559  547  }
 560  548  
 561  549  
 562  550  /*
 563  551   * smb_delete_check_path
 564  552   *
 565  553   * smb_pathname_validate() should already have been used to
 566  554   * perform initial validation on the pathname. Additional
 567  555   * request specific validation of the filename is performed
 568  556   * here.
↓ open down ↓ 46 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX