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-4538 SMB1 create file should support extended_response format (2)
NEX-6116 Failures in smbtorture raw.open
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Include this commit if upstreaming/backporting any of:
NEX-4540 SMB server declines EA support incorrectly
NEX-4239 smbtorture create failures re. allocation size
(illumos) 6398 SMB should support path names longer than 1024
NEX-4538 SMB1 create file should support extended_response format
Reviewed by: Matt Barden <Matt.Barden@nexenta.com>
Reviewed by: Bayard Bell <bayard.bell@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-63 taskq_create_proc ... TQ_DYNAMIC puts tasks in p0
re #11974 CIFS Share - Tree connect fails from Windows 7 Clients
re #14152 Race between ipmi_submit_driver_request() and kcs_loop() (sync with illumos fix 3902)
SMB-46 File handle leaks exposed by mtime fixes (rm 7815)
re #7815 SMB server delivers old modification time...

*** 18,28 **** * * CDDL HEADER END */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. ! * Copyright 2013 Nexenta Systems, Inc. All rights reserved. */ /* * This command is used to create or open a file or directory, when EAs * or an SD must be applied to the file. The functionality is similar --- 18,28 ---- * * CDDL HEADER END */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. ! * Copyright 2017 Nexenta Systems, Inc. All rights reserved. */ /* * This command is used to create or open a file or directory, when EAs * or an SD must be applied to the file. The functionality is similar
*** 34,43 **** --- 34,45 ---- */ #include <smbsrv/smb_kproto.h> #include <smbsrv/smb_fsops.h> + extern int smb_nt_create_enable_extended_response; + /* * smb_nt_transact_create * * This command is used to create or open a file or directory, when EAs * or an SD must be applied to the file. The request parameter block
*** 81,93 **** &SecurityFlags); if (rc == 0) { if (NameLength == 0) { op->fqi.fq_path.pn_path = "\\"; ! } else if (NameLength >= MAXPATHLEN) { ! smbsr_error(sr, NT_STATUS_OBJECT_PATH_NOT_FOUND, ! ERRDOS, ERROR_PATH_NOT_FOUND); rc = -1; } else { rc = smb_mbc_decodef(&xa->req_param_mb, "%#u", sr, NameLength, &op->fqi.fq_path.pn_path); } --- 83,95 ---- &SecurityFlags); if (rc == 0) { if (NameLength == 0) { op->fqi.fq_path.pn_path = "\\"; ! } else if (NameLength >= SMB_MAXPATHLEN) { ! smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID, ! ERRDOS, ERROR_INVALID_NAME); rc = -1; } else { rc = smb_mbc_decodef(&xa->req_param_mb, "%#u", sr, NameLength, &op->fqi.fq_path.pn_path); }
*** 111,153 **** *op->sd = sd; } else { op->sd = NULL; } ! DTRACE_SMB_2(op__NtTransactCreate__start, smb_request_t *, sr, ! struct open_param *, op); return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); } void smb_post_nt_transact_create(smb_request_t *sr, smb_xa_t *xa) { smb_sd_t *sd = sr->arg.open.sd; ! DTRACE_SMB_2(op__NtTransactCreate__done, smb_request_t *, sr, ! smb_xa_t *, xa); if (sd) { smb_sd_term(sd); kmem_free(sd, sizeof (smb_sd_t)); } ! if (sr->arg.open.dir != NULL) smb_ofile_release(sr->arg.open.dir); } smb_sdrc_t smb_nt_transact_create(smb_request_t *sr, smb_xa_t *xa) { struct open_param *op = &sr->arg.open; ! uint8_t DirFlag; ! smb_attr_t attr; smb_ofile_t *of; - uint32_t status; int rc; if ((op->create_options & FILE_DELETE_ON_CLOSE) && !(op->desired_access & DELETE)) { smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, ERRDOS, ERRbadaccess); return (SDRC_ERROR); --- 113,171 ---- *op->sd = sd; } else { op->sd = NULL; } ! DTRACE_SMB_START(op__NtTransactCreate, smb_request_t *, sr); return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); } void smb_post_nt_transact_create(smb_request_t *sr, smb_xa_t *xa) { smb_sd_t *sd = sr->arg.open.sd; + _NOTE(ARGUNUSED(xa)) ! DTRACE_SMB_DONE(op__NtTransactCreate, smb_request_t *, sr); if (sd) { smb_sd_term(sd); kmem_free(sd, sizeof (smb_sd_t)); } ! if (sr->arg.open.dir != NULL) { smb_ofile_release(sr->arg.open.dir); + sr->arg.open.dir = NULL; + } } + /* + * A lot like smb_com_nt_create_andx + */ smb_sdrc_t smb_nt_transact_create(smb_request_t *sr, smb_xa_t *xa) { struct open_param *op = &sr->arg.open; ! smb_attr_t *ap = &op->fqi.fq_fattr; smb_ofile_t *of; int rc; + uint8_t DirFlag; + uint32_t status; + if (op->create_options & ~SMB_NTCREATE_VALID_OPTIONS) { + smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, + ERRDOS, ERROR_INVALID_PARAMETER); + return (SDRC_ERROR); + } + + if (op->create_options & FILE_OPEN_BY_FILE_ID) { + smbsr_error(sr, NT_STATUS_NOT_SUPPORTED, + ERRDOS, ERROR_NOT_SUPPORTED); + return (SDRC_ERROR); + } + if ((op->create_options & FILE_DELETE_ON_CLOSE) && !(op->desired_access & DELETE)) { smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, ERRDOS, ERRbadaccess); return (SDRC_ERROR);
*** 181,197 **** return (SDRC_ERROR); } op->fqi.fq_dnode = op->dir->f_node; } - op->op_oplock_levelII = B_TRUE; - status = smb_common_open(sr); if (status != NT_STATUS_SUCCESS) { smbsr_status(sr, status, 0, 0); return (SDRC_ERROR); } /* * NB: after the above smb_common_open() success, * we have a handle allocated (sr->fid_ofile). * If we don't return success, we must close it. --- 199,217 ---- return (SDRC_ERROR); } op->fqi.fq_dnode = op->dir->f_node; } status = smb_common_open(sr); if (status != NT_STATUS_SUCCESS) { smbsr_status(sr, status, 0, 0); return (SDRC_ERROR); } + if (op->op_oplock_level != SMB_OPLOCK_NONE) { + /* Oplock req. in op->op_oplock_level etc. */ + smb1_oplock_acquire(sr, B_TRUE); + } /* * NB: after the above smb_common_open() success, * we have a handle allocated (sr->fid_ofile). * If we don't return success, we must close it.
*** 200,261 **** switch (sr->tid_tree->t_res_type & STYPE_MASK) { case STYPE_DISKTREE: case STYPE_PRINTQ: if (op->create_options & FILE_DELETE_ON_CLOSE) ! smb_ofile_set_delete_on_close(of); ! DirFlag = smb_node_is_dir(of->f_node) ? 1 : 0; - bzero(&attr, sizeof (attr)); - attr.sa_mask = SMB_AT_ALL; - rc = smb_node_getattr(sr, of->f_node, of->f_cr, of, &attr); - if (rc != 0) { - smbsr_errno(sr, rc); - goto errout; - } - - rc = smb_mbc_encodef(&xa->rep_param_mb, "b.wllTTTTlqqwwb", - op->op_oplock_level, - sr->smb_fid, - op->action_taken, - 0, /* EaErrorOffset */ - &attr.sa_crtime, - &attr.sa_vattr.va_atime, - &attr.sa_vattr.va_mtime, - &attr.sa_vattr.va_ctime, - op->dattr & FILE_ATTRIBUTE_MASK, - attr.sa_allocsz, - attr.sa_vattr.va_size, - op->ftype, - op->devstate, - DirFlag); break; case STYPE_IPC: ! bzero(&attr, sizeof (smb_attr_t)); ! rc = smb_mbc_encodef(&xa->rep_param_mb, "b.wllTTTTlqqwwb", ! 0, ! sr->smb_fid, ! op->action_taken, ! 0, /* EaErrorOffset */ ! &attr.sa_crtime, ! &attr.sa_vattr.va_atime, ! &attr.sa_vattr.va_mtime, ! &attr.sa_vattr.va_ctime, ! op->dattr, ! 0x1000LL, ! 0LL, ! op->ftype, ! op->devstate, ! 0); break; default: smbsr_error(sr, NT_STATUS_INVALID_DEVICE_REQUEST, ERRDOS, ERROR_INVALID_FUNCTION); goto errout; } return (SDRC_SUCCESS); errout: smb_ofile_close(of, 0); return (SDRC_ERROR); --- 220,293 ---- switch (sr->tid_tree->t_res_type & STYPE_MASK) { case STYPE_DISKTREE: case STYPE_PRINTQ: if (op->create_options & FILE_DELETE_ON_CLOSE) ! smb_ofile_set_delete_on_close(sr, of); DirFlag = smb_node_is_dir(of->f_node) ? 1 : 0; break; case STYPE_IPC: ! DirFlag = 0; break; default: smbsr_error(sr, NT_STATUS_INVALID_DEVICE_REQUEST, ERRDOS, ERROR_INVALID_FUNCTION); goto errout; } + + if ((op->nt_flags & NT_CREATE_FLAG_EXTENDED_RESPONSE) != 0 && + smb_nt_create_enable_extended_response != 0) { + uint32_t MaxAccess = 0; + if (of->f_node != NULL) { + smb_fsop_eaccess(sr, of->f_cr, of->f_node, &MaxAccess); + } + MaxAccess |= of->f_granted_access; + + rc = smb_mbc_encodef( + &xa->rep_param_mb, "bbwllTTTTlqqwwb16.qll", + op->op_oplock_level, /* (b) */ + 1, /* ResponseType (b) */ + sr->smb_fid, /* (w) */ + op->action_taken, /* (l) */ + 0, /* EaErrorOffset (l) */ + &ap->sa_crtime, /* (T) */ + &ap->sa_vattr.va_atime, /* (T) */ + &ap->sa_vattr.va_mtime, /* (T) */ + &ap->sa_vattr.va_ctime, /* (T) */ + op->dattr & FILE_ATTRIBUTE_MASK, /* (l) */ + ap->sa_allocsz, /* (q) */ + ap->sa_vattr.va_size, /* (q) */ + op->ftype, /* (w) */ + op->devstate, /* (w) */ + DirFlag, /* (b) */ + /* volume guid (16.) */ + op->fileid, /* (q) */ + MaxAccess, /* (l) */ + 0); /* guest access (l) */ + } else { + rc = smb_mbc_encodef( + &xa->rep_param_mb, "bbwllTTTTlqqwwb", + op->op_oplock_level, /* (b) */ + 0, /* ResponseType (b) */ + sr->smb_fid, /* (w) */ + op->action_taken, /* (l) */ + 0, /* EaErrorOffset (l) */ + &ap->sa_crtime, /* (T) */ + &ap->sa_vattr.va_atime, /* (T) */ + &ap->sa_vattr.va_mtime, /* (T) */ + &ap->sa_vattr.va_ctime, /* (T) */ + op->dattr & FILE_ATTRIBUTE_MASK, /* (l) */ + ap->sa_allocsz, /* (q) */ + ap->sa_vattr.va_size, /* (q) */ + op->ftype, /* (w) */ + op->devstate, /* (w) */ + DirFlag); /* (b) */ + } + + if (rc == 0) return (SDRC_SUCCESS); errout: smb_ofile_close(of, 0); return (SDRC_ERROR);