Print this page
NEX-4856 SMB2 kstats don't correctly count compound requests
Reviewed by: Gordon Ross <gordon.ross@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-15555 SMB2 async redesign
NEX-15061 smtorture smb2.lock.cancel.cancel is failed
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Also follow-up change to:
 NEX-1643 dtrace provider for smbsrv (remove "done2" probes,
 which don't make sense with the new async design)
NEX-15578 SMB2 durable handle redesign
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-15555 SMB2 async redesign
NEX-15061 smtorture smb2.lock.cancel.cancel is failed
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Also follow-up change to:
 NEX-1643 dtrace provider for smbsrv (remove "done2" probes,
 which don't make sense with the new async design)
NEX-1643 dtrace provider for smbsrv
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
NEX-10229 SMB v1 response incorrect when signature verification fails
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
NEX-9864 Some SMB cancel races remain after NEX-5845
Revert (part of) "NEX-5845 rework SMB immediate cancel"
reverts (part of) commit 7a5da69f6d42b17ebcc95ca3d02925d07a01343e.
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-5845 rework SMB immediate cancel
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
NEX-5152 immediate SMB cancel may fail
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Matt Barden <Matt.Barden@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-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-4391 improve smb cancel support
Reviewed by: Matt Barden <Matt.Barden@nexenta.com>
NEX-4147 Cancelled SMB2 requests sometimes have no response (missed things)
NEX-3611 CLONE NEX-3550 Replace smb2_enable with max_protocol
Reviewed by: Yuri Pankov <Yuri.Pankov@nexenta.com>
NEX-2370 unable to save/modify files (zip,notepad,excel) on CIFS share from Windows 7
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-69 read-raw, write-raw are dead code
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())
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-63 taskq_create_proc ... TQ_DYNAMIC puts tasks in p0
re #11974 CIFS Share - Tree connect fails from Windows 7 Clients

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/smbsrv/smb_dispatch.c
          +++ new/usr/src/uts/common/fs/smbsrv/smb_dispatch.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 2015 Nexenta Systems, Inc.  All rights reserved.
       24 + * Copyright 2019 Nexenta Systems, Inc.  All rights reserved.
  25   25   */
  26   26  
  27   27  /*
  28   28   * SMB requests.
  29   29   *
  30   30   * Request
  31   31   *   Header
  32   32   *      Magic           0xFF 'S' 'M' 'B'
  33   33   *      smb_com         a byte, the "first" command
  34   34   *      Error           a 4-byte union, ignored in a request
↓ open down ↓ 126 lines elided ↑ open up ↑
 161  161              0x05, PC_NETWORK_PROGRAM_1_0 },
 162  162          { "SmbDelete", SMB_SDT_OPS(delete),                     /* 0x06 006 */
 163  163              0x06, PC_NETWORK_PROGRAM_1_0 },
 164  164          { "SmbRename", SMB_SDT_OPS(rename),                     /* 0x07 007 */
 165  165              0x07, PC_NETWORK_PROGRAM_1_0 },
 166  166          { "SmbQueryInformation", SMB_SDT_OPS(query_information), /* 0x08 008 */
 167  167              0x08, PC_NETWORK_PROGRAM_1_0 },
 168  168          { "SmbSetInformation", SMB_SDT_OPS(set_information),    /* 0x09 009 */
 169  169              0x09, PC_NETWORK_PROGRAM_1_0 },
 170  170          { "SmbRead", SMB_SDT_OPS(read),                         /* 0x0A 010 */
 171      -            0x0A, PC_NETWORK_PROGRAM_1_0 },
      171 +            0x0A, PC_NETWORK_PROGRAM_1_0, SDDF_READOP },
 172  172          { "SmbWrite", SMB_SDT_OPS(write),                       /* 0x0B 011 */
 173      -            0x0B, PC_NETWORK_PROGRAM_1_0 },
      173 +            0x0B, PC_NETWORK_PROGRAM_1_0, SDDF_WRITEOP },
 174  174          { "SmbLockByteRange", SMB_SDT_OPS(lock_byte_range),     /* 0x0C 012 */
 175  175              0x0C, PC_NETWORK_PROGRAM_1_0 },
 176  176          { "SmbUnlockByteRange", SMB_SDT_OPS(unlock_byte_range), /* 0x0D 013 */
 177  177              0x0D, PC_NETWORK_PROGRAM_1_0 },
 178  178          { "SmbCreateTemporary", SMB_SDT_OPS(create_temporary),  /* 0x0E 014 */
 179  179              0x0E, PC_NETWORK_PROGRAM_1_0 },
 180  180          { "SmbCreateNew", SMB_SDT_OPS(create_new),              /* 0x0F 015 */
 181  181              0x0F, PC_NETWORK_PROGRAM_1_0 },
 182  182          { "SmbCheckDirectory", SMB_SDT_OPS(check_directory),    /* 0x10 016 */
 183  183              0x10, PC_NETWORK_PROGRAM_1_0 },
 184  184          { "SmbProcessExit", SMB_SDT_OPS(process_exit),          /* 0x11 017 */
 185  185              0x11, PC_NETWORK_PROGRAM_1_0,
 186  186              SDDF_SUPPRESS_TID | SDDF_SUPPRESS_UID },
 187  187          { "SmbSeek", SMB_SDT_OPS(seek),                         /* 0x12 018 */
 188  188              0x12, PC_NETWORK_PROGRAM_1_0 },
 189  189          { "SmbLockAndRead", SMB_SDT_OPS(lock_and_read),         /* 0x13 019 */
 190      -            0x13, LANMAN1_0 },
      190 +            0x13, LANMAN1_0, SDDF_READOP},
 191  191          { "SmbWriteAndUnlock", SMB_SDT_OPS(write_and_unlock),   /* 0x14 020 */
 192      -            0x14, LANMAN1_0 },
      192 +            0x14, LANMAN1_0, SDDF_WRITEOP },
 193  193          { "Invalid", SMB_SDT_OPS(invalid), 0x15, 0 },           /* 0x15 021 */
 194  194          { "Invalid", SMB_SDT_OPS(invalid), 0x16, 0 },           /* 0x16 022 */
 195  195          { "Invalid", SMB_SDT_OPS(invalid), 0x17, 0 },           /* 0x17 023 */
 196  196          { "Invalid", SMB_SDT_OPS(invalid), 0x18, 0 },           /* 0x18 024 */
 197  197          { "Invalid", SMB_SDT_OPS(invalid), 0x19, 0 },           /* 0x19 025 */
 198      -        { "SmbReadRaw", SMB_SDT_OPS(invalid), 0x1A, 0 },        /* 0x1A 026 */
      198 +        { "SmbReadRaw", SMB_SDT_OPS(read_raw),                  /* 0x1A 026 */
      199 +            0x1A, LANMAN1_0 },
 199  200          { "Invalid", SMB_SDT_OPS(invalid), 0x1B, 0 },           /* 0x1B 027 */
 200  201          { "Invalid", SMB_SDT_OPS(invalid), 0x1C, 0 },           /* 0x1C 028 */
 201      -        { "SmbWriteRaw", SMB_SDT_OPS(invalid), 0x1D, 0 },       /* 0x1D 029 */
      202 +        { "SmbWriteRaw", SMB_SDT_OPS(write_raw),                /* 0x1D 029 */
      203 +            0x1D, LANMAN1_0 },
 202  204          { "Invalid", SMB_SDT_OPS(invalid), 0x1E, 0 },           /* 0x1E 030 */
 203  205          { "Invalid", SMB_SDT_OPS(invalid), 0x1F, 0 },           /* 0x1F 031 */
 204  206          { "Invalid", SMB_SDT_OPS(invalid), 0x20, 0 },           /* 0x20 032 */
 205  207          { "Invalid", SMB_SDT_OPS(invalid), 0x21, 0 },           /* 0x21 033 */
 206  208          { "SmbSetInformation2", SMB_SDT_OPS(set_information2),  /* 0x22 034 */
 207  209              0x22, LANMAN1_0 },
 208  210          { "SmbQueryInformation2",
 209  211              SMB_SDT_OPS(query_information2),                    /* 0x23 035 */
 210  212              0x23, LANMAN1_0 },
 211  213          { "SmbLockingX", SMB_SDT_OPS(locking_andx),             /* 0x24 036 */
↓ open down ↓ 4 lines elided ↑ open up ↑
 216  218              SMB_SDT_OPS(transaction_secondary),                 /* 0x26 038 */
 217  219              0x26, LANMAN1_0 },
 218  220          { "SmbIoctl", SMB_SDT_OPS(ioctl),                       /* 0x27 039 */
 219  221              0x27, LANMAN1_0 },
 220  222          { "Invalid", SMB_SDT_OPS(invalid), 0x28, 0 },   /* 0x28 040 */
 221  223          { "Invalid", SMB_SDT_OPS(invalid), 0x29, 0 },   /* 0x29 041 */
 222  224          { "Invalid", SMB_SDT_OPS(invalid), 0x2A, 0 },   /* 0x2A 042 */
 223  225          { "SmbEcho", SMB_SDT_OPS(echo),                         /* 0x2B 043 */
 224  226              0x2B, LANMAN1_0, SDDF_SUPPRESS_TID | SDDF_SUPPRESS_UID },
 225  227          { "SmbWriteAndClose", SMB_SDT_OPS(write_and_close),     /* 0x2C 044 */
 226      -            0x2C, LANMAN1_0 },
      228 +            0x2C, LANMAN1_0, SDDF_WRITEOP },
 227  229          { "SmbOpenX", SMB_SDT_OPS(open_andx),                   /* 0x2D 045 */
 228  230              0x2D, LANMAN1_0 },
 229  231          { "SmbReadX", SMB_SDT_OPS(read_andx),                   /* 0x2E 046 */
 230      -            0x2E, LANMAN1_0 },
      232 +            0x2E, LANMAN1_0, SDDF_READOP },
 231  233          { "SmbWriteX", SMB_SDT_OPS(write_andx),                 /* 0x2F 047 */
 232      -            0x2F, LANMAN1_0 },
      234 +            0x2F, LANMAN1_0, SDDF_WRITEOP },
 233  235          { "Invalid", SMB_SDT_OPS(invalid), 0x30, 0 },   /* 0x30 048 */
 234  236          { "SmbCloseAndTreeDisconnect",
 235  237              SMB_SDT_OPS(close_and_tree_disconnect),             /* 0x31 049 */
 236  238              0x31, LANMAN1_0 },
 237  239          { "SmbTransaction2", SMB_SDT_OPS(transaction2),         /* 0x32 050 */
 238  240              0x32, LM1_2X002 },
 239  241          { "SmbTransaction2Secondary",
 240  242              SMB_SDT_OPS(transaction2_secondary),                /* 0x33 051 */
 241  243              0x33, LM1_2X002 },
 242  244          { "SmbFindClose2", SMB_SDT_OPS(find_close2),            /* 0x34 052 */
↓ open down ↓ 158 lines elided ↑ open up ↑
 401  403          { "Invalid", SMB_SDT_OPS(invalid), 0xB9, 0, 0 },        /* 0xB9 185 */
 402  404          { "Invalid", SMB_SDT_OPS(invalid), 0xBA, 0, 0 },        /* 0xBA 186 */
 403  405          { "Invalid", SMB_SDT_OPS(invalid), 0xBB, 0, 0 },        /* 0xBB 187 */
 404  406          { "Invalid", SMB_SDT_OPS(invalid), 0xBC, 0, 0 },        /* 0xBC 188 */
 405  407          { "Invalid", SMB_SDT_OPS(invalid), 0xBD, 0, 0 },        /* 0xBD 189 */
 406  408          { "Invalid", SMB_SDT_OPS(invalid), 0xBE, 0, 0 },        /* 0xBE 190 */
 407  409          { "Invalid", SMB_SDT_OPS(invalid), 0xBF, 0, 0 },        /* 0xBF 191 */
 408  410          { "SmbOpenPrintFile", SMB_SDT_OPS(open_print_file),     /* 0xC0 192 */
 409  411              0xC0, PC_NETWORK_PROGRAM_1_0, 0 },
 410  412          { "SmbWritePrintFile", SMB_SDT_OPS(write_print_file),   /* 0xC1 193 */
 411      -            0xC1, PC_NETWORK_PROGRAM_1_0, 0 },
      413 +            0xC1, PC_NETWORK_PROGRAM_1_0, SDDF_WRITEOP },
 412  414          { "SmbClosePrintFile", SMB_SDT_OPS(close_print_file),   /* 0xC2 194 */
 413  415              0xC2, PC_NETWORK_PROGRAM_1_0, 0 },
 414  416          { "SmbGetPrintQueue", SMB_SDT_OPS(get_print_queue),     /* 0xC3 195 */
 415  417              0xC3, PC_NETWORK_PROGRAM_1_0, 0 },
 416  418          { "Invalid", SMB_SDT_OPS(invalid), 0xC4, 0, 0 },        /* 0xC4 196 */
 417  419          { "Invalid", SMB_SDT_OPS(invalid), 0xC5, 0, 0 },        /* 0xC5 197 */
 418  420          { "Invalid", SMB_SDT_OPS(invalid), 0xC6, 0, 0 },        /* 0xC6 198 */
 419  421          { "Invalid", SMB_SDT_OPS(invalid), 0xC7, 0, 0 },        /* 0xC7 199 */
 420  422          { "Invalid", SMB_SDT_OPS(invalid), 0xC8, 0, 0 },        /* 0xC8 200 */
 421  423          { "Invalid", SMB_SDT_OPS(invalid), 0xC9, 0, 0 },        /* 0xC9 201 */
↓ open down ↓ 74 lines elided ↑ open up ↑
 496  498                  smb_xa_rele(sr->session, sr->r_xa);
 497  499                  sr->r_xa = NULL;
 498  500          }
 499  501  
 500  502          /*
 501  503           * Mark this request so we know that we've already cleaned it up.
 502  504           * A request should only get cleaned up once so multiple calls to
 503  505           * smbsr_cleanup for the same request indicate a bug.
 504  506           */
 505  507          mutex_enter(&sr->sr_mutex);
 506      -        if (sr->sr_state != SMB_REQ_STATE_CANCELED)
      508 +        if (sr->sr_state != SMB_REQ_STATE_CANCELLED)
 507  509                  sr->sr_state = SMB_REQ_STATE_CLEANED_UP;
 508  510          mutex_exit(&sr->sr_mutex);
 509  511  }
 510  512  
      513 +int smb_cancel_in_reader = 1;
      514 +
 511  515  /*
 512  516   * This is the SMB1 handler for new smb requests, called from
 513  517   * smb_session_reader after SMB negotiate is done.  For most SMB
 514  518   * requests, we just enqueue them for the smb_session_worker to
 515  519   * execute via the task queue, so they can block for resources
 516  520   * without stopping the reader thread.  A few protocol messages
 517  521   * are special cases and are handled directly here in the reader
 518  522   * thread so they don't wait for taskq scheduling.  Later, a few
 519  523   * MORE things could be handled here, such as REPLY messages
 520  524   * (oplock break reply) and things like "NT_cancel".
 521  525   *
 522  526   * This function must either enqueue the new request for
 523  527   * execution via the task queue, or execute it directly
 524  528   * and then free it.  If this returns non-zero, the caller
 525  529   * will drop the session.
 526  530   */
 527  531  int
 528  532  smb1sr_newrq(smb_request_t *sr)
 529  533  {
 530      -        uint32_t magic;
      534 +        uint16_t pid_hi, pid_lo;
      535 +        int rc, save_offset;
 531  536  
 532      -        magic = SMB_READ_PROTOCOL(sr->sr_request_buf);
 533      -        if (magic != SMB_PROTOCOL_MAGIC) {
      537 +        /*
      538 +         * Decode the SMB header now (peek) so that
      539 +         * SMB_COM_NT_CANCEL can find this SR.
      540 +         */
      541 +        save_offset = sr->command.chain_offset;
      542 +        rc = smb_mbc_decodef(&sr->command, SMB_HEADER_ED_FMT,
      543 +            &sr->smb_com,
      544 +            &sr->smb_rcls,
      545 +            &sr->smb_reh,
      546 +            &sr->smb_err,
      547 +            &sr->smb_flg,
      548 +            &sr->smb_flg2,
      549 +            &pid_hi,
      550 +            sr->smb_sig,
      551 +            &sr->smb_tid,
      552 +            &pid_lo,
      553 +            &sr->smb_uid,
      554 +            &sr->smb_mid);
      555 +        sr->command.chain_offset = save_offset;
      556 +        if (rc != 0) {
      557 +                /* Failed decoding the header. Drop 'em. */
 534  558                  smb_request_free(sr);
 535  559                  return (EPROTO);
 536  560          }
      561 +        sr->smb_pid = (pid_hi << 16) | pid_lo;
 537  562  
 538      -        if (sr->session->signing.flags & SMB_SIGNING_ENABLED) {
 539      -                if (SMB_IS_NT_CANCEL(sr)) {
      563 +        if (sr->smb_com == SMB_COM_NT_CANCEL) {
      564 +                if (sr->session->signing.flags & SMB_SIGNING_ENABLED) {
 540  565                          sr->session->signing.seqnum++;
 541  566                          sr->sr_seqnum = sr->session->signing.seqnum + 1;
 542  567                          sr->reply_seqnum = 0;
 543      -                } else {
      568 +                }
      569 +
      570 +                /*
      571 +                 * Normally execute cancel requests immediately,
      572 +                 * (here in the reader thread) so they won't wait
      573 +                 * for other commands already in the task queue.
      574 +                 * Disable this via smb_cancel_in_reader=0 for
      575 +                 * testing or diagnostic efforts, in which case
      576 +                 * cancel runs via taskq_dispatch.
      577 +                 */
      578 +                if (smb_cancel_in_reader != 0) {
      579 +                        rc = smb1sr_newrq_cancel(sr);
      580 +                        smb_request_free(sr);
      581 +                        return (rc);
      582 +                }
      583 +        } else {
      584 +                /* not NT cancel */
      585 +                if (sr->session->signing.flags & SMB_SIGNING_ENABLED) {
 544  586                          sr->session->signing.seqnum += 2;
 545  587                          sr->sr_seqnum = sr->session->signing.seqnum;
 546  588                          sr->reply_seqnum = sr->sr_seqnum + 1;
 547  589                  }
 548  590          }
 549  591  
 550  592          /*
 551  593           * Submit the request to the task queue, which calls
 552  594           * smb1_tq_work when the workload permits.
 553  595           */
↓ open down ↓ 13 lines elided ↑ open up ↑
 567  609          smb_srqueue_t   *srq;
 568  610  
 569  611          sr = (smb_request_t *)arg;
 570  612          SMB_REQ_VALID(sr);
 571  613  
 572  614          srq = sr->session->s_srqueue;
 573  615          smb_srqueue_waitq_to_runq(srq);
 574  616          sr->sr_worker = curthread;
 575  617          sr->sr_time_active = gethrtime();
 576  618  
      619 +        /*
      620 +         * Always dispatch to the work function, because cancelled
      621 +         * requests need an error reply (NT_STATUS_CANCELLED).
      622 +         */
 577  623          mutex_enter(&sr->sr_mutex);
 578      -        switch (sr->sr_state) {
 579      -        case SMB_REQ_STATE_SUBMITTED:
 580      -                mutex_exit(&sr->sr_mutex);
 581      -                smb1sr_work(sr);
 582      -                sr = NULL;
 583      -                break;
      624 +        if (sr->sr_state == SMB_REQ_STATE_SUBMITTED)
      625 +                sr->sr_state = SMB_REQ_STATE_ACTIVE;
      626 +        mutex_exit(&sr->sr_mutex);
 584  627  
 585      -        default:
 586      -                /*
 587      -                 * SMB1 requests that have been cancelled
 588      -                 * have no reply.  Just free it.
 589      -                 */
 590      -                sr->sr_state = SMB_REQ_STATE_COMPLETED;
 591      -                mutex_exit(&sr->sr_mutex);
 592      -                smb_request_free(sr);
 593      -                break;
 594      -        }
      628 +        smb1sr_work(sr);
      629 +
 595  630          smb_srqueue_runq_exit(srq);
 596  631  }
 597  632  
 598  633  /*
 599  634   * smb1sr_work
 600  635   *
 601  636   * In most cases, this should free the request before return.
 602  637   * Exceptions are when a dispatch function returns SDRC_SR_KEPT.
 603  638   */
 604  639  void
 605  640  smb1sr_work(struct smb_request *sr)
 606  641  {
 607  642          smb_sdrc_t              sdrc;
 608  643          const smb_disp_entry_t  *sdd;
 609  644          smb_disp_stats_t        *sds;
 610  645          boolean_t               disconnect = B_FALSE;
 611  646          smb_session_t           *session;
 612  647          smb_server_t            *server;
      648 +        int32_t                 txbase;
      649 +        uint32_t                rxbytes;
 613  650          uint32_t                byte_count;
 614  651          uint32_t                max_bytes;
 615  652          uint16_t                pid_hi, pid_lo;
 616  653  
 617  654          session = sr->session;
 618  655          server = session->s_server;
 619  656  
 620  657          ASSERT(sr->tid_tree == 0);
 621  658          ASSERT(sr->uid_user == 0);
 622  659          ASSERT(sr->fid_ofile == 0);
↓ open down ↓ 48 lines elided ↑ open up ↑
 671  708              sr->smb_flg,
 672  709              sr->smb_flg2,
 673  710              pid_hi,
 674  711              sr->smb_sig,
 675  712              sr->smb_tid,
 676  713              pid_lo,
 677  714              sr->smb_uid,
 678  715              sr->smb_mid);
 679  716          sr->first_smb_com = sr->smb_com;
 680  717  
      718 +        /* Need this for early goto report_error cases. */
      719 +        sr->cur_reply_offset = sr->reply.chain_offset;
      720 +
 681  721          if ((session->signing.flags & SMB_SIGNING_CHECK) != 0) {
 682  722                  if ((sr->smb_flg2 & SMB_FLAGS2_SMB_SECURITY_SIGNATURE) == 0 ||
 683  723                      smb_sign_check_request(sr) != 0) {
 684  724                          smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
 685  725                              ERRDOS, ERROR_ACCESS_DENIED);
 686  726                          disconnect = B_TRUE;
 687  727                          goto report_error;
 688  728                  }
 689  729          }
 690  730  
↓ open down ↓ 8 lines elided ↑ open up ↑
 699  739          }
 700  740  
 701  741          (void) MBC_SHADOW_CHAIN(&sr->smb_vwv, &sr->command,
 702  742              sr->command.chain_offset, sr->smb_wct * 2);
 703  743  
 704  744          if (smb_mbc_decodef(&sr->command, "#.w", sr->smb_wct*2, &sr->smb_bcc)) {
 705  745                  disconnect = B_TRUE;
 706  746                  goto report_error;
 707  747          }
 708  748  
 709      -        atomic_add_64(&sds->sdt_rxb,
 710      -            (int64_t)(sr->smb_wct * 2 + sr->smb_bcc + 1));
 711      -        sr->sr_txb = sr->reply.chain_offset;
 712      -
 713  749          /*
 714  750           * Ignore smb_bcc if CAP_LARGE_READX/CAP_LARGE_WRITEX
 715  751           * and this is SmbReadX/SmbWriteX since this enables
 716  752           * large reads/write and bcc is only 16-bits.
 717  753           */
 718  754          max_bytes = sr->command.max_bytes - sr->command.chain_offset;
 719  755          if (sr->smb_com == SMB_COM_WRITE_ANDX) {
 720  756                  /* Allow > BCC */
 721  757                  byte_count = max_bytes;
 722  758          } else if (max_bytes < (uint32_t)sr->smb_bcc) {
 723  759                  /* BCC is bogus.  Will fail later. */
 724  760                  byte_count = max_bytes;
 725  761          } else {
 726  762                  /* ordinary case */
 727  763                  byte_count = (uint32_t)sr->smb_bcc;
 728  764          }
 729  765  
      766 +        /* Save these for kstat updates below. */
      767 +        rxbytes = byte_count + 1 + 2 * sr->smb_wct;
      768 +        txbase = sr->reply.chain_offset;
      769 +
 730  770          (void) MBC_SHADOW_CHAIN(&sr->smb_data, &sr->command,
 731  771              sr->command.chain_offset, byte_count);
 732  772  
 733  773          sr->command.chain_offset += byte_count;
 734  774          if (sr->command.chain_offset > sr->command.max_bytes) {
 735  775                  disconnect = B_TRUE;
 736  776                  goto report_error;
 737  777          }
 738  778  
 739  779          /* Store pointers for later */
↓ open down ↓ 5 lines elided ↑ open up ↑
 745  785                      &sr->andx_com, &sr->andx_off) < 0) {
 746  786                          disconnect = B_TRUE;
 747  787                          goto report_error;
 748  788                  }
 749  789          } else {
 750  790                  sr->andx_com = (unsigned char)-1;
 751  791          }
 752  792  
 753  793          mutex_enter(&sr->sr_mutex);
 754  794          switch (sr->sr_state) {
 755      -        case SMB_REQ_STATE_SUBMITTED:
      795 +        case SMB_REQ_STATE_ACTIVE:
      796 +                break;
 756  797          case SMB_REQ_STATE_CLEANED_UP:
 757  798                  sr->sr_state = SMB_REQ_STATE_ACTIVE;
 758  799                  break;
 759      -        case SMB_REQ_STATE_CANCELED:
      800 +        case SMB_REQ_STATE_CANCELLED:
      801 +                /*
      802 +                 * Keep cancelled.  Handlers that might block will
      803 +                 * check the state and return NT_STATUS_CANCELLED.
      804 +                 */
 760  805                  break;
 761  806          default:
 762  807                  ASSERT(0);
 763  808                  break;
 764  809          }
 765  810          mutex_exit(&sr->sr_mutex);
 766  811  
 767  812          /*
 768  813           * Setup UID and TID information (if required). Both functions
 769  814           * will set the sr credentials. In domain mode, the user and
↓ open down ↓ 21 lines elided ↑ open up ↑
 791  836          }
 792  837  
 793  838          sr->sr_time_start = gethrtime();
 794  839          if ((sdrc = (*sdd->sdt_pre_op)(sr)) == SDRC_SUCCESS)
 795  840                  sdrc = (*sdd->sdt_function)(sr);
 796  841  
 797  842          if (sdrc != SDRC_SR_KEPT) {
 798  843                  (*sdd->sdt_post_op)(sr);
 799  844                  smbsr_cleanup(sr);
 800  845          }
 801      -        smb_latency_add_sample(&sds->sdt_lat, gethrtime() - sr->sr_time_start);
 802  846  
 803      -        atomic_add_64(&sds->sdt_txb,
 804      -            (int64_t)(sr->reply.chain_offset - sr->sr_txb));
      847 +        /* Record latency and rx/tx bytes per:  server, session, share. */
      848 +        {
      849 +                hrtime_t        dt;
      850 +                int64_t         rxb, txb;
      851 +                smb_disp_stats_t        *client_sds;    /* session */
      852 +                smb_disp_stats_t        *share_sds;  /* kshare */
      853 +                int     cmd_type;
 805  854  
      855 +                if (sdd->sdt_flags & SDDF_READOP) {
      856 +                        cmd_type = SMBSRV_CLSH_READ;
      857 +                } else if (sdd->sdt_flags & SDDF_WRITEOP) {
      858 +                        cmd_type = SMBSRV_CLSH_WRITE;
      859 +                } else {
      860 +                        cmd_type = SMBSRV_CLSH_OTHER;
      861 +                }
      862 +
      863 +                dt = gethrtime() - sr->sr_time_start;
      864 +                rxb = (int64_t)rxbytes;
      865 +                txb = (int64_t)(sr->reply.chain_offset - txbase);
      866 +
      867 +                smb_server_inc_req(server);
      868 +                smb_latency_add_sample(&sds->sdt_lat, dt);
      869 +                atomic_add_64(&sds->sdt_rxb, rxb);
      870 +                atomic_add_64(&sds->sdt_txb, txb);
      871 +
      872 +                client_sds = &session->s_stats[cmd_type];
      873 +                smb_latency_add_sample(&client_sds->sdt_lat, dt);
      874 +                atomic_add_64(&client_sds->sdt_rxb, rxb);
      875 +                atomic_add_64(&client_sds->sdt_txb, txb);
      876 +
      877 +                if ((sr->tid_tree != NULL) &&
      878 +                    (sr->tid_tree->t_kshare != NULL)) {
      879 +                        share_sds =
      880 +                            &sr->tid_tree->t_kshare->shr_stats[cmd_type];
      881 +                        smb_latency_add_sample(&share_sds->sdt_lat, dt);
      882 +                        atomic_add_64(&share_sds->sdt_rxb, rxb);
      883 +                        atomic_add_64(&share_sds->sdt_txb, txb);
      884 +                }
      885 +        }
      886 +
 806  887          switch (sdrc) {
 807  888          case SDRC_SUCCESS:
 808  889                  break;
 809  890  
 810  891          case SDRC_DROP_VC:
 811  892                  disconnect = B_TRUE;
 812  893                  goto drop_connection;
 813  894  
 814  895          case SDRC_NO_REPLY:
 815  896                  /* will free sr */
↓ open down ↓ 38 lines elided ↑ open up ↑
 854  935          sr->smb_wct = 0;
 855  936          sr->smb_bcc = 0;
 856  937  
 857  938          if (sr->smb_rcls == 0 && sr->smb_reh == 0 && sr->smb_err == 0)
 858  939                  smbsr_error(sr, 0, ERRSRV, ERRerror);
 859  940  
 860  941  reply_ready:
 861  942          smbsr_send_reply(sr);
 862  943  
 863  944  drop_connection:
 864      -        if (disconnect) {
 865      -                smb_rwx_rwenter(&session->s_lock, RW_WRITER);
 866      -                switch (session->s_state) {
 867      -                case SMB_SESSION_STATE_DISCONNECTED:
 868      -                case SMB_SESSION_STATE_TERMINATED:
 869      -                        break;
 870      -                default:
 871      -                        smb_soshutdown(session->sock);
 872      -                        session->s_state = SMB_SESSION_STATE_DISCONNECTED;
 873      -                        break;
 874      -                }
 875      -                smb_rwx_rwexit(&session->s_lock);
 876      -        }
      945 +        if (disconnect)
      946 +                smb_session_disconnect(session);
 877  947  
 878  948  out:
 879  949          if (sr != NULL) {
 880  950                  mutex_enter(&sr->sr_mutex);
 881  951                  sr->sr_state = SMB_REQ_STATE_COMPLETED;
 882  952                  mutex_exit(&sr->sr_mutex);
 883  953                  smb_request_free(sr);
 884  954          }
 885  955  }
 886  956  
↓ open down ↓ 292 lines elided ↑ open up ↑
1179 1249   *
1180 1250   * The Read/Write Block Multiplexed (mpx) protocol is used to maximize
1181 1251   * performance when reading/writing a large block of data: it can be
1182 1252   * used in parallel with other client/server operations.  The mpx sub-
1183 1253   * protocol is not supported because we support only connection oriented
1184 1254   * transports and NT supports mpx only over connectionless transports.
1185 1255   */
1186 1256  smb_sdrc_t
1187 1257  smb_pre_invalid(smb_request_t *sr)
1188 1258  {
1189      -        DTRACE_SMB_1(op__Invalid__start, smb_request_t *, sr);
     1259 +        DTRACE_SMB_START(op__Invalid, smb_request_t *, sr);
1190 1260          return (SDRC_SUCCESS);
1191 1261  }
1192 1262  
1193 1263  void
1194 1264  smb_post_invalid(smb_request_t *sr)
1195 1265  {
1196      -        DTRACE_SMB_1(op__Invalid__done, smb_request_t *, sr);
     1266 +        DTRACE_SMB_DONE(op__Invalid, smb_request_t *, sr);
1197 1267  }
1198 1268  
1199 1269  smb_sdrc_t
1200 1270  smb_com_invalid(smb_request_t *sr)
1201 1271  {
1202 1272          smb_sdrc_t sdrc;
1203 1273  
1204 1274          switch (sr->smb_com) {
1205 1275          case SMB_COM_WRITE_COMPLETE:
1206 1276                  smbsr_error(sr, 0, ERRSRV, ERRerror);
↓ open down ↓ 80 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX