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));
}