summaryrefslogtreecommitdiff
path: root/source3/smbd/smb2_close.c
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2012-07-17 22:24:51 +0200
committerJeremy Allison <jra@samba.org>2012-07-18 15:58:43 -0700
commita6b58367410abc85fc079910f3f193eaa386f9f1 (patch)
tree3383793f864e45ba910ccb37ca11e8006bba6c7f /source3/smbd/smb2_close.c
parent3e9f58be7e56b7990417e3f97a2d215f3591289e (diff)
downloadsamba-a6b58367410abc85fc079910f3f193eaa386f9f1.tar.gz
s3-smb2: Postpone close_file until all aio is handled
Thanks to Jeremy for this simple idea Signed-off-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'source3/smbd/smb2_close.c')
-rw-r--r--source3/smbd/smb2_close.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/source3/smbd/smb2_close.c b/source3/smbd/smb2_close.c
index 566ac93ea25..6d93278e520 100644
--- a/source3/smbd/smb2_close.c
+++ b/source3/smbd/smb2_close.c
@@ -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,