[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