The branch, master has been updated via b62ce48f007aa93b6c6a7f066f1daf06c7fd1389 (commit) via 47452b8cecaa9ad17d88e259a9972c5ddd007629 (commit) via d60f049eaf30d7a717291b2f295cc889efc7afa9 (commit) via 3b3bde938cd404605b43710478cf7999551071b4 (commit) via 97a1ed53ca4255ac7fc5643292019ad30c276de5 (commit) via 45e4be0d96abdc729252df1e97bb9a56302e5a4a (commit) from 26e114b83ce1de7515bfbf365da03ec3f18c95fd (commit)
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit b62ce48f007aa93b6c6a7f066f1daf06c7fd1389 Author: Stefan Metzmacher <me...@samba.org> Date: Sat Aug 15 10:11:16 2009 +0200 s3:smbd: add support for canceling SMB2 Notify calls. metze commit 47452b8cecaa9ad17d88e259a9972c5ddd007629 Author: Stefan Metzmacher <me...@samba.org> Date: Sat Aug 15 10:07:00 2009 +0200 s3:smbd: add smbd_notify_cancel_by_smbreq() This function will be used by the SMB2 notify code. metze commit d60f049eaf30d7a717291b2f295cc889efc7afa9 Author: Stefan Metzmacher <me...@samba.org> Date: Sat Aug 15 10:01:38 2009 +0200 s3:smbd: implement SMB2 Cancel correctly. metze commit 3b3bde938cd404605b43710478cf7999551071b4 Author: Stefan Metzmacher <me...@samba.org> Date: Sat Aug 15 10:45:21 2009 +0200 s4:build: require tevent 0.9.7 with tevent_req_cancel() metze commit 97a1ed53ca4255ac7fc5643292019ad30c276de5 Author: Stefan Metzmacher <me...@samba.org> Date: Sat Aug 15 10:44:50 2009 +0200 tevent: change version to 0.9.7 after adding tevent_req_cancel infrastructure metze commit 45e4be0d96abdc729252df1e97bb9a56302e5a4a Author: Stefan Metzmacher <me...@samba.org> Date: Sat Aug 15 09:46:23 2009 +0200 tevent: add tevent_req_cancel() infrastructure This offers a generic way for callers to cancel an async request. metze ----------------------------------------------------------------------- Summary of changes: lib/tevent/configure.ac | 2 +- lib/tevent/tevent.h | 8 +++++++ lib/tevent/tevent_internal.h | 19 ++++++++++++++++++ lib/tevent/tevent_req.c | 43 ++++++++++++++++++++++++++++++++++++++++++ source3/smbd/globals.h | 12 ++++++++++- source3/smbd/notify.c | 20 +++++++++++++++++++ source3/smbd/smb2_break.c | 6 +---- source3/smbd/smb2_create.c | 6 +---- source3/smbd/smb2_find.c | 6 +---- source3/smbd/smb2_flush.c | 6 +---- source3/smbd/smb2_getinfo.c | 6 +---- source3/smbd/smb2_ioctl.c | 6 +---- source3/smbd/smb2_lock.c | 6 +---- source3/smbd/smb2_notify.c | 23 +++++++++++++++++---- source3/smbd/smb2_read.c | 6 +---- source3/smbd/smb2_server.c | 17 ++++++++++++--- source3/smbd/smb2_setinfo.c | 6 +---- source3/smbd/smb2_write.c | 6 +---- source4/min_versions.m4 | 2 +- 19 files changed, 144 insertions(+), 62 deletions(-) Changeset truncated at 500 lines: diff --git a/lib/tevent/configure.ac b/lib/tevent/configure.ac index d40e02e..89190af 100644 --- a/lib/tevent/configure.ac +++ b/lib/tevent/configure.ac @@ -1,5 +1,5 @@ AC_PREREQ(2.50) -AC_INIT(tevent, 0.9.6) +AC_INIT(tevent, 0.9.7) AC_CONFIG_SRCDIR([tevent.c]) AC_CONFIG_HEADER(config.h) diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h index 56ae0ee..d355605 100644 --- a/lib/tevent/tevent.h +++ b/lib/tevent/tevent.h @@ -238,6 +238,14 @@ char *tevent_req_default_print(struct tevent_req *req, TALLOC_CTX *mem_ctx); char *tevent_req_print(TALLOC_CTX *mem_ctx, struct tevent_req *req); +typedef bool (*tevent_req_cancel_fn)(struct tevent_req *); + +void tevent_req_set_cancel_fn(struct tevent_req *req, tevent_req_cancel_fn fn); + +bool _tevent_req_cancel(struct tevent_req *req, const char *location); +#define tevent_req_cancel(req) \ + _tevent_req_cancel(req, __location__) + struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx, void *pstate, size_t state_size, diff --git a/lib/tevent/tevent_internal.h b/lib/tevent/tevent_internal.h index e260524..513ca1c 100644 --- a/lib/tevent/tevent_internal.h +++ b/lib/tevent/tevent_internal.h @@ -65,6 +65,15 @@ struct tevent_req { tevent_req_print_fn private_print; /** + * @brief A function to cancel the request + * + * The implementation might want to set a function + * that is called when the tevent_req_cancel() function + * was called. + */ + tevent_req_cancel_fn private_cancel; + + /** * @brief Internal state of the request * * Callers should only access this via functions and never directly. @@ -100,6 +109,16 @@ struct tevent_req { const char *finish_location; /** + * @brief The location where the request was canceled + * + * This uses the __location__ macro via the + * tevent_req_cancel() macro. + * + * This for debugging only. + */ + const char *cancel_location; + + /** * @brief The external state - will be queried by the caller * * While the async request is being processed, state will remain in diff --git a/lib/tevent/tevent_req.c b/lib/tevent/tevent_req.c index c6b1160..345a2fd 100644 --- a/lib/tevent/tevent_req.c +++ b/lib/tevent/tevent_req.c @@ -398,3 +398,46 @@ void tevent_req_set_print_fn(struct tevent_req *req, tevent_req_print_fn fn) { req->private_print = fn; } + +/** + * @brief This function sets a cancel function for the given request + * @param[in] req The given request + * @param[in] fn A pointer to the cancel function + * + * This function can be used to setup a cancel function for the given request. + * This will be triggered if the tevent_req_cancel() function was + * called on the given request. + * + */ +void tevent_req_set_cancel_fn(struct tevent_req *req, tevent_req_cancel_fn fn) +{ + req->private_cancel = fn; +} + +/** + * @brief This function tries to cancel the given request + * @param[in] req The given request + * @param[in] location Automaticly filled with the __location__ macro + * via the tevent_req_cancel() macro. This is for debugging + * only! + * @retval This function returns true is the request is cancelable. + * Otherwise false is returned. + * + * This function can be used to cancel the given request. + * + * It is only possible to cancel a request when the implementation + * has registered a cancel function via the tevent_req_set_cancel_fn(). + * + * Note: Even if the function returns true, the caller need to wait + * for the function to complete normally. + * Only the _recv() function of the given request indicates + * if the request was really canceled. + */ +bool _tevent_req_cancel(struct tevent_req *req, const char *location) +{ + if (req->private_cancel == NULL) { + return false; + } + + return req->private_cancel(req); +} diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index 0b8ef58..4fa85a9 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -234,6 +234,9 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx, uint32_t *_mode, long *_prev_offset); +void smbd_notify_cancel_by_smbreq(struct smbd_server_connection *sconn, + const struct smb_request *smbreq); + void smbd_server_connection_terminate_ex(struct smbd_server_connection *sconn, const char *reason, const char *location); @@ -264,7 +267,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 +315,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/notify.c b/source3/smbd/notify.c index 8f37923..e430fcf 100644 --- a/source3/smbd/notify.c +++ b/source3/smbd/notify.c @@ -317,6 +317,26 @@ void remove_pending_change_notify_requests_by_mid(uint16 mid) change_notify_remove_request(map->req); } +void smbd_notify_cancel_by_smbreq(struct smbd_server_connection *sconn, + const struct smb_request *smbreq) +{ + struct notify_mid_map *map; + + for (map = sconn->smb1.notify_mid_maps; map; map = map->next) { + if (map->req->req == smbreq) { + break; + } + } + + if (map == NULL) { + return; + } + + change_notify_reply(map->req->fsp->conn, map->req->req, + NT_STATUS_CANCELLED, 0, NULL, map->req->reply_fn); + change_notify_remove_request(map->req); +} + /**************************************************************************** Delete entries by fnum from the change notify pending queue. *****************************************************************************/ diff --git a/source3/smbd/smb2_break.c b/source3/smbd/smb2_break.c index 449b8f6..879d59f 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 43b1fcb..76fe504 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 f28ae19..40ba320 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 bfdb2d8..561e690 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 1c247d7..3b50ab9 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 333616a..0041e5f 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 eab95f6..908e1cf 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 390bb57..fb465ab 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) @@ -159,6 +155,7 @@ static void smbd_smb2_request_notify_done(struct tevent_req *subreq) struct smbd_smb2_notify_state { struct smbd_smb2_request *smb2req; + struct smb_request *smbreq; struct tevent_immediate *im; NTSTATUS status; DATA_BLOB out_output_buffer; @@ -170,6 +167,7 @@ static void smbd_smb2_notify_reply(struct smb_request *smbreq, static void smbd_smb2_notify_reply_trigger(struct tevent_context *ctx, struct tevent_immediate *im, void *private_data); +static bool smbd_smb2_notify_cancel(struct tevent_req *req); static struct tevent_req *smbd_smb2_notify_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -205,6 +203,7 @@ static struct tevent_req *smbd_smb2_notify_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } + state->smbreq = smbreq; smbreq->async_priv = (void *)req; fsp = file_fsp(smbreq, (uint16_t)in_file_id_volatile); @@ -297,6 +296,9 @@ static struct tevent_req *smbd_smb2_notify_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } + /* allow this request to be canceled */ + tevent_req_set_cancel_fn(req, smbd_smb2_notify_cancel); + return req; } @@ -354,6 +356,17 @@ static void smbd_smb2_notify_reply_trigger(struct tevent_context *ctx, tevent_req_done(req); } +static bool smbd_smb2_notify_cancel(struct tevent_req *req) +{ + struct smbd_smb2_notify_state *state = tevent_req_data(req, + struct smbd_smb2_notify_state); + + smbd_notify_cancel_by_smbreq(state->smb2req->sconn, + state->smbreq); + + return true; +} + static NTSTATUS smbd_smb2_notify_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, DATA_BLOB *out_output_buffer) diff --git a/source3/smbd/smb2_read.c b/source3/smbd/smb2_read.c index 0b46567..3f316e0 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 edddccb..9e5be40 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 5cb6714..f3e3fc9 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 d9fa46f..fa209fa 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) diff --git a/source4/min_versions.m4 b/source4/min_versions.m4 index 1ecc929..dd97e1b 100644 --- a/source4/min_versions.m4 +++ b/source4/min_versions.m4 @@ -3,4 +3,4 @@ define(TDB_MIN_VERSION,1.1.5) define(TALLOC_MIN_VERSION,1.4.0) define(LDB_REQUIRED_VERSION,0.9.6) -define(TEVENT_REQUIRED_VERSION,0.9.6) +define(TEVENT_REQUIRED_VERSION,0.9.7) -- Samba Shared Repository