Print this page
NEX-17289 Minimal SMB 3.0.2 support
Reviewed by: Gordon Ross <gordon.ross@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-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-1643 dtrace provider for smbsrv
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
NEX-5844 want SMB2 ioctl FSCTL_SRV_COPYCHUNK
NEX-6124 smb_fsop_read/write should allow file != sr->fid_ofile
NEX-6125 smbtorture invalid response with smb2.ioctl
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
NEX-6041 Should pass the smbtorture lock tests
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
NEX-3662 Backport illumos 1501: taskq_create_proc ... TQ_DYNAMIC puts tasks in p0 (take 2)
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Marcel Telka <marcel.telka@nexenta.com>
NEX-3576 RPC error when displaying open files via Windows MMC
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
NEX-2188 Browsing top level share produces RPC error 1728
SMB-69 read-raw, write-raw are dead code
SMB-39 Use AF_UNIX pipes for RPC

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/smbsrv/smb_read.c
          +++ new/usr/src/uts/common/fs/smbsrv/smb_read.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  #include <smbsrv/smb_kproto.h>
  27   27  #include <smbsrv/smb_fsops.h>
  28   28  
  29   29  /*
  30   30   * The maximum number of bytes to return from SMB Core
  31   31   * SmbRead or SmbLockAndRead.
  32   32   */
  33   33  #define SMB_CORE_READ_MAX       4432
↓ open down ↓ 32 lines elided ↑ open up ↑
  66   66          param = kmem_zalloc(sizeof (smb_rw_param_t), KM_SLEEP);
  67   67          sr->arg.rw = param;
  68   68  
  69   69          rc = smbsr_decode_vwv(sr, "wwlw", &sr->smb_fid,
  70   70              &count, &off_low, &remcnt);
  71   71  
  72   72          param->rw_offset = (uint64_t)off_low;
  73   73          param->rw_count = (uint32_t)count;
  74   74          param->rw_mincnt = 0;
  75   75  
  76      -        DTRACE_SMB_2(op__Read__start, smb_request_t *, sr,
  77      -            smb_rw_param_t *, param);
       76 +        DTRACE_SMB_START(op__Read, smb_request_t *, sr); /* arg.rw */
  78   77  
  79   78          return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
  80   79  }
  81   80  
  82   81  void
  83   82  smb_post_read(smb_request_t *sr)
  84   83  {
  85      -        DTRACE_SMB_2(op__Read__done, smb_request_t *, sr,
  86      -            smb_rw_param_t *, sr->arg.rw);
       84 +        DTRACE_SMB_DONE(op__Read, smb_request_t *, sr); /* arg.rw */
  87   85  
  88   86          kmem_free(sr->arg.rw, sizeof (smb_rw_param_t));
  89   87  }
  90   88  
  91   89  smb_sdrc_t
  92   90  smb_com_read(smb_request_t *sr)
  93   91  {
  94   92          smb_rw_param_t *param = sr->arg.rw;
  95   93          uint16_t count;
  96   94          int rc;
↓ open down ↓ 55 lines elided ↑ open up ↑
 152  150          param = kmem_zalloc(sizeof (smb_rw_param_t), KM_SLEEP);
 153  151          sr->arg.rw = param;
 154  152  
 155  153          rc = smbsr_decode_vwv(sr, "wwlw", &sr->smb_fid,
 156  154              &count, &off_low, &remcnt);
 157  155  
 158  156          param->rw_offset = (uint64_t)off_low;
 159  157          param->rw_count = (uint32_t)count;
 160  158          param->rw_mincnt = 0;
 161  159  
 162      -        DTRACE_SMB_2(op__LockAndRead__start, smb_request_t *, sr,
 163      -            smb_rw_param_t *, param);
      160 +        DTRACE_SMB_START(op__LockAndRead, smb_request_t *, sr); /* arg.rw */
 164  161  
 165  162          return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 166  163  }
 167  164  
 168  165  void
 169  166  smb_post_lock_and_read(smb_request_t *sr)
 170  167  {
 171      -        DTRACE_SMB_2(op__LockAndRead__done, smb_request_t *, sr,
 172      -            smb_rw_param_t *, sr->arg.rw);
      168 +        DTRACE_SMB_DONE(op__LockAndRead, smb_request_t *, sr); /* arg.rw */
 173  169  
 174  170          kmem_free(sr->arg.rw, sizeof (smb_rw_param_t));
 175  171  }
 176  172  
 177  173  smb_sdrc_t
 178  174  smb_com_lock_and_read(smb_request_t *sr)
 179  175  {
 180  176          smb_rw_param_t *param = sr->arg.rw;
 181  177          DWORD status;
      178 +        uint32_t lk_pid;
 182  179          uint16_t count;
 183  180          int rc;
 184  181  
 185  182          if (STYPE_ISDSK(sr->tid_tree->t_res_type) == 0) {
 186  183                  smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERRnoaccess);
 187  184                  return (SDRC_ERROR);
 188  185          }
 189  186  
 190  187          smbsr_lookup_file(sr);
 191  188          if (sr->fid_ofile == NULL) {
 192  189                  smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
 193  190                  return (SDRC_ERROR);
 194  191          }
 195  192  
 196  193          sr->user_cr = smb_ofile_getcred(sr->fid_ofile);
 197  194  
      195 +        /* Note: SMB1 locking uses 16-bit PIDs. */
      196 +        lk_pid = sr->smb_pid & 0xFFFF;
      197 +
 198  198          status = smb_lock_range(sr, param->rw_offset, (uint64_t)param->rw_count,
 199      -            0, SMB_LOCK_TYPE_READWRITE);
      199 +            lk_pid, SMB_LOCK_TYPE_READWRITE, 0);
 200  200  
 201  201          if (status != NT_STATUS_SUCCESS) {
 202  202                  smb_lock_range_error(sr, status);
 203  203                  return (SDRC_ERROR);
 204  204          }
 205  205  
 206  206          if (param->rw_count > SMB_CORE_READ_MAX)
 207  207                  param->rw_count = SMB_CORE_READ_MAX;
 208  208  
 209  209          if ((rc = smb_common_read(sr, param)) != 0) {
↓ open down ↓ 2 lines elided ↑ open up ↑
 212  212          }
 213  213  
 214  214          count = (uint16_t)param->rw_count;
 215  215          rc = smbsr_encode_result(sr, 5, VAR_BCC, "bw8.wbwC",
 216  216              5, count, VAR_BCC, 0x1, count, &sr->raw_data);
 217  217  
 218  218          return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 219  219  }
 220  220  
 221  221  /*
      222 + * The SMB_COM_READ_RAW protocol was a negotiated option introduced in
      223 + * SMB Core Plus to maximize performance when reading a large block
      224 + * of data from a server.  It's obsolete and no longer supported.
      225 + *
      226 + * We keep a handler for it so the dtrace provider can see if
      227 + * the client tried to use this command.
      228 + */
      229 +smb_sdrc_t
      230 +smb_pre_read_raw(smb_request_t *sr)
      231 +{
      232 +        DTRACE_SMB_START(op__ReadRaw, smb_request_t *, sr);
      233 +        return (SDRC_SUCCESS);
      234 +}
      235 +
      236 +void
      237 +smb_post_read_raw(smb_request_t *sr)
      238 +{
      239 +        DTRACE_SMB_DONE(op__ReadRaw, smb_request_t *, sr);
      240 +}
      241 +
      242 +smb_sdrc_t
      243 +smb_com_read_raw(smb_request_t *sr)
      244 +{
      245 +        smbsr_error(sr, NT_STATUS_NOT_SUPPORTED, ERRDOS,
      246 +            ERROR_NOT_SUPPORTED);
      247 +        return (SDRC_ERROR);
      248 +}
      249 +
      250 +/*
 222  251   * Read bytes from a file (SMB Core).  This request was extended in
 223  252   * LM 0.12 to support 64-bit offsets, indicated by sending a wct of
 224  253   * 12 and including additional offset information.
 225  254   *
 226  255   * MS-SMB 3.3.5.7 update to LM 0.12 4.2.4:
 227  256   * If wct is 12 and CAP_LARGE_READX is set, the count may be larger
 228  257   * than the negotiated buffer size.  If maxcnt_high is 0xFF, it must
 229  258   * be ignored.  Otherwise, maxcnt_high represents the upper 16 bits
 230  259   * of rw_count.
 231  260   */
↓ open down ↓ 29 lines elided ↑ open up ↑
 261  290                  rc = smbsr_decode_vwv(sr, "b3.wlwwlw", &param->rw_andx,
 262  291                      &sr->smb_fid, &off_low, &maxcnt_low, &mincnt, &maxcnt_high,
 263  292                      &remcnt);
 264  293  
 265  294                  param->rw_offset = (uint64_t)off_low;
 266  295                  param->rw_count = (uint32_t)maxcnt_low;
 267  296          }
 268  297  
 269  298          param->rw_mincnt = 0;
 270  299  
 271      -        DTRACE_SMB_2(op__ReadX__start, smb_request_t *, sr,
 272      -            smb_rw_param_t *, param);
      300 +        DTRACE_SMB_START(op__ReadX, smb_request_t *, sr); /* arg.rw */
 273  301  
 274  302          return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 275  303  }
 276  304  
 277  305  void
 278  306  smb_post_read_andx(smb_request_t *sr)
 279  307  {
 280      -        DTRACE_SMB_2(op__ReadX__done, smb_request_t *, sr,
 281      -            smb_rw_param_t *, sr->arg.rw);
      308 +        DTRACE_SMB_DONE(op__ReadX, smb_request_t *, sr); /* arg.rw */
 282  309  
 283  310          kmem_free(sr->arg.rw, sizeof (smb_rw_param_t));
 284  311  }
 285  312  
 286  313  smb_sdrc_t
 287  314  smb_com_read_andx(smb_request_t *sr)
 288  315  {
 289  316          smb_rw_param_t *param = sr->arg.rw;
 290  317          uint16_t datalen_high;
 291  318          uint16_t datalen_low;
↓ open down ↓ 59 lines elided ↑ open up ↑
 351  378  
 352  379          return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 353  380  }
 354  381  
 355  382  /*
 356  383   * Common function for reading files or IPC/MSRPC named pipes.  All
 357  384   * protocol read functions should lookup the fid before calling this
 358  385   * function.  We can't move the fid lookup here because lock-and-read
 359  386   * requires the fid to do locking before attempting the read.
 360  387   *
 361      - * Reading from a file should break oplocks on the file to LEVEL_II.
 362      - * A call to smb_oplock_break(SMB_OPLOCK_BREAK_TO_LEVEL_II) is not
 363      - * required as it is a no-op. If there's anything greater than a
 364      - * LEVEL_II oplock on the file, the oplock MUST be owned by the ofile
 365      - * on which the read is occuring and therefore would not be broken.
      388 + * Reading from a file does not break oplocks because any need for
      389 + * breaking before read is handled in open.
 366  390   *
 367  391   * Returns errno values.
 368  392   */
 369  393  int
 370  394  smb_common_read(smb_request_t *sr, smb_rw_param_t *param)
 371  395  {
 372  396          smb_ofile_t *ofile = sr->fid_ofile;
 373  397          smb_node_t *node;
 374  398          smb_vdb_t *vdb = &param->rw_vdb;
 375  399          struct mbuf *top;
↓ open down ↓ 30 lines elided ↑ open up ↑
 406  430                           * execute-only and SMB_FLAGS2_READ_IF_EXECUTE is not
 407  431                           * set.
 408  432                           */
 409  433                          rc = EACCES;
 410  434                          break;
 411  435                  }
 412  436  
 413  437                  sr->raw_data.max_bytes = vdb->vdb_uio.uio_resid;
 414  438                  top = smb_mbuf_allocate(&vdb->vdb_uio);
 415  439  
 416      -                rc = smb_fsop_read(sr, sr->user_cr, node, &vdb->vdb_uio);
      440 +                rc = smb_fsop_read(sr, sr->user_cr, node, ofile,
      441 +                    &vdb->vdb_uio, 0);
 417  442  
 418  443                  sr->raw_data.max_bytes -= vdb->vdb_uio.uio_resid;
 419  444                  smb_mbuf_trim(top, sr->raw_data.max_bytes);
 420  445                  MBC_ATTACH_MBUF(&sr->raw_data, top);
 421  446                  break;
 422  447  
 423  448          case STYPE_IPC:
 424  449                  sr->raw_data.max_bytes = vdb->vdb_uio.uio_resid;
 425  450                  top = smb_mbuf_allocate(&vdb->vdb_uio);
 426  451  
↓ open down ↓ 33 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX