From: Stefan Metzmacher Date: Sat, 15 Aug 2009 08:01:38 +0000 (+0200) Subject: s3:smbd: implement SMB2 Cancel correctly. X-Git-Url: http://git.samba.org/?p=metze%2Fsamba%2Fwip.git;a=commitdiff_plain;h=d60f049eaf30d7a717291b2f295cc889efc7afa9 s3:smbd: implement SMB2 Cancel correctly. metze --- diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index 0b8ef5818ccd..bfed901bf4ad 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -264,7 +264,8 @@ NTSTATUS smbd_smb2_send_oplock_break(struct smbd_server_connection *sconn, uint64_t file_id_volatile, uint8_t oplock_level); -NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req); +NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req, + struct tevent_req *subreq); NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req); NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req); @@ -311,6 +312,12 @@ struct smbd_smb2_request { NTSTATUS next_status; + /* + * The sub request for async backend calls. + * This is used for SMB2 Cancel. + */ + struct tevent_req *subreq; + struct { /* the NBT header is not allocated */ uint8_t nbt_hdr[4]; diff --git a/source3/smbd/smb2_break.c b/source3/smbd/smb2_break.c index 449b8f6f4d7b..879d59f89e7e 100644 --- a/source3/smbd/smb2_break.c +++ b/source3/smbd/smb2_break.c @@ -77,11 +77,7 @@ NTSTATUS smbd_smb2_request_process_break(struct smbd_smb2_request *req) } tevent_req_set_callback(subreq, smbd_smb2_request_oplock_break_done, req); - if (tevent_req_is_in_progress(subreq)) { - return smbd_smb2_request_pending_queue(req); - } - - return NT_STATUS_OK; + return smbd_smb2_request_pending_queue(req, subreq); } static void smbd_smb2_request_oplock_break_done(struct tevent_req *subreq) diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c index 43b1fcb43deb..76fe504738dc 100644 --- a/source3/smbd/smb2_create.c +++ b/source3/smbd/smb2_create.c @@ -126,11 +126,7 @@ NTSTATUS smbd_smb2_request_process_create(struct smbd_smb2_request *req) } tevent_req_set_callback(subreq, smbd_smb2_request_create_done, req); - if (tevent_req_is_in_progress(subreq)) { - return smbd_smb2_request_pending_queue(req); - } - - return NT_STATUS_OK; + return smbd_smb2_request_pending_queue(req, subreq); } static void smbd_smb2_request_create_done(struct tevent_req *subreq) diff --git a/source3/smbd/smb2_find.c b/source3/smbd/smb2_find.c index f28ae1974b87..40ba320fc5d0 100644 --- a/source3/smbd/smb2_find.c +++ b/source3/smbd/smb2_find.c @@ -121,11 +121,7 @@ NTSTATUS smbd_smb2_request_process_find(struct smbd_smb2_request *req) } tevent_req_set_callback(subreq, smbd_smb2_request_find_done, req); - if (tevent_req_is_in_progress(subreq)) { - return smbd_smb2_request_pending_queue(req); - } - - return NT_STATUS_OK; + return smbd_smb2_request_pending_queue(req, subreq); } static void smbd_smb2_request_find_done(struct tevent_req *subreq) diff --git a/source3/smbd/smb2_flush.c b/source3/smbd/smb2_flush.c index bfdb2d87384a..561e69058225 100644 --- a/source3/smbd/smb2_flush.c +++ b/source3/smbd/smb2_flush.c @@ -70,11 +70,7 @@ NTSTATUS smbd_smb2_request_process_flush(struct smbd_smb2_request *req) } tevent_req_set_callback(subreq, smbd_smb2_request_flush_done, req); - if (tevent_req_is_in_progress(subreq)) { - return smbd_smb2_request_pending_queue(req); - } - - return NT_STATUS_OK; + return smbd_smb2_request_pending_queue(req, subreq); } static void smbd_smb2_request_flush_done(struct tevent_req *subreq) diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c index 1c247d7a0c57..3b50ab9cd7ae 100644 --- a/source3/smbd/smb2_getinfo.c +++ b/source3/smbd/smb2_getinfo.c @@ -114,11 +114,7 @@ NTSTATUS smbd_smb2_request_process_getinfo(struct smbd_smb2_request *req) } tevent_req_set_callback(subreq, smbd_smb2_request_getinfo_done, req); - if (tevent_req_is_in_progress(subreq)) { - return smbd_smb2_request_pending_queue(req); - } - - return NT_STATUS_OK; + return smbd_smb2_request_pending_queue(req, subreq); } static void smbd_smb2_request_getinfo_done(struct tevent_req *subreq) diff --git a/source3/smbd/smb2_ioctl.c b/source3/smbd/smb2_ioctl.c index 333616ab6143..0041e5f7d000 100644 --- a/source3/smbd/smb2_ioctl.c +++ b/source3/smbd/smb2_ioctl.c @@ -105,11 +105,7 @@ NTSTATUS smbd_smb2_request_process_ioctl(struct smbd_smb2_request *req) } tevent_req_set_callback(subreq, smbd_smb2_request_ioctl_done, req); - if (tevent_req_is_in_progress(subreq)) { - return smbd_smb2_request_pending_queue(req); - } - - return NT_STATUS_OK; + return smbd_smb2_request_pending_queue(req, subreq); } static void smbd_smb2_request_ioctl_done(struct tevent_req *subreq) diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c index eab95f666dbc..908e1cf8a4d5 100644 --- a/source3/smbd/smb2_lock.c +++ b/source3/smbd/smb2_lock.c @@ -124,11 +124,7 @@ NTSTATUS smbd_smb2_request_process_lock(struct smbd_smb2_request *req) } tevent_req_set_callback(subreq, smbd_smb2_request_lock_done, req); - if (tevent_req_is_in_progress(subreq)) { - return smbd_smb2_request_pending_queue(req); - } - - return NT_STATUS_OK; + return smbd_smb2_request_pending_queue(req, subreq); } static void smbd_smb2_request_lock_done(struct tevent_req *subreq) diff --git a/source3/smbd/smb2_notify.c b/source3/smbd/smb2_notify.c index 390bb578a43a..4d21b27ff831 100644 --- a/source3/smbd/smb2_notify.c +++ b/source3/smbd/smb2_notify.c @@ -92,11 +92,7 @@ NTSTATUS smbd_smb2_request_process_notify(struct smbd_smb2_request *req) } tevent_req_set_callback(subreq, smbd_smb2_request_notify_done, req); - if (tevent_req_is_in_progress(subreq)) { - return smbd_smb2_request_pending_queue(req); - } - - return NT_STATUS_OK; + return smbd_smb2_request_pending_queue(req, subreq); } static void smbd_smb2_request_notify_done(struct tevent_req *subreq) diff --git a/source3/smbd/smb2_read.c b/source3/smbd/smb2_read.c index 0b46567d6076..3f316e0b71aa 100644 --- a/source3/smbd/smb2_read.c +++ b/source3/smbd/smb2_read.c @@ -101,11 +101,7 @@ NTSTATUS smbd_smb2_request_process_read(struct smbd_smb2_request *req) } tevent_req_set_callback(subreq, smbd_smb2_request_read_done, req); - if (tevent_req_is_in_progress(subreq)) { - return smbd_smb2_request_pending_queue(req); - } - - return NT_STATUS_OK; + return smbd_smb2_request_pending_queue(req, subreq); } static void smbd_smb2_request_read_done(struct tevent_req *subreq) diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index edddccb9d942..9e5be404eff2 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -420,10 +420,10 @@ struct smbd_smb2_request_pending_state { static void smbd_smb2_request_pending_writev_done(struct tevent_req *subreq); -NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req) +NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req, + struct tevent_req *subreq) { struct smbd_smb2_request_pending_state *state; - struct tevent_req *subreq; uint8_t *outhdr; int i = req->current_idx; uint32_t flags; @@ -432,6 +432,13 @@ NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req) uint8_t *hdr; uint8_t *body; + if (!tevent_req_is_in_progress(subreq)) { + return NT_STATUS_OK; + } + + req->subreq = subreq; + subreq = NULL; + outhdr = (uint8_t *)req->out.vector[i].iov_base; flags = IVAL(outhdr, SMB2_HDR_FLAGS); @@ -559,8 +566,8 @@ static NTSTATUS smbd_smb2_request_process_cancel(struct smbd_smb2_request *req) } } - if (cur) { - /* TODO: try to cancel the request */ + if (cur && cur->subreq) { + tevent_req_cancel(cur->subreq); } return NT_STATUS_OK; @@ -797,6 +804,8 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req) { struct tevent_req *subreq; + req->subreq = NULL; + smb2_setup_nbt_length(req->out.vector, req->out.vector_count); if (req->do_signing) { diff --git a/source3/smbd/smb2_setinfo.c b/source3/smbd/smb2_setinfo.c index 5cb6714477f6..f3e3fc964f98 100644 --- a/source3/smbd/smb2_setinfo.c +++ b/source3/smbd/smb2_setinfo.c @@ -104,11 +104,7 @@ NTSTATUS smbd_smb2_request_process_setinfo(struct smbd_smb2_request *req) } tevent_req_set_callback(subreq, smbd_smb2_request_setinfo_done, req); - if (tevent_req_is_in_progress(subreq)) { - return smbd_smb2_request_pending_queue(req); - } - - return NT_STATUS_OK; + return smbd_smb2_request_pending_queue(req, subreq); } static void smbd_smb2_request_setinfo_done(struct tevent_req *subreq) diff --git a/source3/smbd/smb2_write.c b/source3/smbd/smb2_write.c index d9fa46f5cabf..fa209fafc731 100644 --- a/source3/smbd/smb2_write.c +++ b/source3/smbd/smb2_write.c @@ -109,11 +109,7 @@ NTSTATUS smbd_smb2_request_process_write(struct smbd_smb2_request *req) } tevent_req_set_callback(subreq, smbd_smb2_request_write_done, req); - if (tevent_req_is_in_progress(subreq)) { - return smbd_smb2_request_pending_queue(req); - } - - return NT_STATUS_OK; + return smbd_smb2_request_pending_queue(req, subreq); } static void smbd_smb2_request_write_done(struct tevent_req *subreq)