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

Reply via email to