From: Jeremy Allison Date: Wed, 18 Mar 2020 22:59:03 +0000 (-0700) Subject: s3: smbd: Convert async SMB2 close to use the wait_queue idiom. X-Git-Tag: ldb-2.2.0~1291 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b686de4e7ba83f6f37b1da175e259d25e75c98d1;p=thirdparty%2Fsamba.git s3: smbd: Convert async SMB2 close to use the wait_queue idiom. Use the same mechanism to wait for aio on a handle used by SMB1 reply_tdis(), reply_ulogoffX(), reply_exit(), reply_close() and SMB2 tree disconnect. This removes the last user of fsp->deferred_close, allowing us to remove it. Signed-off-by: Jeremy Allison Reviewed-by: Ralph Boehme --- diff --git a/source3/smbd/smb2_close.c b/source3/smbd/smb2_close.c index ae0873e3bbe..09778617884 100644 --- a/source3/smbd/smb2_close.c +++ b/source3/smbd/smb2_close.c @@ -301,9 +301,10 @@ struct smbd_smb2_close_state { uint64_t out_allocation_size; uint64_t out_end_of_file; uint32_t out_file_attributes; + struct tevent_queue *wait_queue; }; -static void smbd_smb2_close_do(struct tevent_req *subreq); +static void smbd_smb2_close_wait_done(struct tevent_req *subreq); static struct tevent_req *smbd_smb2_close_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -337,12 +338,41 @@ static struct tevent_req *smbd_smb2_close_send(TALLOC_CTX *mem_ctx, } 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)) { + struct tevent_req *subreq; + + state->wait_queue = tevent_queue_create(state, + "smbd_smb2_close_send_wait_queue"); + if (tevent_req_nomem(state->wait_queue, req)) { + return tevent_req_post(req, ev); + } + /* + * Now wait until all aio requests on this fsp are + * finished. + * + * We don't set a callback, as we just want to block the + * wait queue and the talloc_free() of fsp->aio_request + * will remove the item from the wait queue. + */ + subreq = tevent_queue_wait_send(in_fsp->aio_requests, + smb2req->sconn->ev_ctx, + state->wait_queue); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + + /* + * Now we add our own waiter to the end of the queue, + * this way we get notified when all pending requests are + * finished. + */ + subreq = tevent_queue_wait_send(state, + smb2req->sconn->ev_ctx, + state->wait_queue); + if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } - tevent_req_set_callback(in_fsp->deferred_close, - smbd_smb2_close_do, req); + + tevent_req_set_callback(subreq, smbd_smb2_close_wait_done, req); return req; } @@ -365,24 +395,16 @@ 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) +static void smbd_smb2_close_wait_done(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); + tevent_queue_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,