s3-smb2: Postpone close_file until all aio is handled
authorVolker Lendecke <vl@samba.org>
Tue, 17 Jul 2012 20:24:51 +0000 (22:24 +0200)
committerJeremy Allison <jra@samba.org>
Wed, 18 Jul 2012 22:58:43 +0000 (15:58 -0700)
Thanks to Jeremy for this simple idea

Signed-off-by: Jeremy Allison <jra@samba.org>
source3/smbd/smb2_close.c

index 566ac93ea2563394187caf092bef8eaf3f72a389..6d93278e520d97272fe66cc16af3feda4aa9bfc9 100644 (file)
@@ -23,6 +23,7 @@
 #include "smbd/globals.h"
 #include "../libcli/smb/smb_common.h"
 #include "../lib/util/tevent_ntstatus.h"
+#include "lib/tevent_wait.h"
 
 static struct tevent_req *smbd_smb2_close_send(TALLOC_CTX *mem_ctx,
                                               struct tevent_context *ev,
@@ -255,6 +256,7 @@ static NTSTATUS smbd_smb2_close(struct smbd_smb2_request *req,
 }
 
 struct smbd_smb2_close_state {
+       struct smbd_smb2_request *smb2req;
        struct files_struct *in_fsp;
        uint16_t in_flags;
        uint16_t out_flags;
@@ -267,6 +269,8 @@ struct smbd_smb2_close_state {
        uint32_t out_file_attributes;
 };
 
+static void smbd_smb2_close_do(struct tevent_req *subreq);
+
 static struct tevent_req *smbd_smb2_close_send(TALLOC_CTX *mem_ctx,
                                               struct tevent_context *ev,
                                               struct smbd_smb2_request *smb2req,
@@ -282,9 +286,21 @@ static struct tevent_req *smbd_smb2_close_send(TALLOC_CTX *mem_ctx,
        if (req == NULL) {
                return NULL;
        }
+       state->smb2req = smb2req;
        state->in_fsp = in_fsp;
        state->in_flags = in_flags;
 
+       if (in_fsp->num_aio_requests != 0) {
+
+               in_fsp->deferred_close = tevent_wait_send(in_fsp, ev);
+               if (tevent_req_nomem(in_fsp->deferred_close, req)) {
+                       return tevent_req_post(req, ev);
+               }
+               tevent_req_set_callback(in_fsp->deferred_close,
+                                       smbd_smb2_close_do, req);
+               return req;
+       }
+
        status = smbd_smb2_close(smb2req,
                                 state->in_fsp,
                                 state->in_flags,
@@ -304,6 +320,42 @@ static struct tevent_req *smbd_smb2_close_send(TALLOC_CTX *mem_ctx,
        return tevent_req_post(req, ev);
 }
 
+static void smbd_smb2_close_do(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct smbd_smb2_close_state *state = tevent_req_data(
+               req, struct smbd_smb2_close_state);
+       NTSTATUS status;
+       int ret;
+
+       ret = tevent_wait_recv(subreq);
+       TALLOC_FREE(subreq);
+       if (ret != 0) {
+               DEBUG(10, ("tevent_wait_recv returned %s\n",
+                          strerror(ret)));
+               /*
+                * Continue anyway, this should never happen
+                */
+       }
+
+       status = smbd_smb2_close(state->smb2req,
+                                state->in_fsp,
+                                state->in_flags,
+                                &state->out_flags,
+                                &state->out_creation_time,
+                                &state->out_last_access_time,
+                                &state->out_last_write_time,
+                                &state->out_change_time,
+                                &state->out_allocation_size,
+                                &state->out_end_of_file,
+                                &state->out_file_attributes);
+       if (tevent_req_nterror(req, status)) {
+               return;
+       }
+       tevent_req_done(req);
+}
+
 static NTSTATUS smbd_smb2_close_recv(struct tevent_req *req,
                                     uint16_t *out_flags,
                                     NTTIME *out_creation_time,