The Samba-Bugzilla – Attachment 15858 Details for
Bug 14301
smbd panic on force-close share during async io
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
git-am for master. Updated WIP
aio-part4 (text/plain), 76.70 KB, created by
Jeremy Allison
on 2020-03-13 01:19:27 UTC
(
hide
)
Description:
git-am for master. Updated WIP
Filename:
MIME Type:
Creator:
Jeremy Allison
Created:
2020-03-13 01:19:27 UTC
Size:
76.70 KB
patch
obsolete
>From e99089c9eff2b9f2124896fe00991252f0272be9 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 10 Mar 2020 10:55:22 -0700 >Subject: [PATCH 01/37] s3: smbd: In aio_del_req_from_fsp() > talloc_free(fsp->aio_requests[]) when fsp->num_aio_requests reaches zero. > >The add code in aio_add_req_to_fsp() re-tallocs >this array on demand, and talloc freeing it here >allows it to be used as the parent for a tevent >wait queue, so callers can get notified when >all outstanding aio on an fsp is finished. > >We'll deal with any performance issues in >the next commit. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/aio.c | 1 + > 1 file changed, 1 insertion(+) > >diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c >index 0f824f5aa1f..afe76608cd3 100644 >--- a/source3/smbd/aio.c >+++ b/source3/smbd/aio.c >@@ -103,6 +103,7 @@ static int aio_del_req_from_fsp(struct aio_req_fsp_link *lnk) > > if (fsp->num_aio_requests == 0) { > tevent_wait_done(fsp->deferred_close); >+ TALLOC_FREE(fsp->aio_requests); > } > return 0; > } >-- >2.20.1 > > >From 18fd1567ec4f1657f52c8fa63e7d8cfd40656754 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Wed, 11 Mar 2020 14:47:50 -0700 >Subject: [PATCH 02/37] s3: smbd: Now we free fsp->aio_requests when it gets > zero entries, talloc in chunks of 10 instead of 1. > >Prevents incremental +1 tallocs, and the original >idea of this array was that it wasn't freed for >io efficiency reasons. Add paranoia integer wrap >protection also. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/aio.c | 12 +++++++++++- > 1 file changed, 11 insertions(+), 1 deletion(-) > >diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c >index afe76608cd3..cf35f3297ec 100644 >--- a/source3/smbd/aio.c >+++ b/source3/smbd/aio.c >@@ -122,9 +122,19 @@ bool aio_add_req_to_fsp(files_struct *fsp, struct tevent_req *req) > if (array_len <= fsp->num_aio_requests) { > struct tevent_req **tmp; > >+ if (fsp->num_aio_requests + 10 < 10) { >+ /* Integer wrap. */ >+ TALLOC_FREE(lnk); >+ return false; >+ } >+ >+ /* >+ * Allocate in blocks of 10 so we don't allocate >+ * on every aio request. >+ */ > tmp = talloc_realloc( > fsp, fsp->aio_requests, struct tevent_req *, >- fsp->num_aio_requests+1); >+ fsp->num_aio_requests+10); > if (tmp == NULL) { > TALLOC_FREE(lnk); > return false; >-- >2.20.1 > > >From 2d4d87f17ca52d2cd031e82c8b9385862143da46 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Wed, 11 Mar 2020 17:25:59 -0700 >Subject: [PATCH 03/37] s3: smbd: In async SMB1 reply_close() set fsp->closing > = true, as we already do in SMB2 async close. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/reply.c | 7 +++++++ > 1 file changed, 7 insertions(+) > >diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c >index aef34d9ede8..55c77346050 100644 >--- a/source3/smbd/reply.c >+++ b/source3/smbd/reply.c >@@ -5672,6 +5672,13 @@ void reply_close(struct smb_request *req) > DEBUG(10, ("closing with aio %u requests pending\n", > fsp->num_aio_requests)); > >+ /* >+ * Flag the file as close in progress. >+ * This will prevent any more IO being >+ * done on it. >+ */ >+ fsp->closing = true; >+ > /* > * We depend on the aio_extra destructor to take care of this > * close request once fsp->num_aio_request drops to 0. >-- >2.20.1 > > >From 36033546b10708331f9dc8d062f04915c087e7af Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Wed, 11 Mar 2020 15:16:35 -0700 >Subject: [PATCH 04/37] s3: smbd: Every place we check fsp->deferred_close, > also check for fsp->closing. > >Eventually this will allow us to remove fsp->deferred_close >from the fsp struct (and also source3/lib/tevent_wait.[ch]). > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/modules/offload_token.c | 10 ++++++++++ > source3/smbd/files.c | 14 ++++++++++++++ > 2 files changed, 24 insertions(+) > >diff --git a/source3/modules/offload_token.c b/source3/modules/offload_token.c >index 3fb84dabdff..03bb3309f38 100644 >--- a/source3/modules/offload_token.c >+++ b/source3/modules/offload_token.c >@@ -280,6 +280,16 @@ NTSTATUS vfs_offload_token_check_handles(uint32_t fsctl, > return NT_STATUS_ACCESS_DENIED; > } > >+ if (src_fsp->closing) { >+ DBG_INFO("copy chunk src handle with closing in progress.\n"); >+ return NT_STATUS_ACCESS_DENIED; >+ } >+ >+ if (dst_fsp->closing) { >+ DBG_INFO("copy chunk dst handle with closing in progress.\n"); >+ return NT_STATUS_ACCESS_DENIED; >+ } >+ > if (src_fsp->is_directory) { > DBG_INFO("copy chunk no read on src directory handle (%s).\n", > smb_fname_str_dbg(src_fsp->fsp_name)); >diff --git a/source3/smbd/files.c b/source3/smbd/files.c >index 99b2f343685..b06511147ab 100644 >--- a/source3/smbd/files.c >+++ b/source3/smbd/files.c >@@ -598,6 +598,9 @@ files_struct *file_fsp(struct smb_request *req, uint16_t fid) > if (req->chain_fsp->deferred_close) { > return NULL; > } >+ if (req->chain_fsp->closing) { >+ return NULL; >+ } > return req->chain_fsp; > } > >@@ -622,6 +625,10 @@ files_struct *file_fsp(struct smb_request *req, uint16_t fid) > return NULL; > } > >+ if (fsp->closing) { >+ return NULL; >+ } >+ > req->chain_fsp = fsp; > return fsp; > } >@@ -669,6 +676,10 @@ struct files_struct *file_fsp_get(struct smbd_smb2_request *smb2req, > return NULL; > } > >+ if (fsp->closing) { >+ return NULL; >+ } >+ > return fsp; > } > >@@ -682,6 +693,9 @@ struct files_struct *file_fsp_smb2(struct smbd_smb2_request *smb2req, > if (smb2req->compat_chain_fsp->deferred_close) { > return NULL; > } >+ if (smb2req->compat_chain_fsp->closing) { >+ return NULL; >+ } > return smb2req->compat_chain_fsp; > } > >-- >2.20.1 > > >From abcc36ca8ffdd158b4bd031b2659c3c065d8d3bc Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 10 Mar 2020 12:25:58 -0700 >Subject: [PATCH 05/37] s3: smbd: Don't allow force disconnect of a connection > already being disconnected. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/conn_idle.c | 6 ++++++ > 1 file changed, 6 insertions(+) > >diff --git a/source3/smbd/conn_idle.c b/source3/smbd/conn_idle.c >index cd12e3f1266..9de2ae91d94 100644 >--- a/source3/smbd/conn_idle.c >+++ b/source3/smbd/conn_idle.c >@@ -103,6 +103,12 @@ void conn_force_tdis( > } > tcon = conn->tcon; > >+ if (NT_STATUS_EQUAL(tcon->status, >+ NT_STATUS_NETWORK_NAME_DELETED)) { >+ /* In the process of already being disconnected. */ >+ continue; >+ } >+ > do_close = check_fn(conn, private_data); > if (!do_close) { > continue; >-- >2.20.1 > > >From 254d559e7d08cdf5eb29e61a77a7d1f09eea80b4 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 12 Mar 2020 09:28:21 -0700 >Subject: [PATCH 06/37] s3: smbd: Add async internals of conn_force_tdis(). > >Commented out so it can be seen complete as >a diff. The next commit will replace the old >synchronous conn_force_tdis() code with the >new async code. > >Uses a wait_queue to cause the force close >requests to stay pending until all outstanding >aio is finished on all file handles opened >on the connection. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/conn_idle.c | 148 +++++++++++++++++++++++++++++++++++++++ > 1 file changed, 148 insertions(+) > >diff --git a/source3/smbd/conn_idle.c b/source3/smbd/conn_idle.c >index 9de2ae91d94..7b2863c85d6 100644 >--- a/source3/smbd/conn_idle.c >+++ b/source3/smbd/conn_idle.c >@@ -23,6 +23,7 @@ > #include "smbd/smbd.h" > #include "smbd/globals.h" > #include "rpc_server/rpc_pipes.h" >+#include "lib/util/tevent_ntstatus.h" > > /**************************************************************************** > Update last used timestamps. >@@ -140,3 +141,150 @@ void conn_force_tdis( > change_to_root_user(); > reload_services(sconn, conn_snum_used, true); > } >+ >+#if 0 >+struct conn_force_tdis_state { >+ struct tevent_queue *wait_queue; >+}; >+ >+static void conn_force_tdis_wait_done(struct tevent_req *subreq); >+ >+static struct tevent_req *conn_force_tdis_send(connection_struct *conn) >+{ >+ struct tevent_req *req; >+ struct conn_force_tdis_state *state; >+ struct tevent_req *subreq; >+ files_struct *fsp; >+ >+ /* Create this off the NULL context. We must clean up on return. */ >+ req = tevent_req_create(NULL, &state, >+ struct conn_force_tdis_state); >+ if (req == NULL) { >+ return NULL; >+ } >+ state->wait_queue = tevent_queue_create(state, >+ "conn_force_tdis_wait_queue"); >+ if (tevent_req_nomem(state->wait_queue, req)) { >+ TALLOC_FREE(req); >+ return NULL; >+ } >+ >+ /* >+ * Make sure that no new request will be able to use this tcon. >+ * This ensures that once all outstanding fsp->aio_requests >+ * on this tcon are done, we are safe to close it. >+ */ >+ conn->tcon->status = NT_STATUS_NETWORK_NAME_DELETED; >+ >+ for (fsp = conn->sconn->files; fsp; fsp = fsp->next) { >+ if (fsp->conn != conn) { >+ continue; >+ } >+ /* >+ * Flag the file as close in progress. >+ * This will prevent any more IO being >+ * done on it. Not strictly needed, but >+ * doesn't hurt to flag it as closing. >+ */ >+ fsp->closing = true; >+ >+ if (fsp->num_aio_requests > 0) { >+ /* >+ * 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(fsp->aio_requests, >+ conn->sconn->ev_ctx, >+ state->wait_queue); >+ if (tevent_req_nomem(subreq, req)) { >+ TALLOC_FREE(req); >+ return NULL; >+ } >+ } >+ } >+ /* >+ * Now we add our own waiter to the end of the queue, >+ * this way we get notified when all pending requests are finished >+ * and reply to the outstanding SMB1 request. >+ */ >+ subreq = tevent_queue_wait_send(state, >+ conn->sconn->ev_ctx, >+ state->wait_queue); >+ if (tevent_req_nomem(subreq, req)) { >+ TALLOC_FREE(req); >+ return NULL; >+ } >+ >+ tevent_req_set_callback(subreq, conn_force_tdis_wait_done, req); >+ return req; >+} >+ >+static void conn_force_tdis_wait_done(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ >+ tevent_queue_wait_recv(subreq); >+ TALLOC_FREE(subreq); >+ tevent_req_done(req); >+} >+ >+static NTSTATUS conn_force_tdis_recv(struct tevent_req *req) >+{ >+ return tevent_req_simple_recv_ntstatus(req); >+} >+ >+static void conn_force_tdis_done(struct tevent_req *req) >+{ >+ connection_struct *conn = tevent_req_callback_data( >+ req, connection_struct); >+ NTSTATUS status; >+ uint64_t vuid = UID_FIELD_INVALID; >+ struct smbXsrv_tcon *tcon = conn->tcon; >+ struct smbd_server_connection *sconn = conn->sconn; >+ >+ status = conn_force_tdis_recv(req); >+ TALLOC_FREE(req); >+ if (!NT_STATUS_IS_OK(status)) { >+ DBG_ERR("conn_force_tdis_recv of share '%s' " >+ "(wire_id=0x%08x) failed: %s\n", >+ tcon->global->share_name, >+ tcon->global->tcon_wire_id, >+ nt_errstr(status)); >+ return; >+ } >+ >+ if (conn->sconn->using_smb2) { >+ vuid = conn->vuid; >+ } >+ >+ DBG_WARNING("Closing " >+ "share '%s' (wire_id=0x%08x)\n", >+ tcon->global->share_name, >+ tcon->global->tcon_wire_id); >+ >+ conn = NULL; >+ status = smbXsrv_tcon_disconnect(tcon, vuid); >+ if (!NT_STATUS_IS_OK(status)) { >+ DBG_ERR("smbXsrv_tcon_disconnect() of share '%s' " >+ "(wire_id=0x%08x) failed: %s\n", >+ tcon->global->share_name, >+ tcon->global->tcon_wire_id, >+ nt_errstr(status)); >+ return; >+ } >+ >+ TALLOC_FREE(tcon); >+ >+ /* >+ * As we've been awoken, we may have changed >+ * uid in the meantime. Ensure we're still root. >+ */ >+ change_to_root_user(); >+ reload_services(sconn, conn_snum_used, true); >+} >+#endif >-- >2.20.1 > > >From 5dc1ddf94bcb5fe75066554dc840f7b9ecda21f4 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 12 Mar 2020 09:47:26 -0700 >Subject: [PATCH 07/37] s3: smbd: Replace synchronous conn_force_tdis() with > the async version. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/conn_idle.c | 44 +++++++++++++++------------------------- > 1 file changed, 16 insertions(+), 28 deletions(-) > >diff --git a/source3/smbd/conn_idle.c b/source3/smbd/conn_idle.c >index 7b2863c85d6..6d818c4b9ab 100644 >--- a/source3/smbd/conn_idle.c >+++ b/source3/smbd/conn_idle.c >@@ -77,27 +77,27 @@ bool conn_idle_all(struct smbd_server_connection *sconn, time_t t) > } > > /**************************************************************************** >- Forcibly unmount a share. >+ Forcibly unmount a share - async > All instances of the parameter 'sharename' share are unmounted. > The special sharename '*' forces unmount of all shares. > ****************************************************************************/ > >+static struct tevent_req *conn_force_tdis_send(connection_struct *conn); >+static void conn_force_tdis_done(struct tevent_req *req); >+ > void conn_force_tdis( > struct smbd_server_connection *sconn, > bool (*check_fn)(struct connection_struct *conn, > void *private_data), > void *private_data) > { >- connection_struct *conn, *next; >+ connection_struct *conn; > > /* SMB1 and SMB 2*/ >- for (conn = sconn->connections; conn; conn = next) { >+ for (conn = sconn->connections; conn; conn = conn->next) { > struct smbXsrv_tcon *tcon; > bool do_close = false; >- NTSTATUS status; >- uint64_t vuid = UID_FIELD_INVALID; >- >- next = conn->next; >+ struct tevent_req *req; > > if (conn->tcon == NULL) { > continue; >@@ -115,34 +115,23 @@ void conn_force_tdis( > continue; > } > >+ req = conn_force_tdis_send(conn); >+ if (req == NULL) { >+ DBG_WARNING("talloc_fail forcing async close of " >+ "share '%s'\n", >+ tcon->global->share_name); >+ continue; >+ } >+ > DBG_WARNING("Forcing close of " > "share '%s' (wire_id=0x%08x)\n", > tcon->global->share_name, > tcon->global->tcon_wire_id); > >- if (sconn->using_smb2) { >- vuid = conn->vuid; >- } >- >- conn = NULL; >- status = smbXsrv_tcon_disconnect(tcon, vuid); >- if (!NT_STATUS_IS_OK(status)) { >- DEBUG(0, ("conn_force_tdis: " >- "smbXsrv_tcon_disconnect() of share '%s' " >- "(wire_id=0x%08x) failed: %s\n", >- tcon->global->share_name, >- tcon->global->tcon_wire_id, >- nt_errstr(status))); >- } >- >- TALLOC_FREE(tcon); >+ tevent_req_set_callback(req, conn_force_tdis_done, conn); > } >- >- change_to_root_user(); >- reload_services(sconn, conn_snum_used, true); > } > >-#if 0 > struct conn_force_tdis_state { > struct tevent_queue *wait_queue; > }; >@@ -287,4 +276,3 @@ static void conn_force_tdis_done(struct tevent_req *req) > change_to_root_user(); > reload_services(sconn, conn_snum_used, true); > } >-#endif >-- >2.20.1 > > >From cc954e6814a5ecb8eb182f9e9cc0e41d2b67dc68 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 12 Mar 2020 09:51:53 -0700 >Subject: [PATCH 08/37] s3: smbd: Add async internals of reply_tdis(). > >Waits until all aio requests on all fsp's under this >conn struct are finished before returning to the client. > >Done this way (commented out) so it is a clean >diff and it's clear what is being added. > >A later commit will remove the old synchronous version. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/reply.c | 167 +++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 167 insertions(+) > >diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c >index 55c77346050..ade13de26bc 100644 >--- a/source3/smbd/reply.c >+++ b/source3/smbd/reply.c >@@ -42,6 +42,7 @@ > #include "smbprofile.h" > #include "../lib/tsocket/tsocket.h" > #include "lib/tevent_wait.h" >+#include "lib/util/tevent_ntstatus.h" > #include "libcli/smb/smb_signing.h" > #include "lib/util/sys_rw_data.h" > #include "librpc/gen_ndr/open_files.h" >@@ -6080,6 +6081,172 @@ void reply_tdis(struct smb_request *req) > return; > } > >+#if 0 >+struct reply_tdis_state { >+ struct tevent_queue *wait_queue; >+}; >+ >+static void reply_tdis_wait_done(struct tevent_req *subreq); >+ >+/**************************************************************************** >+ Async SMB1 tdis. >+ Note, on failure here we deallocate and return NULL to allow the caller to >+ SMB1 return an error of ERRnomem immediately. >+****************************************************************************/ >+ >+static struct tevent_req *reply_tdis_send(struct smb_request *smb1req) >+{ >+ struct tevent_req *req; >+ struct reply_tdis_state *state; >+ struct tevent_req *subreq; >+ connection_struct *conn = smb1req->conn; >+ files_struct *fsp; >+ >+ /* Create this off the NULL context. We must clean up on return. */ >+ req = tevent_req_create(NULL, &state, >+ struct reply_tdis_state); >+ if (req == NULL) { >+ return NULL; >+ } >+ state->wait_queue = tevent_queue_create(state, "reply_tdis_wait_queue"); >+ if (tevent_req_nomem(state->wait_queue, req)) { >+ TALLOC_FREE(req); >+ return NULL; >+ } >+ >+ /* >+ * Make sure that no new request will be able to use this tcon. >+ * This ensures that once all outstanding fsp->aio_requests >+ * on this tcon are done, we are safe to close it. >+ */ >+ conn->tcon->status = NT_STATUS_NETWORK_NAME_DELETED; >+ >+ for (fsp = conn->sconn->files; fsp; fsp = fsp->next) { >+ if (fsp->conn != conn) { >+ continue; >+ } >+ /* >+ * Flag the file as close in progress. >+ * This will prevent any more IO being >+ * done on it. Not strictly needed, but >+ * doesn't hurt to flag it as closing. >+ */ >+ fsp->closing = true; >+ >+ if (fsp->num_aio_requests > 0) { >+ /* >+ * 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(fsp->aio_requests, >+ conn->sconn->ev_ctx, >+ state->wait_queue); >+ if (tevent_req_nomem(subreq, req)) { >+ TALLOC_FREE(req); >+ return NULL; >+ } >+ } >+ } >+ >+ /* >+ * Now we add our own waiter to the end of the queue, >+ * this way we get notified when all pending requests are finished >+ * and reply to the outstanding SMB1 request. >+ */ >+ subreq = tevent_queue_wait_send(state, >+ conn->sconn->ev_ctx, >+ state->wait_queue); >+ if (tevent_req_nomem(subreq, req)) { >+ TALLOC_FREE(req); >+ return NULL; >+ } >+ >+ /* >+ * We're really going async - move the SMB1 request from >+ * a talloc stackframe above us to the NULL context. >+ * We need this to stick around until the wait_done >+ * callback is invoked. >+ */ >+ smb1req = talloc_move(NULL, &smb1req); >+ >+ tevent_req_set_callback(subreq, reply_tdis_wait_done, req); >+ >+ return req; >+} >+ >+static void reply_tdis_wait_done(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ >+ tevent_queue_wait_recv(subreq); >+ TALLOC_FREE(subreq); >+ tevent_req_done(req); >+} >+ >+static NTSTATUS reply_tdis_recv(struct tevent_req *req) >+{ >+ return tevent_req_simple_recv_ntstatus(req); >+} >+ >+static void reply_tdis_done(struct tevent_req *req) >+{ >+ struct smb_request *smb1req = tevent_req_callback_data( >+ req, struct smb_request); >+ NTSTATUS status; >+ struct smbXsrv_tcon *tcon = smb1req->conn->tcon; >+ bool ok; >+ >+ status = reply_tdis_recv(req); >+ TALLOC_FREE(req); >+ if (!NT_STATUS_IS_OK(status)) { >+ TALLOC_FREE(smb1req); >+ END_PROFILE(SMBtdis); >+ exit_server(__location__ ": reply_tdis_recv failed"); >+ return; >+ } >+ >+ /* >+ * As we've been awoken, we may have changed >+ * directory in the meantime. >+ * reply_tdis() has the DO_CHDIR flag set. >+ */ >+ ok = chdir_current_service(smb1req->conn); >+ if (!ok) { >+ reply_force_doserror(smb1req, ERRSRV, ERRinvnid); >+ smb_request_done(smb1req); >+ END_PROFILE(SMBtdis); >+ } >+ >+ status = smbXsrv_tcon_disconnect(tcon, >+ smb1req->vuid); >+ if (!NT_STATUS_IS_OK(status)) { >+ TALLOC_FREE(smb1req); >+ END_PROFILE(SMBtdis); >+ exit_server(__location__ ": smbXsrv_tcon_disconnect failed"); >+ return; >+ } >+ >+ /* smbXsrv_tcon_disconnect frees smb1req->conn. */ >+ smb1req->conn = NULL; >+ >+ TALLOC_FREE(tcon); >+ >+ reply_outbuf(smb1req, 0, 0); >+ /* >+ * The following call is needed to push the >+ * reply data back out the socket after async >+ * return. Plus it frees smb1req. >+ */ >+ smb_request_done(smb1req); >+ END_PROFILE(SMBtdis); >+} >+#endif >+ > /**************************************************************************** > Reply to a echo. > conn POINTER CAN BE NULL HERE ! >-- >2.20.1 > > >From 19db94df3e254184a944f11311463bbb0b869328 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 12 Mar 2020 09:55:30 -0700 >Subject: [PATCH 09/37] s3: smbd: In reply_tdis(), replace req -> smb1req. > >Minimises the diff in the next commit. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/reply.c | 12 ++++++------ > 1 file changed, 6 insertions(+), 6 deletions(-) > >diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c >index ade13de26bc..0e4b50254e1 100644 >--- a/source3/smbd/reply.c >+++ b/source3/smbd/reply.c >@@ -6039,28 +6039,28 @@ void reply_unlock(struct smb_request *req) > conn POINTER CAN BE NULL HERE ! > ****************************************************************************/ > >-void reply_tdis(struct smb_request *req) >+void reply_tdis(struct smb_request *smb1req) > { > NTSTATUS status; >- connection_struct *conn = req->conn; >+ connection_struct *conn = smb1req->conn; > struct smbXsrv_tcon *tcon; > > START_PROFILE(SMBtdis); > > if (!conn) { > DEBUG(4,("Invalid connection in tdis\n")); >- reply_force_doserror(req, ERRSRV, ERRinvnid); >+ reply_force_doserror(smb1req, ERRSRV, ERRinvnid); > END_PROFILE(SMBtdis); > return; > } > > tcon = conn->tcon; >- req->conn = NULL; >+ smb1req->conn = NULL; > > /* > * TODO: cancel all outstanding requests on the tcon > */ >- status = smbXsrv_tcon_disconnect(tcon, req->vuid); >+ status = smbXsrv_tcon_disconnect(tcon, smb1req->vuid); > if (!NT_STATUS_IS_OK(status)) { > DEBUG(0, ("reply_tdis: " > "smbXsrv_tcon_disconnect() failed: %s\n", >@@ -6076,7 +6076,7 @@ void reply_tdis(struct smb_request *req) > > TALLOC_FREE(tcon); > >- reply_outbuf(req, 0, 0); >+ reply_outbuf(smb1req, 0, 0); > END_PROFILE(SMBtdis); > return; > } >-- >2.20.1 > > >From 54330fa946b4a3a180380944fb4d1e34c6468ef6 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 12 Mar 2020 09:59:47 -0700 >Subject: [PATCH 10/37] s3: smbd: reply_tdis() Update to modern coding > standards. > >Minimizes the diff in the next commit. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/reply.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c >index 0e4b50254e1..c2ee7692db0 100644 >--- a/source3/smbd/reply.c >+++ b/source3/smbd/reply.c >@@ -6047,8 +6047,8 @@ void reply_tdis(struct smb_request *smb1req) > > START_PROFILE(SMBtdis); > >- if (!conn) { >- DEBUG(4,("Invalid connection in tdis\n")); >+ if (conn == NULL) { >+ DBG_INFO("Invalid connection in tdis\n"); > reply_force_doserror(smb1req, ERRSRV, ERRinvnid); > END_PROFILE(SMBtdis); > return; >-- >2.20.1 > > >From 7384adb13b363c988eaaaf3e9011c777b73c1df3 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 12 Mar 2020 10:03:27 -0700 >Subject: [PATCH 11/37] s3: smbd: Remove old synchronous SMB1 reply_tdis(). > >SMB1 tree disconnect is now fully async. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/reply.c | 34 +++++++++------------------------- > 1 file changed, 9 insertions(+), 25 deletions(-) > >diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c >index c2ee7692db0..db020b64268 100644 >--- a/source3/smbd/reply.c >+++ b/source3/smbd/reply.c >@@ -6039,11 +6039,13 @@ void reply_unlock(struct smb_request *req) > conn POINTER CAN BE NULL HERE ! > ****************************************************************************/ > >+static struct tevent_req *reply_tdis_send(struct smb_request *smb1req); >+static void reply_tdis_done(struct tevent_req *req); >+ > void reply_tdis(struct smb_request *smb1req) > { >- NTSTATUS status; > connection_struct *conn = smb1req->conn; >- struct smbXsrv_tcon *tcon; >+ struct tevent_req *req; > > START_PROFILE(SMBtdis); > >@@ -6054,34 +6056,17 @@ void reply_tdis(struct smb_request *smb1req) > return; > } > >- tcon = conn->tcon; >- smb1req->conn = NULL; >- >- /* >- * TODO: cancel all outstanding requests on the tcon >- */ >- status = smbXsrv_tcon_disconnect(tcon, smb1req->vuid); >- if (!NT_STATUS_IS_OK(status)) { >- DEBUG(0, ("reply_tdis: " >- "smbXsrv_tcon_disconnect() failed: %s\n", >- nt_errstr(status))); >- /* >- * If we hit this case, there is something completely >- * wrong, so we better disconnect the transport connection. >- */ >+ req = reply_tdis_send(smb1req); >+ if (req == NULL) { >+ reply_force_doserror(smb1req, ERRDOS, ERRnomem); > END_PROFILE(SMBtdis); >- exit_server(__location__ ": smbXsrv_tcon_disconnect failed"); > return; > } >- >- TALLOC_FREE(tcon); >- >- reply_outbuf(smb1req, 0, 0); >- END_PROFILE(SMBtdis); >+ /* We're async. This will complete later. */ >+ tevent_req_set_callback(req, reply_tdis_done, smb1req); > return; > } > >-#if 0 > struct reply_tdis_state { > struct tevent_queue *wait_queue; > }; >@@ -6245,7 +6230,6 @@ static void reply_tdis_done(struct tevent_req *req) > smb_request_done(smb1req); > END_PROFILE(SMBtdis); > } >-#endif > > /**************************************************************************** > Reply to a echo. >-- >2.20.1 > > >From 6d7fb4ddb7150e4d864c4e9ef0eb463af66c320a Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 12 Mar 2020 10:11:14 -0700 >Subject: [PATCH 12/37] s3: smbd: Add async internals of reply_ulogoffX. > >Waits until all aio requests on all fsp's owned by this >vuid are finished before returning to the client. > >Done this way (commented out) so it is a clean >diff and it's clear what is being added. > >A later commit will remove the old synchronous version. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/reply.c | 162 +++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 162 insertions(+) > >diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c >index db020b64268..23680b6d4e9 100644 >--- a/source3/smbd/reply.c >+++ b/source3/smbd/reply.c >@@ -2665,6 +2665,168 @@ void reply_ulogoffX(struct smb_request *req) > req->vuid = UID_FIELD_INVALID; > } > >+#if 0 >+struct reply_ulogoff_state { >+ struct tevent_queue *wait_queue; >+ struct smbXsrv_session *session; >+}; >+ >+static void reply_ulogoff_wait_done(struct tevent_req *subreq); >+ >+/**************************************************************************** >+ Async SMB1 ulogoff. >+ Note, on failure here we deallocate and return NULL to allow the caller to >+ SMB1 return an error of ERRnomem immediately. >+****************************************************************************/ >+ >+static struct tevent_req *reply_ulogoff_send(struct smb_request *smb1req, >+ struct smbXsrv_session *session) >+{ >+ struct tevent_req *req; >+ struct reply_ulogoff_state *state; >+ struct tevent_req *subreq; >+ files_struct *fsp; >+ struct smbd_server_connection *sconn = session->client->sconn; >+ uint64_t vuid = session->global->session_wire_id; >+ >+ /* Create this off the NULL context. We must clean up on return. */ >+ req = tevent_req_create(NULL, &state, >+ struct reply_ulogoff_state); >+ if (req == NULL) { >+ return NULL; >+ } >+ state->wait_queue = tevent_queue_create(state, >+ "reply_ulogoff_wait_queue"); >+ if (tevent_req_nomem(state->wait_queue, req)) { >+ TALLOC_FREE(req); >+ return NULL; >+ } >+ state->session = session; >+ >+ /* >+ * Make sure that no new request will be able to use this session. >+ * This ensures that once all outstanding fsp->aio_requests >+ * on this session are done, we are safe to close it. >+ */ >+ session->status = NT_STATUS_USER_SESSION_DELETED; >+ >+ for (fsp = sconn->files; fsp; fsp = fsp->next) { >+ if (fsp->vuid != vuid) { >+ continue; >+ } >+ /* >+ * Flag the file as close in progress. >+ * This will prevent any more IO being >+ * done on it. >+ */ >+ fsp->closing = true; >+ >+ if (fsp->num_aio_requests > 0) { >+ /* >+ * 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(fsp->aio_requests, >+ sconn->ev_ctx, >+ state->wait_queue); >+ if (tevent_req_nomem(subreq, req)) { >+ TALLOC_FREE(req); >+ return NULL; >+ } >+ } >+ } >+ >+ /* >+ * Now we add our own waiter to the end of the queue, >+ * this way we get notified when all pending requests are finished >+ * and reply to the outstanding SMB1 request. >+ */ >+ subreq = tevent_queue_wait_send(state, >+ sconn->ev_ctx, >+ state->wait_queue); >+ if (tevent_req_nomem(subreq, req)) { >+ TALLOC_FREE(req); >+ return NULL; >+ } >+ >+ /* >+ * We're really going async - move the SMB1 request from >+ * a talloc stackframe above us to the NULL context. >+ * We need this to stick around until the wait_done >+ * callback is invoked. >+ */ >+ smb1req = talloc_move(NULL, &smb1req); >+ >+ tevent_req_set_callback(subreq, reply_ulogoff_wait_done, req); >+ >+ return req; >+} >+ >+static void reply_ulogoff_wait_done(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ >+ tevent_queue_wait_recv(subreq); >+ TALLOC_FREE(subreq); >+ tevent_req_done(req); >+} >+ >+static NTSTATUS reply_ulogoff_recv(struct tevent_req *req) >+{ >+ return tevent_req_simple_recv_ntstatus(req); >+} >+ >+static void reply_ulogoff_done(struct tevent_req *req) >+{ >+ struct smb_request *smb1req = tevent_req_callback_data( >+ req, struct smb_request); >+ struct reply_ulogoff_state *state = tevent_req_data(req, >+ struct reply_ulogoff_state); >+ struct smbXsrv_session *session = state->session; >+ NTSTATUS status; >+ >+ status = reply_ulogoff_recv(req); >+ TALLOC_FREE(req); >+ if (!NT_STATUS_IS_OK(status)) { >+ TALLOC_FREE(smb1req); >+ END_PROFILE(SMBulogoffX); >+ exit_server(__location__ ": reply_ulogoff_recv failed"); >+ return; >+ } >+ >+ status = smbXsrv_session_logoff(session); >+ if (!NT_STATUS_IS_OK(status)) { >+ TALLOC_FREE(smb1req); >+ END_PROFILE(SMBulogoffX); >+ exit_server(__location__ ": smbXsrv_session_logoff failed"); >+ return; >+ } >+ >+ TALLOC_FREE(session); >+ >+ reply_outbuf(smb1req, 2, 0); >+ SSVAL(smb1req->outbuf, smb_vwv0, 0xff); /* andx chain ends */ >+ SSVAL(smb1req->outbuf, smb_vwv1, 0); /* no andx offset */ >+ >+ DBG_NOTICE("ulogoffX vuid=%llu\n", >+ (unsigned long long)smb1req->vuid); >+ >+ smb1req->vuid = UID_FIELD_INVALID; >+ /* >+ * The following call is needed to push the >+ * reply data back out the socket after async >+ * return. Plus it frees smb1req. >+ */ >+ smb_request_done(smb1req); >+ END_PROFILE(SMBulogoffX); >+} >+#endif >+ > /**************************************************************************** > Reply to a mknew or a create. > ****************************************************************************/ >-- >2.20.1 > > >From 358ab6fdaa88f8240a785db1ea84d29ab6251df1 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 12 Mar 2020 10:15:10 -0700 >Subject: [PATCH 13/37] s3: smbd: In reply_ulogoffX(), replace req -> smb1req. > >Minimises the diff in later commits. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/reply.c | 22 +++++++++++----------- > 1 file changed, 11 insertions(+), 11 deletions(-) > >diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c >index 23680b6d4e9..83c32d3f54b 100644 >--- a/source3/smbd/reply.c >+++ b/source3/smbd/reply.c >@@ -2613,7 +2613,7 @@ void reply_open_and_X(struct smb_request *req) > Reply to a SMBulogoffX. > ****************************************************************************/ > >-void reply_ulogoffX(struct smb_request *req) >+void reply_ulogoffX(struct smb_request *smb1req) > { > struct timeval now = timeval_current(); > struct smbXsrv_session *session = NULL; >@@ -2621,16 +2621,16 @@ void reply_ulogoffX(struct smb_request *req) > > START_PROFILE(SMBulogoffX); > >- status = smb1srv_session_lookup(req->xconn, >- req->vuid, >+ status = smb1srv_session_lookup(smb1req->xconn, >+ smb1req->vuid, > timeval_to_nttime(&now), > &session); > if (!NT_STATUS_IS_OK(status)) { > DEBUG(3,("ulogoff, vuser id %llu does not map to user.\n", >- (unsigned long long)req->vuid)); >+ (unsigned long long)smb1req->vuid)); > >- req->vuid = UID_FIELD_INVALID; >- reply_force_doserror(req, ERRSRV, ERRbaduid); >+ smb1req->vuid = UID_FIELD_INVALID; >+ reply_force_doserror(smb1req, ERRSRV, ERRbaduid); > END_PROFILE(SMBulogoffX); > return; > } >@@ -2654,15 +2654,15 @@ void reply_ulogoffX(struct smb_request *req) > > TALLOC_FREE(session); > >- reply_outbuf(req, 2, 0); >- SSVAL(req->outbuf, smb_vwv0, 0xff); /* andx chain ends */ >- SSVAL(req->outbuf, smb_vwv1, 0); /* no andx offset */ >+ reply_outbuf(smb1req, 2, 0); >+ SSVAL(smb1req->outbuf, smb_vwv0, 0xff); /* andx chain ends */ >+ SSVAL(smb1req->outbuf, smb_vwv1, 0); /* no andx offset */ > > DEBUG(3, ("ulogoffX vuid=%llu\n", >- (unsigned long long)req->vuid)); >+ (unsigned long long)smb1req->vuid)); > > END_PROFILE(SMBulogoffX); >- req->vuid = UID_FIELD_INVALID; >+ smb1req->vuid = UID_FIELD_INVALID; > } > > #if 0 >-- >2.20.1 > > >From 1d8a31d3addd7db9d140084d5e480c889ee8ec21 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 12 Mar 2020 10:16:42 -0700 >Subject: [PATCH 14/37] s3: smbd: reply_ulogoffX() Update to modern coding > standards. > >Minimizes the diff in the later commits. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/reply.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c >index 83c32d3f54b..8836f4e201f 100644 >--- a/source3/smbd/reply.c >+++ b/source3/smbd/reply.c >@@ -2626,8 +2626,8 @@ void reply_ulogoffX(struct smb_request *smb1req) > timeval_to_nttime(&now), > &session); > if (!NT_STATUS_IS_OK(status)) { >- DEBUG(3,("ulogoff, vuser id %llu does not map to user.\n", >- (unsigned long long)smb1req->vuid)); >+ DBG_WARNING("ulogoff, vuser id %llu does not map to user.\n", >+ (unsigned long long)smb1req->vuid); > > smb1req->vuid = UID_FIELD_INVALID; > reply_force_doserror(smb1req, ERRSRV, ERRbaduid); >-- >2.20.1 > > >From 11ff3926cb9cc244e30d59e1e72cf90474a95939 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 12 Mar 2020 10:19:31 -0700 >Subject: [PATCH 15/37] s3: smbd: Remove old synchronous SMB1 reply_ulogoffX(). > >SMB1 user logoff is now fully async. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/reply.c | 37 +++++++++++-------------------------- > 1 file changed, 11 insertions(+), 26 deletions(-) > >diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c >index 8836f4e201f..b3b1d10892e 100644 >--- a/source3/smbd/reply.c >+++ b/source3/smbd/reply.c >@@ -2613,10 +2613,15 @@ void reply_open_and_X(struct smb_request *req) > Reply to a SMBulogoffX. > ****************************************************************************/ > >+static struct tevent_req *reply_ulogoff_send(struct smb_request *smb1req, >+ struct smbXsrv_session *session); >+static void reply_ulogoff_done(struct tevent_req *req); >+ > void reply_ulogoffX(struct smb_request *smb1req) > { > struct timeval now = timeval_current(); > struct smbXsrv_session *session = NULL; >+ struct tevent_req *req; > NTSTATUS status; > > START_PROFILE(SMBulogoffX); >@@ -2635,37 +2640,18 @@ void reply_ulogoffX(struct smb_request *smb1req) > return; > } > >- /* >- * TODO: cancel all outstanding requests on the session >- */ >- status = smbXsrv_session_logoff(session); >- if (!NT_STATUS_IS_OK(status)) { >- DEBUG(0, ("reply_ulogoff: " >- "smbXsrv_session_logoff() failed: %s\n", >- nt_errstr(status))); >- /* >- * If we hit this case, there is something completely >- * wrong, so we better disconnect the transport connection. >- */ >+ req = reply_ulogoff_send(smb1req, session); >+ if (req == NULL) { >+ reply_force_doserror(smb1req, ERRDOS, ERRnomem); > END_PROFILE(SMBulogoffX); >- exit_server(__location__ ": smbXsrv_session_logoff failed"); > return; > } > >- TALLOC_FREE(session); >- >- reply_outbuf(smb1req, 2, 0); >- SSVAL(smb1req->outbuf, smb_vwv0, 0xff); /* andx chain ends */ >- SSVAL(smb1req->outbuf, smb_vwv1, 0); /* no andx offset */ >- >- DEBUG(3, ("ulogoffX vuid=%llu\n", >- (unsigned long long)smb1req->vuid)); >- >- END_PROFILE(SMBulogoffX); >- smb1req->vuid = UID_FIELD_INVALID; >+ /* We're async. This will complete later. */ >+ tevent_req_set_callback(req, reply_ulogoff_done, smb1req); >+ return; > } > >-#if 0 > struct reply_ulogoff_state { > struct tevent_queue *wait_queue; > struct smbXsrv_session *session; >@@ -2825,7 +2811,6 @@ static void reply_ulogoff_done(struct tevent_req *req) > smb_request_done(smb1req); > END_PROFILE(SMBulogoffX); > } >-#endif > > /**************************************************************************** > Reply to a mknew or a create. >-- >2.20.1 > > >From d82f4fdebd5817ae76a436749ec8f9b946388173 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 12 Mar 2020 10:59:16 -0700 >Subject: [PATCH 16/37] s3: smbd: Add async internals of reply_exit(). > >Waits until all aio requests on all fsp's owned by this >vuid are finished before returning to the client. > >Done this way (commented out) so it is a clean >diff and it's clear what is being added. > >A later commit will remove the old synchronous version. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/reply.c | 195 +++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 195 insertions(+) > >diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c >index b3b1d10892e..83114ae2a25 100644 >--- a/source3/smbd/reply.c >+++ b/source3/smbd/reply.c >@@ -5765,6 +5765,201 @@ void reply_exit(struct smb_request *req) > return; > } > >+#if 0 >+struct reply_exit_state { >+ struct tevent_queue *wait_queue; >+}; >+ >+static void reply_exit_wait_done(struct tevent_req *subreq); >+ >+/**************************************************************************** >+ Async SMB1 exit. >+ Note, on failure here we deallocate and return NULL to allow the caller to >+ SMB1 return an error of ERRnomem immediately. >+****************************************************************************/ >+ >+static struct tevent_req *reply_exit_send(struct smb_request *smb1req) >+{ >+ struct tevent_req *req; >+ struct reply_exit_state *state; >+ struct tevent_req *subreq; >+ files_struct *fsp; >+ struct smbd_server_connection *sconn = smb1req->sconn; >+ >+ /* Create this off the NULL context. We must clean up on return. */ >+ req = tevent_req_create(NULL, &state, >+ struct reply_exit_state); >+ if (req == NULL) { >+ return NULL; >+ } >+ state->wait_queue = tevent_queue_create(state, >+ "reply_exit_wait_queue"); >+ if (tevent_req_nomem(state->wait_queue, req)) { >+ TALLOC_FREE(req); >+ return NULL; >+ } >+ >+ for (fsp = sconn->files; fsp; fsp = fsp->next) { >+ if (fsp->file_pid != smb1req->smbpid) { >+ continue; >+ } >+ if (fsp->vuid != smb1req->vuid) { >+ continue; >+ } >+ /* >+ * Flag the file as close in progress. >+ * This will prevent any more IO being >+ * done on it. >+ */ >+ fsp->closing = true; >+ >+ if (fsp->num_aio_requests > 0) { >+ /* >+ * 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(fsp->aio_requests, >+ sconn->ev_ctx, >+ state->wait_queue); >+ if (tevent_req_nomem(subreq, req)) { >+ TALLOC_FREE(req); >+ return NULL; >+ } >+ } >+ } >+ >+ /* >+ * Now we add our own waiter to the end of the queue, >+ * this way we get notified when all pending requests are finished >+ * and reply to the outstanding SMB1 request. >+ */ >+ subreq = tevent_queue_wait_send(state, >+ sconn->ev_ctx, >+ state->wait_queue); >+ if (tevent_req_nomem(subreq, req)) { >+ TALLOC_FREE(req); >+ return NULL; >+ } >+ >+ /* >+ * We're really going async - move the SMB1 request from >+ * a talloc stackframe above us to the NULL context. >+ * We need this to stick around until the wait_done >+ * callback is invoked. >+ */ >+ smb1req = talloc_move(NULL, &smb1req); >+ >+ tevent_req_set_callback(subreq, reply_exit_wait_done, req); >+ >+ return req; >+} >+ >+static void reply_exit_wait_done(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ >+ tevent_queue_wait_recv(subreq); >+ TALLOC_FREE(subreq); >+ tevent_req_done(req); >+} >+ >+static NTSTATUS reply_exit_recv(struct tevent_req *req) >+{ >+ return tevent_req_simple_recv_ntstatus(req); >+} >+ >+static void reply_exit_done(struct tevent_req *req) >+{ >+ struct smb_request *smb1req = tevent_req_callback_data( >+ req, struct smb_request); >+ struct smbd_server_connection *sconn = smb1req->sconn; >+ struct smbXsrv_connection *xconn = smb1req->xconn; >+ NTTIME now = timeval_to_nttime(&smb1req->request_time); >+ struct smbXsrv_session *session = NULL; >+ files_struct *fsp, *next; >+ NTSTATUS status; >+ >+ status = reply_exit_recv(req); >+ TALLOC_FREE(req); >+ if (!NT_STATUS_IS_OK(status)) { >+ TALLOC_FREE(smb1req); >+ END_PROFILE(SMBexit); >+ exit_server(__location__ ": reply_exit_recv failed"); >+ return; >+ } >+ >+ /* >+ * Ensure the session is still valid. >+ */ >+ status = smb1srv_session_lookup(xconn, >+ smb1req->vuid, >+ now, >+ &session); >+ if (!NT_STATUS_IS_OK(status)) { >+ reply_force_doserror(smb1req, ERRSRV, ERRinvnid); >+ smb_request_done(smb1req); >+ END_PROFILE(SMBexit); >+ } >+ >+ /* >+ * Ensure the vuid is still valid - no one >+ * called reply_ulogoffX() in the meantime. >+ * reply_exit() doesn't have AS_USER set, so >+ * use set_current_user_info() directly. >+ * This is the same logic as in switch_message(). >+ */ >+ if (session->global->auth_session_info != NULL) { >+ set_current_user_info( >+ session->global->auth_session_info->unix_info->sanitized_username, >+ session->global->auth_session_info->unix_info->unix_name, >+ session->global->auth_session_info->info->domain_name); >+ } >+ >+ /* No more aio - do the actual closes. */ >+ for (fsp = sconn->files; fsp; fsp = next) { >+ bool ok; >+ next = fsp->next; >+ >+ if (fsp->file_pid != smb1req->smbpid) { >+ continue; >+ } >+ if (fsp->vuid != smb1req->vuid) { >+ continue; >+ } >+ if (!fsp->closing) { >+ continue; >+ } >+ >+ /* >+ * reply_exit() has the DO_CHDIR flag set. >+ */ >+ ok = chdir_current_service(fsp->conn); >+ if (!ok) { >+ reply_force_doserror(smb1req, ERRSRV, ERRinvnid); >+ smb_request_done(smb1req); >+ END_PROFILE(SMBexit); >+ } >+ close_file(NULL, fsp, SHUTDOWN_CLOSE); >+ } >+ >+ reply_outbuf(smb1req, 0, 0); >+ /* >+ * The following call is needed to push the >+ * reply data back out the socket after async >+ * return. Plus it frees smb1req. >+ */ >+ smb_request_done(smb1req); >+ DBG_INFO("reply_exit complete\n"); >+ END_PROFILE(SMBexit); >+ return; >+} >+#endif >+ > struct reply_close_state { > files_struct *fsp; > struct smb_request *smbreq; >-- >2.20.1 > > >From 6c8034960dbf89fe97d806c3f470964c36434f82 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 12 Mar 2020 11:01:05 -0700 >Subject: [PATCH 17/37] s3: smbd: Remove old synchronous SMB1 reply_exit(). > >SMB1 exit is now fully async. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/reply.c | 23 ++++++++++++++--------- > 1 file changed, 14 insertions(+), 9 deletions(-) > >diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c >index 83114ae2a25..5696607e995 100644 >--- a/source3/smbd/reply.c >+++ b/source3/smbd/reply.c >@@ -5751,21 +5751,27 @@ void reply_flush(struct smb_request *req) > conn POINTER CAN BE NULL HERE ! > ****************************************************************************/ > >-void reply_exit(struct smb_request *req) >-{ >- START_PROFILE(SMBexit); >+static struct tevent_req *reply_exit_send(struct smb_request *smb1req); >+static void reply_exit_done(struct tevent_req *req); > >- file_close_pid(req->sconn, req->smbpid, req->vuid); >+void reply_exit(struct smb_request *smb1req) >+{ >+ struct tevent_req *req; > >- reply_outbuf(req, 0, 0); >+ START_PROFILE(SMBexit); > >- DEBUG(3,("exit\n")); >+ req = reply_exit_send(smb1req); >+ if (req == NULL) { >+ reply_force_doserror(smb1req, ERRDOS, ERRnomem); >+ END_PROFILE(SMBexit); >+ return; >+ } > >- END_PROFILE(SMBexit); >+ /* We're async. This will complete later. */ >+ tevent_req_set_callback(req, reply_exit_done, smb1req); > return; > } > >-#if 0 > struct reply_exit_state { > struct tevent_queue *wait_queue; > }; >@@ -5958,7 +5964,6 @@ static void reply_exit_done(struct tevent_req *req) > END_PROFILE(SMBexit); > return; > } >-#endif > > struct reply_close_state { > files_struct *fsp; >-- >2.20.1 > > >From ef0d055dd7b3b8b473ac38545ad6edbe4098a88b Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 12 Mar 2020 11:02:19 -0700 >Subject: [PATCH 18/37] s3: smbd: Remove file_close_pid(). > >The old synchronous reply_exit() was the only user. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/files.c | 17 ----------------- > source3/smbd/proto.h | 2 -- > 2 files changed, 19 deletions(-) > >diff --git a/source3/smbd/files.c b/source3/smbd/files.c >index b06511147ab..a982c0a5980 100644 >--- a/source3/smbd/files.c >+++ b/source3/smbd/files.c >@@ -188,23 +188,6 @@ void file_close_conn(connection_struct *conn) > } > } > >-/**************************************************************************** >- Close all open files for a pid and a vuid. >-****************************************************************************/ >- >-void file_close_pid(struct smbd_server_connection *sconn, uint16_t smbpid, >- uint64_t vuid) >-{ >- files_struct *fsp, *next; >- >- for (fsp=sconn->files;fsp;fsp=next) { >- next = fsp->next; >- if ((fsp->file_pid == smbpid) && (fsp->vuid == vuid)) { >- close_file(NULL, fsp, SHUTDOWN_CLOSE); >- } >- } >-} >- > /**************************************************************************** > Initialise file structures. > ****************************************************************************/ >diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h >index 199f8544e01..0f773c06225 100644 >--- a/source3/smbd/proto.h >+++ b/source3/smbd/proto.h >@@ -379,8 +379,6 @@ void fsp_set_gen_id(files_struct *fsp); > NTSTATUS file_new(struct smb_request *req, connection_struct *conn, > files_struct **result); > void file_close_conn(connection_struct *conn); >-void file_close_pid(struct smbd_server_connection *sconn, uint16_t smbpid, >- uint64_t vuid); > bool file_init_global(void); > bool file_init(struct smbd_server_connection *sconn); > void file_close_user(struct smbd_server_connection *sconn, uint64_t vuid); >-- >2.20.1 > > >From ae4fa8696105c15e3874df8a491e9cc57ccc3543 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 12 Mar 2020 17:16:18 -0700 >Subject: [PATCH 19/37] Revert "vfs_default: pass in state as the callback data > to the subreq" > >This reverts commit 0e894f3e48285415f72cf7a68e26f1802fe8045d. > >Now all SHUTDOWN_CLOSE paths are async safe, we no >longer need this. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/modules/vfs_default.c | 9 +++++---- > 1 file changed, 5 insertions(+), 4 deletions(-) > >diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c >index cf24e66e048..b8723156b15 100644 >--- a/source3/modules/vfs_default.c >+++ b/source3/modules/vfs_default.c >@@ -3417,7 +3417,7 @@ static struct tevent_req *vfswrap_getxattrat_send( > if (tevent_req_nomem(subreq, req)) { > return tevent_req_post(req, ev); > } >- tevent_req_set_callback(subreq, vfswrap_getxattrat_done, state); >+ tevent_req_set_callback(subreq, vfswrap_getxattrat_done, req); > > talloc_set_destructor(state, vfswrap_getxattrat_state_destructor); > >@@ -3512,9 +3512,10 @@ end_profile: > > static void vfswrap_getxattrat_done(struct tevent_req *subreq) > { >- struct vfswrap_getxattrat_state *state = tevent_req_callback_data( >- subreq, struct vfswrap_getxattrat_state); >- struct tevent_req *req = state->req; >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ struct vfswrap_getxattrat_state *state = tevent_req_data( >+ req, struct vfswrap_getxattrat_state); > int ret; > bool ok; > >-- >2.20.1 > > >From 7afd294b43c632ac63f560857d14cc6e179808d6 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 12 Mar 2020 17:15:23 -0700 >Subject: [PATCH 20/37] Revert "vfs_default: Protect vfs_getxattrat_done() from > accessing a freed req pointer" > >This reverts commit 95cfcda13fe9a70b9955a7c44173d619eacb34c1. > >Now all SHUTDOWN_CLOSE paths are async safe, we no >longer need this. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/modules/vfs_default.c | 19 ------------------- > 1 file changed, 19 deletions(-) > >diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c >index b8723156b15..fac7fa30ab7 100644 >--- a/source3/modules/vfs_default.c >+++ b/source3/modules/vfs_default.c >@@ -3289,15 +3289,6 @@ struct vfswrap_getxattrat_state { > static int vfswrap_getxattrat_state_destructor( > struct vfswrap_getxattrat_state *state) > { >- /* >- * This destructor only gets called if the request is still >- * in flight, which is why we deny it by returning -1. We >- * also set the req pointer to NULL so the _done function >- * can detect the caller doesn't want the result anymore. >- * >- * Forcing the fsp closed by a SHUTDOWN_CLOSE can cause this. >- */ >- state->req = NULL; > return -1; > } > >@@ -3529,16 +3520,6 @@ static void vfswrap_getxattrat_done(struct tevent_req *subreq) > TALLOC_FREE(subreq); > SMBPROFILE_BYTES_ASYNC_END(state->profile_bytes); > talloc_set_destructor(state, NULL); >- if (req == NULL) { >- /* >- * We were shutdown closed in flight. No one wants the result, >- * and state has been reparented to the NULL context, so just >- * free it so we don't leak memory. >- */ >- DBG_NOTICE("getxattr request abandoned in flight\n"); >- TALLOC_FREE(state); >- return; >- } > if (ret != 0) { > if (ret != EAGAIN) { > tevent_req_error(req, ret); >-- >2.20.1 > > >From c474a242f2d1be0131aed649035a92246f44f1e5 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 12 Mar 2020 17:20:31 -0700 >Subject: [PATCH 21/37] Revert "s3: VFS: vfs_glusterfs. Protect > vfs_gluster_fsync_done() from accessing a freed req pointer." > >This reverts commit 9ecbda263f102a24257fd47142b7c24d1f429d8d. > >Now all SHUTDOWN_CLOSE paths are async safe, we no >longer need this. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/modules/vfs_glusterfs.c | 20 -------------------- > 1 file changed, 20 deletions(-) > >diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c >index b5300282b7b..4706e6f9189 100644 >--- a/source3/modules/vfs_glusterfs.c >+++ b/source3/modules/vfs_glusterfs.c >@@ -1197,15 +1197,6 @@ static void vfs_gluster_fsync_do(void *private_data) > > static int vfs_gluster_fsync_state_destructor(struct vfs_gluster_fsync_state *state) > { >- /* >- * This destructor only gets called if the request is still >- * in flight, which is why we deny it by returning -1. We >- * also set the req pointer to NULL so the _done function >- * can detect the caller doesn't want the result anymore. >- * >- * Forcing the fsp closed by a SHUTDOWN_CLOSE can cause this. >- */ >- state->req = NULL; > return -1; > } > >@@ -1220,17 +1211,6 @@ static void vfs_gluster_fsync_done(struct tevent_req *subreq) > TALLOC_FREE(subreq); > SMBPROFILE_BYTES_ASYNC_END(state->profile_bytes); > talloc_set_destructor(state, NULL); >- if (req == NULL) { >- /* >- * We were shutdown closed in flight. No one >- * wants the result, and state has been reparented >- * to the NULL context, so just free it so we >- * don't leak memory. >- */ >- DBG_NOTICE("gluster fsync request abandoned in flight\n"); >- TALLOC_FREE(state); >- return; >- } > if (ret != 0) { > if (ret != EAGAIN) { > tevent_req_error(req, ret); >-- >2.20.1 > > >From 599961ca8c1b058c715155920d32102f120ecc83 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 12 Mar 2020 17:20:35 -0700 >Subject: [PATCH 22/37] Revert "s3: VFS: vfs_glusterfs. Pass in struct > vfs_gluster_fsync_state as the callback data to the subreq." > >This reverts commit cdde55a69d0dacd2f9939c2f00cd356c0186f791. > >Now all SHUTDOWN_CLOSE paths are async safe, we no >longer need this. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/modules/vfs_glusterfs.c | 9 +++++---- > 1 file changed, 5 insertions(+), 4 deletions(-) > >diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c >index 4706e6f9189..d5d402d72ab 100644 >--- a/source3/modules/vfs_glusterfs.c >+++ b/source3/modules/vfs_glusterfs.c >@@ -1158,7 +1158,7 @@ static struct tevent_req *vfs_gluster_fsync_send(struct vfs_handle_struct > if (tevent_req_nomem(subreq, req)) { > return tevent_req_post(req, ev); > } >- tevent_req_set_callback(subreq, vfs_gluster_fsync_done, state); >+ tevent_req_set_callback(subreq, vfs_gluster_fsync_done, req); > > talloc_set_destructor(state, vfs_gluster_fsync_state_destructor); > >@@ -1202,9 +1202,10 @@ static int vfs_gluster_fsync_state_destructor(struct vfs_gluster_fsync_state *st > > static void vfs_gluster_fsync_done(struct tevent_req *subreq) > { >- struct vfs_gluster_fsync_state *state = tevent_req_callback_data( >- subreq, struct vfs_gluster_fsync_state); >- struct tevent_req *req = state->req; >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ struct vfs_gluster_fsync_state *state = tevent_req_data( >+ req, struct vfs_gluster_fsync_state); > int ret; > > ret = pthreadpool_tevent_job_recv(subreq); >-- >2.20.1 > > >From ec8fad44351b0b1414f8cb4fee600bb24b27ca85 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 12 Mar 2020 17:20:36 -0700 >Subject: [PATCH 23/37] Revert "s3: VFS: vfs_glusterfs: Add tevent_req pointer > to state struct in vfs_gluster_fsync_state." > >This reverts commit c0c088b1b786f0ba248960114191277e91bbba2f. > >Now all SHUTDOWN_CLOSE paths are async safe, we no >longer need this. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/modules/vfs_glusterfs.c | 2 -- > 1 file changed, 2 deletions(-) > >diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c >index d5d402d72ab..4e978f168d6 100644 >--- a/source3/modules/vfs_glusterfs.c >+++ b/source3/modules/vfs_glusterfs.c >@@ -1114,7 +1114,6 @@ static int vfs_gluster_renameat(struct vfs_handle_struct *handle, > } > > struct vfs_gluster_fsync_state { >- struct tevent_req *req; > ssize_t ret; > glfs_fd_t *fd; > >@@ -1145,7 +1144,6 @@ static struct tevent_req *vfs_gluster_fsync_send(struct vfs_handle_struct > return NULL; > } > >- state->req = req; > state->ret = -1; > state->fd = glfd; > >-- >2.20.1 > > >From c818437d668012c4d510f399224f170d6c01fd61 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 12 Mar 2020 17:20:37 -0700 >Subject: [PATCH 24/37] Revert "s3: VFS: vfs_glusterfs. Protect > vfs_gluster_pwrite_done() from accessing a freed req pointer." > >This reverts commit 67910c751c9f5ce8cdd1e57b34e51e5b7163838b. > >Now all SHUTDOWN_CLOSE paths are async safe, we no >longer need this. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/modules/vfs_glusterfs.c | 20 -------------------- > 1 file changed, 20 deletions(-) > >diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c >index 4e978f168d6..52c33725b8d 100644 >--- a/source3/modules/vfs_glusterfs.c >+++ b/source3/modules/vfs_glusterfs.c >@@ -967,15 +967,6 @@ static void vfs_gluster_pwrite_do(void *private_data) > > static int vfs_gluster_pwrite_state_destructor(struct vfs_gluster_pwrite_state *state) > { >- /* >- * This destructor only gets called if the request is still >- * in flight, which is why we deny it by returning -1. We >- * also set the req pointer to NULL so the _done function >- * can detect the caller doesn't want the result anymore. >- * >- * Forcing the fsp closed by a SHUTDOWN_CLOSE can cause this. >- */ >- state->req = NULL; > return -1; > } > >@@ -990,17 +981,6 @@ static void vfs_gluster_pwrite_done(struct tevent_req *subreq) > TALLOC_FREE(subreq); > SMBPROFILE_BYTES_ASYNC_END(state->profile_bytes); > talloc_set_destructor(state, NULL); >- if (req == NULL) { >- /* >- * We were shutdown closed in flight. No one >- * wants the result, and state has been reparented >- * to the NULL context, so just free it so we >- * don't leak memory. >- */ >- DBG_NOTICE("gluster pwrite request abandoned in flight\n"); >- TALLOC_FREE(state); >- return; >- } > if (ret != 0) { > if (ret != EAGAIN) { > tevent_req_error(req, ret); >-- >2.20.1 > > >From 3364e17a0acc7e65ec3c697bb9d4e603e5b5e70b Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 12 Mar 2020 17:20:39 -0700 >Subject: [PATCH 25/37] Revert "s3: VFS: vfs_glusterfs. Pass in struct > vfs_gluster_pwrite_state as the callback data to the subreq." > >This reverts commit 3357a77d0823eddc1b0db68cfa251a0d54058c88. > >Now all SHUTDOWN_CLOSE paths are async safe, we no >longer need this. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/modules/vfs_glusterfs.c | 9 +++++---- > 1 file changed, 5 insertions(+), 4 deletions(-) > >diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c >index 52c33725b8d..456e0c8a498 100644 >--- a/source3/modules/vfs_glusterfs.c >+++ b/source3/modules/vfs_glusterfs.c >@@ -926,7 +926,7 @@ static struct tevent_req *vfs_gluster_pwrite_send(struct vfs_handle_struct > if (tevent_req_nomem(subreq, req)) { > return tevent_req_post(req, ev); > } >- tevent_req_set_callback(subreq, vfs_gluster_pwrite_done, state); >+ tevent_req_set_callback(subreq, vfs_gluster_pwrite_done, req); > > talloc_set_destructor(state, vfs_gluster_pwrite_state_destructor); > >@@ -972,9 +972,10 @@ static int vfs_gluster_pwrite_state_destructor(struct vfs_gluster_pwrite_state * > > static void vfs_gluster_pwrite_done(struct tevent_req *subreq) > { >- struct vfs_gluster_pwrite_state *state = tevent_req_callback_data( >- subreq, struct vfs_gluster_pwrite_state); >- struct tevent_req *req = state->req; >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ struct vfs_gluster_pwrite_state *state = tevent_req_data( >+ req, struct vfs_gluster_pwrite_state); > int ret; > > ret = pthreadpool_tevent_job_recv(subreq); >-- >2.20.1 > > >From 76578154daac123c8cdfc08552e4080e19b3900e Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 12 Mar 2020 17:20:40 -0700 >Subject: [PATCH 26/37] Revert "s3: VFS: vfs_glusterfs: Add tevent_req pointer > to state struct in vfs_gluster_pwrite_state." > >This reverts commit 058a7effd00b47e4778f7d680cc9c2a7d40d5fa8. > >Now all SHUTDOWN_CLOSE paths are async safe, we no >longer need this. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/modules/vfs_glusterfs.c | 2 -- > 1 file changed, 2 deletions(-) > >diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c >index 456e0c8a498..7924f123cca 100644 >--- a/source3/modules/vfs_glusterfs.c >+++ b/source3/modules/vfs_glusterfs.c >@@ -873,7 +873,6 @@ static ssize_t vfs_gluster_pread_recv(struct tevent_req *req, > } > > struct vfs_gluster_pwrite_state { >- struct tevent_req *req; > ssize_t ret; > glfs_fd_t *fd; > const void *buf; >@@ -909,7 +908,6 @@ static struct tevent_req *vfs_gluster_pwrite_send(struct vfs_handle_struct > return NULL; > } > >- state->req = req; > state->ret = -1; > state->fd = glfd; > state->buf = data; >-- >2.20.1 > > >From 3115305523d1dfabc58159030a696d696dcd359a Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 12 Mar 2020 17:20:41 -0700 >Subject: [PATCH 27/37] Revert "s3: VFS: vfs_glusterfs. Protect > vfs_gluster_pread_done() from accessing a freed req pointer." > >This reverts commit 99283871c5230e640a8102943ebed685459ed9af. > >Now all SHUTDOWN_CLOSE paths are async safe, we no >longer need this. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/modules/vfs_glusterfs.c | 20 -------------------- > 1 file changed, 20 deletions(-) > >diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c >index 7924f123cca..84b284152c6 100644 >--- a/source3/modules/vfs_glusterfs.c >+++ b/source3/modules/vfs_glusterfs.c >@@ -807,15 +807,6 @@ static void vfs_gluster_pread_do(void *private_data) > > static int vfs_gluster_pread_state_destructor(struct vfs_gluster_pread_state *state) > { >- /* >- * This destructor only gets called if the request is still >- * in flight, which is why we deny it by returning -1. We >- * also set the req pointer to NULL so the _done function >- * can detect the caller doesn't want the result anymore. >- * >- * Forcing the fsp closed by a SHUTDOWN_CLOSE can cause this. >- */ >- state->req = NULL; > return -1; > } > >@@ -830,17 +821,6 @@ static void vfs_gluster_pread_done(struct tevent_req *subreq) > TALLOC_FREE(subreq); > SMBPROFILE_BYTES_ASYNC_END(state->profile_bytes); > talloc_set_destructor(state, NULL); >- if (req == NULL) { >- /* >- * We were shutdown closed in flight. No one >- * wants the result, and state has been reparented >- * to the NULL context, so just free it so we >- * don't leak memory. >- */ >- DBG_NOTICE("gluster pread request abandoned in flight\n"); >- TALLOC_FREE(state); >- return; >- } > if (ret != 0) { > if (ret != EAGAIN) { > tevent_req_error(req, ret); >-- >2.20.1 > > >From dbf407afe6464aaaea4bc0877a974299caf5bc2b Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 12 Mar 2020 17:20:42 -0700 >Subject: [PATCH 28/37] Revert "s3: VFS: vfs_glusterfs. Pass in struct > vfs_gluster_pread_state as the callback data to the subreq." > >This reverts commit c6c4e2de22cd3d84f45f5c21e6b09b09274f7f7b. > >Now all SHUTDOWN_CLOSE paths are async safe, we no >longer need this. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/modules/vfs_glusterfs.c | 9 +++++---- > 1 file changed, 5 insertions(+), 4 deletions(-) > >diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c >index 84b284152c6..6598aadad17 100644 >--- a/source3/modules/vfs_glusterfs.c >+++ b/source3/modules/vfs_glusterfs.c >@@ -766,7 +766,7 @@ static struct tevent_req *vfs_gluster_pread_send(struct vfs_handle_struct > if (tevent_req_nomem(subreq, req)) { > return tevent_req_post(req, ev); > } >- tevent_req_set_callback(subreq, vfs_gluster_pread_done, state); >+ tevent_req_set_callback(subreq, vfs_gluster_pread_done, req); > > talloc_set_destructor(state, vfs_gluster_pread_state_destructor); > >@@ -812,9 +812,10 @@ static int vfs_gluster_pread_state_destructor(struct vfs_gluster_pread_state *st > > static void vfs_gluster_pread_done(struct tevent_req *subreq) > { >- struct vfs_gluster_pread_state *state = tevent_req_callback_data( >- subreq, struct vfs_gluster_pread_state); >- struct tevent_req *req = state->req; >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ struct vfs_gluster_pread_state *state = tevent_req_data( >+ req, struct vfs_gluster_pread_state); > int ret; > > ret = pthreadpool_tevent_job_recv(subreq); >-- >2.20.1 > > >From 085c50d8a1d2b545936d133031f80b39509a9959 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 12 Mar 2020 17:20:43 -0700 >Subject: [PATCH 29/37] Revert "s3: VFS: vfs_glusterfs: Add tevent_req pointer > to state struct in vfs_gluster_pread_state." > >This reverts commit 0e3dc0078ebd6aa79553bf2afa8e72945e23dfb0. > >Now all SHUTDOWN_CLOSE paths are async safe, we no >longer need this. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/modules/vfs_glusterfs.c | 2 -- > 1 file changed, 2 deletions(-) > >diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c >index 6598aadad17..d4b68fba376 100644 >--- a/source3/modules/vfs_glusterfs.c >+++ b/source3/modules/vfs_glusterfs.c >@@ -713,7 +713,6 @@ static ssize_t vfs_gluster_pread(struct vfs_handle_struct *handle, > } > > struct vfs_gluster_pread_state { >- struct tevent_req *req; > ssize_t ret; > glfs_fd_t *fd; > void *buf; >@@ -749,7 +748,6 @@ static struct tevent_req *vfs_gluster_pread_send(struct vfs_handle_struct > return NULL; > } > >- state->req = req; > state->ret = -1; > state->fd = glfd; > state->buf = data; >-- >2.20.1 > > >From f4ebd048f5709fcfd838f9c3de2bd1a10ea3fc37 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 12 Mar 2020 17:20:44 -0700 >Subject: [PATCH 30/37] Revert "s3: VFS: vfs_default. Protect vfs_fsync_done() > from accessing a freed req pointer." > >This reverts commit 18671534e42f66b904e51c3fbe887e998ff79493. > >Now all SHUTDOWN_CLOSE paths are async safe, we no >longer need this. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/modules/vfs_default.c | 20 -------------------- > 1 file changed, 20 deletions(-) > >diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c >index fac7fa30ab7..f9d958a003d 100644 >--- a/source3/modules/vfs_default.c >+++ b/source3/modules/vfs_default.c >@@ -1151,15 +1151,6 @@ static void vfs_fsync_do(void *private_data) > > static int vfs_fsync_state_destructor(struct vfswrap_fsync_state *state) > { >- /* >- * This destructor only gets called if the request is still >- * in flight, which is why we deny it by returning -1. We >- * also set the req pointer to NULL so the _done function >- * can detect the caller doesn't want the result anymore. >- * >- * Forcing the fsp closed by a SHUTDOWN_CLOSE can cause this. >- */ >- state->req = NULL; > return -1; > } > >@@ -1174,17 +1165,6 @@ static void vfs_fsync_done(struct tevent_req *subreq) > TALLOC_FREE(subreq); > SMBPROFILE_BYTES_ASYNC_END(state->profile_bytes); > talloc_set_destructor(state, NULL); >- if (req == NULL) { >- /* >- * We were shutdown closed in flight. No one >- * wants the result, and state has been reparented >- * to the NULL context, so just free it so we >- * don't leak memory. >- */ >- DBG_NOTICE("fsync request abandoned in flight\n"); >- TALLOC_FREE(state); >- return; >- } > if (ret != 0) { > if (ret != EAGAIN) { > tevent_req_error(req, ret); >-- >2.20.1 > > >From cce15acb369eeb8295469d2226925597ea37279d Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 12 Mar 2020 17:20:45 -0700 >Subject: [PATCH 31/37] Revert "s3: VFS: vfs_default. Pass in struct > vfswrap_fsync_state as the callback data to the subreq." > >This reverts commit d623779913e0d4a46d7e299dc41b5c83cb127872. > >Now all SHUTDOWN_CLOSE paths are async safe, we no >longer need this. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/modules/vfs_default.c | 9 +++++---- > 1 file changed, 5 insertions(+), 4 deletions(-) > >diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c >index f9d958a003d..28b8c04dee4 100644 >--- a/source3/modules/vfs_default.c >+++ b/source3/modules/vfs_default.c >@@ -1116,7 +1116,7 @@ static struct tevent_req *vfswrap_fsync_send(struct vfs_handle_struct *handle, > if (tevent_req_nomem(subreq, req)) { > return tevent_req_post(req, ev); > } >- tevent_req_set_callback(subreq, vfs_fsync_done, state); >+ tevent_req_set_callback(subreq, vfs_fsync_done, req); > > talloc_set_destructor(state, vfs_fsync_state_destructor); > >@@ -1156,9 +1156,10 @@ static int vfs_fsync_state_destructor(struct vfswrap_fsync_state *state) > > static void vfs_fsync_done(struct tevent_req *subreq) > { >- struct vfswrap_fsync_state *state = tevent_req_callback_data( >- subreq, struct vfswrap_fsync_state); >- struct tevent_req *req = state->req; >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ struct vfswrap_fsync_state *state = tevent_req_data( >+ req, struct vfswrap_fsync_state); > int ret; > > ret = pthreadpool_tevent_job_recv(subreq); >-- >2.20.1 > > >From def3bd092f746b4056dc7505d8eaec347ce3aefc Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 12 Mar 2020 17:20:46 -0700 >Subject: [PATCH 32/37] Revert "s3: VFS: vfs_default: Add tevent_req pointer to > state struct in vfswrap_fsync_state." > >This reverts commit 4adde71b99d4ab09914072458329d5f1008b77e3. > >Now all SHUTDOWN_CLOSE paths are async safe, we no >longer need this. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/modules/vfs_default.c | 2 -- > 1 file changed, 2 deletions(-) > >diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c >index 28b8c04dee4..3425ee31dcb 100644 >--- a/source3/modules/vfs_default.c >+++ b/source3/modules/vfs_default.c >@@ -1078,7 +1078,6 @@ static ssize_t vfswrap_pwrite_recv(struct tevent_req *req, > } > > struct vfswrap_fsync_state { >- struct tevent_req *req; > ssize_t ret; > int fd; > >@@ -1103,7 +1102,6 @@ static struct tevent_req *vfswrap_fsync_send(struct vfs_handle_struct *handle, > return NULL; > } > >- state->req = req; > state->ret = -1; > state->fd = fsp->fh->fd; > >-- >2.20.1 > > >From 1b7f921dbd5a481eda81e1b13fb370d2f11adf04 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 12 Mar 2020 17:20:47 -0700 >Subject: [PATCH 33/37] Revert "s3: VFS: vfs_default. Protect vfs_pwrite_done() > from accessing a freed req pointer." > >This reverts commit c8cd93dd54cb9f78665928d4bc8fcc3baf084b6f. > >Now all SHUTDOWN_CLOSE paths are async safe, we no >longer need this. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/modules/vfs_default.c | 20 -------------------- > 1 file changed, 20 deletions(-) > >diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c >index 3425ee31dcb..641764e41f1 100644 >--- a/source3/modules/vfs_default.c >+++ b/source3/modules/vfs_default.c >@@ -1012,15 +1012,6 @@ static void vfs_pwrite_do(void *private_data) > > static int vfs_pwrite_state_destructor(struct vfswrap_pwrite_state *state) > { >- /* >- * This destructor only gets called if the request is still >- * in flight, which is why we deny it by returning -1. We >- * also set the req pointer to NULL so the _done function >- * can detect the caller doesn't want the result anymore. >- * >- * Forcing the fsp closed by a SHUTDOWN_CLOSE can cause this. >- */ >- state->req = NULL; > return -1; > } > >@@ -1035,17 +1026,6 @@ static void vfs_pwrite_done(struct tevent_req *subreq) > TALLOC_FREE(subreq); > SMBPROFILE_BYTES_ASYNC_END(state->profile_bytes); > talloc_set_destructor(state, NULL); >- if (req == NULL) { >- /* >- * We were shutdown closed in flight. No one >- * wants the result, and state has been reparented >- * to the NULL context, so just free it so we >- * don't leak memory. >- */ >- DBG_NOTICE("pwrite request abandoned in flight\n"); >- TALLOC_FREE(state); >- return; >- } > if (ret != 0) { > if (ret != EAGAIN) { > tevent_req_error(req, ret); >-- >2.20.1 > > >From 52def19f3aa10d7d2c4dba0c69395b4fd18839f6 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 12 Mar 2020 17:20:48 -0700 >Subject: [PATCH 34/37] Revert "s3: VFS: vfs_default. Pass in struct > vfswrap_pwrite_state as the callback data to the subreq." > >This reverts commit 13e25d68385aa951115e0e063ec6a9a281fea4a4. > >Now all SHUTDOWN_CLOSE paths are async safe, we no >longer need this. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/modules/vfs_default.c | 9 +++++---- > 1 file changed, 5 insertions(+), 4 deletions(-) > >diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c >index 641764e41f1..cbc8335cd12 100644 >--- a/source3/modules/vfs_default.c >+++ b/source3/modules/vfs_default.c >@@ -976,7 +976,7 @@ static struct tevent_req *vfswrap_pwrite_send(struct vfs_handle_struct *handle, > if (tevent_req_nomem(subreq, req)) { > return tevent_req_post(req, ev); > } >- tevent_req_set_callback(subreq, vfs_pwrite_done, state); >+ tevent_req_set_callback(subreq, vfs_pwrite_done, req); > > talloc_set_destructor(state, vfs_pwrite_state_destructor); > >@@ -1017,9 +1017,10 @@ static int vfs_pwrite_state_destructor(struct vfswrap_pwrite_state *state) > > static void vfs_pwrite_done(struct tevent_req *subreq) > { >- struct vfswrap_pwrite_state *state = tevent_req_callback_data( >- subreq, struct vfswrap_pwrite_state); >- struct tevent_req *req = state->req; >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ struct vfswrap_pwrite_state *state = tevent_req_data( >+ req, struct vfswrap_pwrite_state); > int ret; > > ret = pthreadpool_tevent_job_recv(subreq); >-- >2.20.1 > > >From 4e575e34659e86e4d7d55264890d05a5616e2d4a Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 12 Mar 2020 17:20:49 -0700 >Subject: [PATCH 35/37] Revert "s3: VFS: vfs_default: Add tevent_req pointer to > state struct in vfswrap_pwrite_state." > >This reverts commit 86cc7439501ab9b9eb018a18dbbef9567eb9b6f9. > >Now all SHUTDOWN_CLOSE paths are async safe, we no >longer need this. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/modules/vfs_default.c | 2 -- > 1 file changed, 2 deletions(-) > >diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c >index cbc8335cd12..21bc9c7adf7 100644 >--- a/source3/modules/vfs_default.c >+++ b/source3/modules/vfs_default.c >@@ -929,7 +929,6 @@ static ssize_t vfswrap_pread_recv(struct tevent_req *req, > } > > struct vfswrap_pwrite_state { >- struct tevent_req *req; > ssize_t ret; > int fd; > const void *buf; >@@ -959,7 +958,6 @@ static struct tevent_req *vfswrap_pwrite_send(struct vfs_handle_struct *handle, > return NULL; > } > >- state->req = req; > state->ret = -1; > state->fd = fsp->fh->fd; > state->buf = data; >-- >2.20.1 > > >From db79deb893d550fcad24eba51c0f34e5accf1880 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 12 Mar 2020 17:20:49 -0700 >Subject: [PATCH 36/37] Revert "s3: VFS: vfs_default. Protect vfs_pread_done() > from accessing a freed req pointer." > >This reverts commit b9ad06079fe362385cc4c77f8e8d54f5f74d6db6. > >Now all SHUTDOWN_CLOSE paths are async safe, we no >longer need this. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/modules/vfs_default.c | 20 -------------------- > 1 file changed, 20 deletions(-) > >diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c >index 21bc9c7adf7..b8c36180b7c 100644 >--- a/source3/modules/vfs_default.c >+++ b/source3/modules/vfs_default.c >@@ -863,15 +863,6 @@ static void vfs_pread_do(void *private_data) > > static int vfs_pread_state_destructor(struct vfswrap_pread_state *state) > { >- /* >- * This destructor only gets called if the request is still >- * in flight, which is why we deny it by returning -1. We >- * also set the req pointer to NULL so the _done function >- * can detect the caller doesn't want the result anymore. >- * >- * Forcing the fsp closed by a SHUTDOWN_CLOSE can cause this. >- */ >- state->req = NULL; > return -1; > } > >@@ -886,17 +877,6 @@ static void vfs_pread_done(struct tevent_req *subreq) > TALLOC_FREE(subreq); > SMBPROFILE_BYTES_ASYNC_END(state->profile_bytes); > talloc_set_destructor(state, NULL); >- if (req == NULL) { >- /* >- * We were shutdown closed in flight. No one >- * wants the result, and state has been reparented >- * to the NULL context, so just free it so we >- * don't leak memory. >- */ >- DBG_NOTICE("pread request abandoned in flight\n"); >- TALLOC_FREE(state); >- return; >- } > if (ret != 0) { > if (ret != EAGAIN) { > tevent_req_error(req, ret); >-- >2.20.1 > > >From f56562e2c2141dc8522460b56bbb5013bd9ddde0 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 12 Mar 2020 17:20:50 -0700 >Subject: [PATCH 37/37] Revert "s3: VFS: vfs_default. Pass in struct > vfswrap_pread_state as the callback data to the subreq." > >This reverts commit e102908f112866d657b8c0cd6a5b217d070210c8. > >Now all SHUTDOWN_CLOSE paths are async safe, we no >longer need this. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/modules/vfs_default.c | 9 +++++---- > 1 file changed, 5 insertions(+), 4 deletions(-) > >diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c >index b8c36180b7c..4bb4adf5f7e 100644 >--- a/source3/modules/vfs_default.c >+++ b/source3/modules/vfs_default.c >@@ -827,7 +827,7 @@ static struct tevent_req *vfswrap_pread_send(struct vfs_handle_struct *handle, > if (tevent_req_nomem(subreq, req)) { > return tevent_req_post(req, ev); > } >- tevent_req_set_callback(subreq, vfs_pread_done, state); >+ tevent_req_set_callback(subreq, vfs_pread_done, req); > > talloc_set_destructor(state, vfs_pread_state_destructor); > >@@ -868,9 +868,10 @@ static int vfs_pread_state_destructor(struct vfswrap_pread_state *state) > > static void vfs_pread_done(struct tevent_req *subreq) > { >- struct vfswrap_pread_state *state = tevent_req_callback_data( >- subreq, struct vfswrap_pread_state); >- struct tevent_req *req = state->req; >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ struct vfswrap_pread_state *state = tevent_req_data( >+ req, struct vfswrap_pread_state); > int ret; > > ret = pthreadpool_tevent_job_recv(subreq); >-- >2.20.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 14301
:
15825
|
15837
|
15844
|
15847
|
15854
|
15858
|
15861
|
15867
|
15870
|
16043
|
16044
|
16054
|
16055
|
16064
|
16065
|
16069
|
16091