From a6b58367410abc85fc079910f3f193eaa386f9f1 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 17 Jul 2012 22:24:51 +0200 Subject: s3-smb2: Postpone close_file until all aio is handled Thanks to Jeremy for this simple idea Signed-off-by: Jeremy Allison --- source3/smbd/smb2_close.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'source3') diff --git a/source3/smbd/smb2_close.c b/source3/smbd/smb2_close.c index 566ac93ea2..6d93278e52 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, -- cgit