[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha8-1047-gb62ce48
Stefan Metzmacher
metze at samba.org
Mon Aug 17 01:27:38 MDT 2009
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 <metze at 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 <metze at 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 <metze at samba.org>
Date: Sat Aug 15 10:01:38 2009 +0200
s3:smbd: implement SMB2 Cancel correctly.
metze
commit 3b3bde938cd404605b43710478cf7999551071b4
Author: Stefan Metzmacher <metze at 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 <metze at 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 <metze at 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
More information about the samba-cvs
mailing list