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-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-2370 unable to save/modify files (zip,notepad,excel) on CIFS share from Windows 7
NEX-2039 Codenomicon failure in smb_write
re #7815 SMB server delivers old modification time...

@@ -19,11 +19,11 @@
  * CDDL HEADER END
  */
 
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
  */
 
 #include <sys/sdt.h>
 #include <smbsrv/smb_kproto.h>
 #include <smbsrv/smb_fsops.h>

@@ -59,21 +59,19 @@
 
         param->rw_count = (uint32_t)count;
         param->rw_offset = (uint64_t)off;
         param->rw_vdb.vdb_uio.uio_loffset = (offset_t)param->rw_offset;
 
-        DTRACE_SMB_2(op__Write__start, smb_request_t *, sr,
-            smb_rw_param_t *, param);
+        DTRACE_SMB_START(op__Write, smb_request_t *, sr); /* arg.rw */
 
         return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 }
 
 void
 smb_post_write(smb_request_t *sr)
 {
-        DTRACE_SMB_2(op__Write__done, smb_request_t *, sr,
-            smb_rw_param_t *, sr->arg.rw);
+        DTRACE_SMB_DONE(op__Write, smb_request_t *, sr); /* arg.rw */
 
         kmem_free(sr->arg.rw, sizeof (smb_rw_param_t));
 }
 
 smb_sdrc_t

@@ -149,21 +147,19 @@
         }
 
         param->rw_count = (uint32_t)count;
         param->rw_offset = (uint64_t)off;
 
-        DTRACE_SMB_2(op__WriteAndClose__start, smb_request_t *, sr,
-            smb_rw_param_t *, param);
+        DTRACE_SMB_START(op__WriteAndClose, smb_request_t *, sr); /* arg.rw */
 
         return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 }
 
 void
 smb_post_write_and_close(smb_request_t *sr)
 {
-        DTRACE_SMB_2(op__WriteAndClose__done, smb_request_t *, sr,
-            smb_rw_param_t *, sr->arg.rw);
+        DTRACE_SMB_DONE(op__WriteAndClose, smb_request_t *, sr); /* arg.rw */
 
         kmem_free(sr->arg.rw, sizeof (smb_rw_param_t));
 }
 
 smb_sdrc_t

@@ -247,29 +243,28 @@
         rc = smbsr_decode_vwv(sr, "wwlw", &sr->smb_fid, &count, &off, &remcnt);
 
         param->rw_count = (uint32_t)count;
         param->rw_offset = (uint64_t)off;
 
-        DTRACE_SMB_2(op__WriteAndUnlock__start, smb_request_t *, sr,
-            smb_rw_param_t *, param);
+        DTRACE_SMB_START(op__WriteAndUnlock, smb_request_t *, sr); /* arg.rw */
 
         return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 }
 
 void
 smb_post_write_and_unlock(smb_request_t *sr)
 {
-        DTRACE_SMB_2(op__WriteAndUnlock__done, smb_request_t *, sr,
-            smb_rw_param_t *, sr->arg.rw);
+        DTRACE_SMB_DONE(op__WriteAndUnlock, smb_request_t *, sr); /* arg.rw */
 
         kmem_free(sr->arg.rw, sizeof (smb_rw_param_t));
 }
 
 smb_sdrc_t
 smb_com_write_and_unlock(smb_request_t *sr)
 {
         smb_rw_param_t *param = sr->arg.rw;
+        uint32_t lk_pid;
         uint32_t status;
         int rc = 0;
 
         if (STYPE_ISDSK(sr->tid_tree->t_res_type) == 0) {
                 smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERRnoaccess);

@@ -304,12 +299,16 @@
                 if (sr->smb_error.status != NT_STATUS_FILE_LOCK_CONFLICT)
                         smbsr_errno(sr, rc);
                 return (SDRC_ERROR);
         }
 
-        status = smb_unlock_range(sr, sr->fid_ofile->f_node, param->rw_offset,
-            (uint64_t)param->rw_count);
+
+        /* Note: SMB1 locking uses 16-bit PIDs. */
+        lk_pid = sr->smb_pid & 0xFFFF;
+
+        status = smb_unlock_range(sr, param->rw_offset,
+            (uint64_t)param->rw_count, lk_pid);
         if (status != NT_STATUS_SUCCESS) {
                 smbsr_error(sr, NT_STATUS_RANGE_NOT_LOCKED,
                     ERRDOS, ERROR_NOT_LOCKED);
                 return (SDRC_ERROR);
         }

@@ -318,10 +317,39 @@
             (uint16_t)param->rw_count, 0);
         return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 }
 
 /*
+ * The SMB_COM_WRITE_RAW protocol was a negotiated option introduced in
+ * SMB Core Plus to maximize performance when writing a large block
+ * of data to a server.  It's obsolete and no longer supported.
+ *
+ * We keep a handler for it so the dtrace provider can see if
+ * the client tried to use this command.
+ */
+smb_sdrc_t
+smb_pre_write_raw(smb_request_t *sr)
+{
+        DTRACE_SMB_START(op__WriteRaw, smb_request_t *, sr);
+        return (SDRC_SUCCESS);
+}
+
+void
+smb_post_write_raw(smb_request_t *sr)
+{
+        DTRACE_SMB_DONE(op__WriteRaw, smb_request_t *, sr);
+}
+
+smb_sdrc_t
+smb_com_write_raw(struct smb_request *sr)
+{
+        smbsr_error(sr, NT_STATUS_NOT_SUPPORTED, ERRDOS,
+            ERROR_NOT_SUPPORTED);
+        return (SDRC_ERROR);
+}
+
+/*
  * Write bytes to a file (SMB Core).  This request was extended in
  * LM 0.12 to support 64-bit offsets, indicated by sending a wct of
  * 14, instead of 12, and including additional offset information.
  *
  * A ByteCount of 0 does not truncate the file - use SMB_COM_WRITE

@@ -380,21 +408,19 @@
          */
         if ((sr->session->capabilities & CAP_LARGE_WRITEX) != 0 ||
             (sr->smb_data.max_bytes > (sr->smb_data.chain_offset + 0xFFFF)))
                 param->rw_count |= ((uint32_t)datalen_high << 16);
 
-        DTRACE_SMB_2(op__WriteX__start, smb_request_t *, sr,
-            smb_rw_param_t *, param);
+        DTRACE_SMB_START(op__WriteX, smb_request_t *, sr); /* arg.rw */
 
         return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 }
 
 void
 smb_post_write_andx(smb_request_t *sr)
 {
-        DTRACE_SMB_2(op__WriteX__done, smb_request_t *, sr,
-            smb_rw_param_t *, sr->arg.rw);
+        DTRACE_SMB_DONE(op__WriteX, smb_request_t *, sr); /* arg.rw */
 
         kmem_free(sr->arg.rw, sizeof (smb_rw_param_t));
 }
 
 smb_sdrc_t

@@ -483,11 +509,11 @@
                 if (SMB_WRMODE_IS_STABLE(param->rw_mode) ||
                     (node->flags & NODE_FLAGS_WRITE_THROUGH)) {
                         stability = FSYNC;
                 }
 
-                rc = smb_fsop_write(sr, sr->user_cr, node,
+                rc = smb_fsop_write(sr, sr->user_cr, node, ofile,
                     &param->rw_vdb.vdb_uio, &lcount, stability);
 
                 if (rc)
                         return (rc);
 

@@ -500,12 +526,12 @@
                  * However, keep track of the fact that
                  * we have written data via this handle.
                  */
                 ofile->f_written = B_TRUE;
 
-                if (!smb_node_is_dir(node))
-                        smb_oplock_break_levelII(node);
+                /* This revokes read cache delegations. */
+                (void) smb_oplock_break_WRITE(node, ofile);
 
                 param->rw_count = lcount;
                 break;
 
         case STYPE_IPC: