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,29 **** * CDDL HEADER END */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. ! * Copyright 2014 Nexenta Systems, Inc. All rights reserved. */ #include <sys/sdt.h> #include <smbsrv/smb_kproto.h> #include <smbsrv/smb_fsops.h> --- 19,29 ---- * CDDL HEADER END */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. 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,79 **** 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); 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); kmem_free(sr->arg.rw, sizeof (smb_rw_param_t)); } smb_sdrc_t --- 59,77 ---- 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_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_DONE(op__Write, smb_request_t *, sr); /* arg.rw */ kmem_free(sr->arg.rw, sizeof (smb_rw_param_t)); } smb_sdrc_t
*** 149,169 **** } 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); 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); kmem_free(sr->arg.rw, sizeof (smb_rw_param_t)); } smb_sdrc_t --- 147,165 ---- } param->rw_count = (uint32_t)count; param->rw_offset = (uint64_t)off; ! 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_DONE(op__WriteAndClose, smb_request_t *, sr); /* arg.rw */ kmem_free(sr->arg.rw, sizeof (smb_rw_param_t)); } smb_sdrc_t
*** 247,275 **** 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); 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); 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 status; int rc = 0; if (STYPE_ISDSK(sr->tid_tree->t_res_type) == 0) { smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERRnoaccess); --- 243,270 ---- 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_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_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,315 **** 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); if (status != NT_STATUS_SUCCESS) { smbsr_error(sr, NT_STATUS_RANGE_NOT_LOCKED, ERRDOS, ERROR_NOT_LOCKED); return (SDRC_ERROR); } --- 299,314 ---- if (sr->smb_error.status != NT_STATUS_FILE_LOCK_CONFLICT) smbsr_errno(sr, rc); return (SDRC_ERROR); } ! ! /* 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,327 **** --- 317,355 ---- (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,400 **** */ 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); 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); kmem_free(sr->arg.rw, sizeof (smb_rw_param_t)); } smb_sdrc_t --- 408,426 ---- */ 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_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_DONE(op__WriteX, smb_request_t *, sr); /* arg.rw */ kmem_free(sr->arg.rw, sizeof (smb_rw_param_t)); } smb_sdrc_t
*** 483,493 **** 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, &param->rw_vdb.vdb_uio, &lcount, stability); if (rc) return (rc); --- 509,519 ---- 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, ofile, &param->rw_vdb.vdb_uio, &lcount, stability); if (rc) return (rc);
*** 500,511 **** * 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); param->rw_count = lcount; break; case STYPE_IPC: --- 526,537 ---- * However, keep track of the fact that * we have written data via this handle. */ ofile->f_written = B_TRUE; ! /* This revokes read cache delegations. */ ! (void) smb_oplock_break_WRITE(node, ofile); param->rw_count = lcount; break; case STYPE_IPC: