1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-24 21:34:56 +03:00

smbd: Introduce handle_share_mode_lease()

This consolidates the core share_mode_lock access of open_file_ntcreate
into one routine.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
Volker Lendecke 2019-08-07 12:15:45 +02:00 committed by Jeremy Allison
parent d4e98b8ae5
commit 385a7fb196

View File

@ -2339,6 +2339,66 @@ static NTSTATUS grant_fsp_oplock_type(struct files_struct *fsp,
return NT_STATUS_OK;
}
static NTSTATUS handle_share_mode_lease(
files_struct *fsp,
struct share_mode_lock *lck,
uint32_t create_disposition,
uint32_t access_mask,
uint32_t share_access,
int oplock_request,
const struct smb2_lease *lease,
bool first_open_attempt)
{
bool sharing_violation = false;
bool delay = false;
NTSTATUS status;
status = open_mode_check(
fsp->conn, lck, access_mask, share_access);
if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
sharing_violation = true;
status = NT_STATUS_OK; /* handled later */
}
if (!NT_STATUS_IS_OK(status)) {
return status;
}
if (oplock_request == INTERNAL_OPEN_ONLY) {
if (sharing_violation) {
DBG_DEBUG("Sharing violation for internal open\n");
return NT_STATUS_SHARING_VIOLATION;
}
/*
* Internal opens never do oplocks or leases. We don't
* need to go through delay_for_oplock().
*/
fsp->oplock_type = NO_OPLOCK;
return NT_STATUS_OK;
}
delay = delay_for_oplock(
fsp,
oplock_request,
lease,
lck,
sharing_violation,
create_disposition,
first_open_attempt);
if (delay) {
return NT_STATUS_RETRY;
}
if (sharing_violation) {
return NT_STATUS_SHARING_VIOLATION;
}
status = grant_fsp_oplock_type(fsp, lck, oplock_request, lease);
return status;
}
static bool request_timed_out(struct smb_request *req, struct timeval timeout)
{
struct timeval now, end_time;
@ -3460,50 +3520,23 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
return NT_STATUS_DELETE_PENDING;
}
status = open_mode_check(conn, lck,
access_mask, share_access);
if (req != NULL) {
/*
* Handle oplocks, deferring the request if delay_for_oplock()
* triggered a break message and we have to wait for the break
* response.
*/
bool delay;
bool sharing_violation = NT_STATUS_EQUAL(
status, NT_STATUS_SHARING_VIOLATION);
delay = delay_for_oplock(fsp, oplock_request, lease, lck,
sharing_violation,
create_disposition,
first_open_attempt);
if (delay) {
schedule_defer_open(lck, fsp->file_id, req);
TALLOC_FREE(lck);
fd_close(fsp);
return NT_STATUS_SHARING_VIOLATION;
}
}
if (!NT_STATUS_IS_OK(status)) {
SMB_ASSERT(NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION));
status = handle_share_mode_lease(
fsp,
lck,
create_disposition,
access_mask,
share_access,
oplock_request,
lease,
first_open_attempt);
if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
schedule_defer_open(lck, fsp->file_id, req);
TALLOC_FREE(lck);
fd_close(fsp);
return NT_STATUS_SHARING_VIOLATION;
}
/*
* Setup the oplock info in both the shared memory and
* file structs.
*/
status = grant_fsp_oplock_type(
fsp,
lck,
oplock_request,
lease);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(lck);
fd_close(fsp);