summaryrefslogtreecommitdiff
path: root/source3/smbd/smb2_lock.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2010-05-06 15:39:21 -0700
committerJeremy Allison <jra@samba.org>2010-05-06 15:39:21 -0700
commit1c7a60ef41d76526384d6b9e4ba03d3df251fe06 (patch)
tree1c334e32a22290d3ca4b8cdc9fabb80fa70a3344 /source3/smbd/smb2_lock.c
parent82900073fb38b8d86fe2b9ef2ef5cd9fabfbaec7 (diff)
downloadsamba-1c7a60ef41d76526384d6b9e4ba03d3df251fe06.tar.gz
samba-1c7a60ef41d76526384d6b9e4ba03d3df251fe06.tar.bz2
samba-1c7a60ef41d76526384d6b9e4ba03d3df251fe06.zip
Fix cancel by close lock test.
Jeremy.
Diffstat (limited to 'source3/smbd/smb2_lock.c')
-rw-r--r--source3/smbd/smb2_lock.c60
1 files changed, 36 insertions, 24 deletions
diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c
index 63e43fa832..b106c5fad1 100644
--- a/source3/smbd/smb2_lock.c
+++ b/source3/smbd/smb2_lock.c
@@ -3,6 +3,7 @@
Core SMB2 server
Copyright (C) Stefan Metzmacher 2009
+ Copyright (C) Jeremy Allison 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -29,6 +30,16 @@ struct smbd_smb2_lock_element {
uint32_t flags;
};
+struct smbd_smb2_lock_state {
+ struct smbd_smb2_request *smb2req;
+ struct smb_request *smb1req;
+ struct blocking_lock_record *blr;
+ uint16_t lock_count;
+ struct smbd_lock_element *locks;
+};
+
+static void remove_pending_lock(TALLOC_CTX *mem_ctx, struct blocking_lock_record *blr);
+
static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct smbd_smb2_request *smb2req,
@@ -130,22 +141,32 @@ NTSTATUS smbd_smb2_request_process_lock(struct smbd_smb2_request *req)
static void smbd_smb2_request_lock_done(struct tevent_req *subreq)
{
- struct smbd_smb2_request *req = tevent_req_callback_data(subreq,
+ struct smbd_smb2_request *smb2req = tevent_req_callback_data(subreq,
struct smbd_smb2_request);
DATA_BLOB outbody;
NTSTATUS status;
NTSTATUS error; /* transport error */
- if (req->cancelled) {
+ if (smb2req->cancelled) {
const uint8_t *inhdr = (const uint8_t *)
- req->in.vector[req->current_idx].iov_base;
+ smb2req->in.vector[smb2req->current_idx].iov_base;
uint64_t mid = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
+ struct smbd_smb2_lock_state *state;
DEBUG(10,("smbd_smb2_request_lock_done: cancelled mid %llu\n",
(unsigned long long)mid ));
- error = smbd_smb2_request_error(req, NT_STATUS_CANCELLED);
+
+ state = tevent_req_data(smb2req->subreq,
+ struct smbd_smb2_lock_state);
+
+ SMB_ASSERT(state);
+ SMB_ASSERT(state->blr);
+
+ remove_pending_lock(state, state->blr);
+
+ error = smbd_smb2_request_error(smb2req, NT_STATUS_CANCELLED);
if (!NT_STATUS_IS_OK(error)) {
- smbd_server_connection_terminate(req->sconn,
+ smbd_server_connection_terminate(smb2req->sconn,
nt_errstr(error));
return;
}
@@ -155,20 +176,20 @@ static void smbd_smb2_request_lock_done(struct tevent_req *subreq)
status = smbd_smb2_lock_recv(subreq);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
- error = smbd_smb2_request_error(req, status);
+ error = smbd_smb2_request_error(smb2req, status);
if (!NT_STATUS_IS_OK(error)) {
- smbd_server_connection_terminate(req->sconn,
+ smbd_server_connection_terminate(smb2req->sconn,
nt_errstr(error));
return;
}
return;
}
- outbody = data_blob_talloc(req->out.vector, NULL, 0x04);
+ outbody = data_blob_talloc(smb2req->out.vector, NULL, 0x04);
if (outbody.data == NULL) {
- error = smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
+ error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
if (!NT_STATUS_IS_OK(error)) {
- smbd_server_connection_terminate(req->sconn,
+ smbd_server_connection_terminate(smb2req->sconn,
nt_errstr(error));
return;
}
@@ -178,22 +199,14 @@ static void smbd_smb2_request_lock_done(struct tevent_req *subreq)
SSVAL(outbody.data, 0x00, 0x04); /* struct size */
SSVAL(outbody.data, 0x02, 0); /* reserved */
- error = smbd_smb2_request_done(req, outbody, NULL);
+ error = smbd_smb2_request_done(smb2req, outbody, NULL);
if (!NT_STATUS_IS_OK(error)) {
- smbd_server_connection_terminate(req->sconn,
+ smbd_server_connection_terminate(smb2req->sconn,
nt_errstr(error));
return;
}
}
-struct smbd_smb2_lock_state {
- struct smbd_smb2_request *smb2req;
- struct smb_request *smb1req;
- struct blocking_lock_record *blr;
- uint16_t lock_count;
- struct smbd_lock_element *locks;
-};
-
static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct smbd_smb2_request *smb2req,
@@ -853,7 +866,7 @@ void cancel_pending_lock_requests_by_fid_smb2(files_struct *fsp,
}
inhdr = (const uint8_t *)smb2req->in.vector[i].iov_base;
- if (IVAL(inhdr, SMB2_HDR_OPCODE) != SMB2_OP_LOCK) {
+ if (SVAL(inhdr, SMB2_HDR_OPCODE) != SMB2_OP_LOCK) {
/* Not a lock call. */
continue;
}
@@ -890,8 +903,7 @@ void cancel_pending_lock_requests_by_fid_smb2(files_struct *fsp,
blr->lock_flav,
blr);
- /* Finally cancel the request. */
- smb2req->cancelled = true;
- tevent_req_cancel(smb2req->subreq);
+ /* Finally end the request. */
+ tevent_req_nterror(smb2req->subreq, NT_STATUS_RANGE_NOT_LOCKED);
}
}