]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3: smbd: Convert async SMB2 close to use the wait_queue idiom.
authorJeremy Allison <jra@samba.org>
Wed, 18 Mar 2020 22:59:03 +0000 (15:59 -0700)
committerRalph Boehme <slow@samba.org>
Mon, 23 Mar 2020 09:40:45 +0000 (09:40 +0000)
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>
source3/smbd/smb2_close.c

index ae0873e3bbea8b63a307c16992b7184ee0a88567..097786178840526b95b7ce09f5868fbbb90c0dca 100644 (file)
@@ -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,