mirror of
https://github.com/samba-team/samba.git
synced 2025-03-01 04:58:35 +03:00
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 <jra@samba.org> Reviewed-by: Ralph Boehme <slow@samba.org>
This commit is contained in:
parent
53ee28381e
commit
b686de4e7b
@ -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);
|
||||
}
|
||||
tevent_req_set_callback(in_fsp->deferred_close,
|
||||
smbd_smb2_close_do, req);
|
||||
/*
|
||||
* 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(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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user