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>
SMB-131 Don't allow setting delete-on-close on non empty dirs
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)

*** 18,37 **** * * CDDL HEADER END */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. ! * Copyright 2014 Nexenta Systems, Inc. All rights reserved. */ /* * Common functions supporting both: * SMB1 Trans2 Set File/Path Info, * SMB2 Set File Info */ ! #include <smbsrv/smb_kproto.h> #include <smbsrv/smb_fsops.h> /* * smb_set_basic_info * [MS-FSCC] 2.4.7 --- 18,37 ---- * * CDDL HEADER END */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. ! * Copyright 2017 Nexenta Systems, Inc. All rights reserved. */ /* * Common functions supporting both: * SMB1 Trans2 Set File/Path Info, * SMB2 Set File Info */ ! #include <smbsrv/smb2_kproto.h> #include <smbsrv/smb_fsops.h> /* * smb_set_basic_info * [MS-FSCC] 2.4.7
*** 106,136 **** smb_set_eof_info(smb_request_t *sr, smb_setinfo_t *si) { smb_attr_t *attr = &si->si_attr; smb_node_t *node = si->si_node; uint64_t eof; int rc; if (smb_mbc_decodef(&si->si_data, "q", &eof) != 0) return (NT_STATUS_INFO_LENGTH_MISMATCH); if (smb_node_is_dir(node)) return (NT_STATUS_INVALID_PARAMETER); ! /* If opened by path, break exclusive oplock */ ! if (sr->fid_ofile == NULL) ! (void) smb_oplock_break(sr, node, ! SMB_OPLOCK_BREAK_EXCLUSIVE | SMB_OPLOCK_BREAK_TO_NONE); bzero(attr, sizeof (*attr)); attr->sa_mask = SMB_AT_SIZE; attr->sa_vattr.va_size = (u_offset_t)eof; rc = smb_node_setattr(sr, node, sr->user_cr, sr->fid_ofile, attr); if (rc != 0) return (smb_errno2status(rc)); - smb_oplock_break_levelII(node); return (0); } /* * smb_set_alloc_info --- 106,142 ---- smb_set_eof_info(smb_request_t *sr, smb_setinfo_t *si) { smb_attr_t *attr = &si->si_attr; smb_node_t *node = si->si_node; uint64_t eof; + uint32_t status; int rc; if (smb_mbc_decodef(&si->si_data, "q", &eof) != 0) return (NT_STATUS_INFO_LENGTH_MISMATCH); if (smb_node_is_dir(node)) return (NT_STATUS_INVALID_PARAMETER); ! status = smb_oplock_break_SETINFO(node, sr->fid_ofile, ! FileEndOfFileInformation); ! if (status == NT_STATUS_OPLOCK_BREAK_IN_PROGRESS) { ! if (sr->session->dialect >= SMB_VERS_2_BASE) ! (void) smb2sr_go_async(sr); ! (void) smb_oplock_wait_break(node, 0); ! status = 0; ! } ! if (status != 0) ! return (status); bzero(attr, sizeof (*attr)); attr->sa_mask = SMB_AT_SIZE; attr->sa_vattr.va_size = (u_offset_t)eof; rc = smb_node_setattr(sr, node, sr->user_cr, sr->fid_ofile, attr); if (rc != 0) return (smb_errno2status(rc)); return (0); } /* * smb_set_alloc_info
*** 142,172 **** smb_set_alloc_info(smb_request_t *sr, smb_setinfo_t *si) { smb_attr_t *attr = &si->si_attr; smb_node_t *node = si->si_node; uint64_t allocsz; int rc; if (smb_mbc_decodef(&si->si_data, "q", &allocsz) != 0) return (NT_STATUS_INFO_LENGTH_MISMATCH); if (smb_node_is_dir(node)) return (NT_STATUS_INVALID_PARAMETER); ! /* If opened by path, break exclusive oplock */ ! if (sr->fid_ofile == NULL) ! (void) smb_oplock_break(sr, node, ! SMB_OPLOCK_BREAK_EXCLUSIVE | SMB_OPLOCK_BREAK_TO_NONE); bzero(attr, sizeof (*attr)); attr->sa_mask = SMB_AT_ALLOCSZ; attr->sa_allocsz = (u_offset_t)allocsz; rc = smb_node_setattr(sr, node, sr->user_cr, sr->fid_ofile, attr); if (rc != 0) return (smb_errno2status(rc)); - smb_oplock_break_levelII(node); return (0); } /* * smb_set_disposition_info --- 148,184 ---- smb_set_alloc_info(smb_request_t *sr, smb_setinfo_t *si) { smb_attr_t *attr = &si->si_attr; smb_node_t *node = si->si_node; uint64_t allocsz; + uint32_t status; int rc; if (smb_mbc_decodef(&si->si_data, "q", &allocsz) != 0) return (NT_STATUS_INFO_LENGTH_MISMATCH); if (smb_node_is_dir(node)) return (NT_STATUS_INVALID_PARAMETER); ! status = smb_oplock_break_SETINFO(node, sr->fid_ofile, ! FileAllocationInformation); ! if (status == NT_STATUS_OPLOCK_BREAK_IN_PROGRESS) { ! if (sr->session->dialect >= SMB_VERS_2_BASE) ! (void) smb2sr_go_async(sr); ! (void) smb_oplock_wait_break(node, 0); ! status = 0; ! } ! if (status != 0) ! return (status); bzero(attr, sizeof (*attr)); attr->sa_mask = SMB_AT_ALLOCSZ; attr->sa_allocsz = (u_offset_t)allocsz; rc = smb_node_setattr(sr, node, sr->user_cr, sr->fid_ofile, attr); if (rc != 0) return (smb_errno2status(rc)); return (0); } /* * smb_set_disposition_info
*** 209,231 **** smb_set_disposition_info(smb_request_t *sr, smb_setinfo_t *si) { smb_node_t *node = si->si_node; smb_ofile_t *of = sr->fid_ofile; uint8_t mark_delete; uint32_t flags = 0; if (smb_mbc_decodef(&si->si_data, "b", &mark_delete) != 0) return (NT_STATUS_INFO_LENGTH_MISMATCH); if ((of == NULL) || !(smb_ofile_granted_access(of) & DELETE)) return (NT_STATUS_ACCESS_DENIED); ! if (mark_delete) { ! if (SMB_TREE_SUPPORTS_CATIA(sr)) ! flags |= SMB_CATIA; ! return (smb_node_set_delete_on_close(node, of->f_cr, flags)); ! } else { smb_node_reset_delete_on_close(node); } ! return (NT_STATUS_SUCCESS); } --- 221,258 ---- smb_set_disposition_info(smb_request_t *sr, smb_setinfo_t *si) { smb_node_t *node = si->si_node; smb_ofile_t *of = sr->fid_ofile; uint8_t mark_delete; + uint32_t status; uint32_t flags = 0; if (smb_mbc_decodef(&si->si_data, "b", &mark_delete) != 0) return (NT_STATUS_INFO_LENGTH_MISMATCH); if ((of == NULL) || !(smb_ofile_granted_access(of) & DELETE)) return (NT_STATUS_ACCESS_DENIED); ! if (mark_delete == 0) { smb_node_reset_delete_on_close(node); + return (NT_STATUS_SUCCESS); } ! /* ! * Break any oplock handle caching. ! */ ! status = smb_oplock_break_SETINFO(node, of, ! FileDispositionInformation); ! if (status == NT_STATUS_OPLOCK_BREAK_IN_PROGRESS) { ! if (sr->session->dialect >= SMB_VERS_2_BASE) ! (void) smb2sr_go_async(sr); ! (void) smb_oplock_wait_break(node, 0); ! status = 0; ! } ! if (status != 0) ! return (status); ! ! if (SMB_TREE_SUPPORTS_CATIA(sr)) ! flags |= SMB_CATIA; ! ! return (smb_node_set_delete_on_close(node, of->f_cr, flags)); }