summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2020-03-02 13:11:06 -0800
committerKarolin Seeger <kseeger@samba.org>2020-04-07 08:12:36 +0000
commita108dece4fb11c36af321f5673097e76433c28ad (patch)
treec548df2b9c635a15277d33adbc81c94ba6b4b38f
parent680157b533808b3a09f31e703805c830e6d63349 (diff)
downloadsamba-a108dece4fb11c36af321f5673097e76433c28ad.tar.gz
smbd: enforce AIO requests draining
Assert we have no aio on a close. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301 Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org> Combined squash of commits: (cherry picked from commit 410e7599bd2ae9b35429f60a529bb7c4aa88df25) (cherry picked from commit acb0b01761330864a23932f643f7ad4e3d374634) (cherry picked from commit f94cd10a211e2eae966ba4bd26921556bbe513fc) (cherry picked from commit 0ae4f368c6c8d2c8c7aa34069007a984055df0da) (cherry picked from commit 86dd5a080969e14ab0d131d8cb1054ec624a41ba)
-rw-r--r--source3/smbd/close.c80
1 files changed, 17 insertions, 63 deletions
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index f45371e656c..d5af62a277c 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -31,6 +31,7 @@
#include "auth.h"
#include "messages.h"
#include "../librpc/gen_ndr/open_files.h"
+#include "lib/util/tevent_ntstatus.h"
/****************************************************************************
Run a file if it is a magic script.
@@ -635,6 +636,20 @@ static NTSTATUS ntstatus_keeperror(NTSTATUS s1, NTSTATUS s2)
return s2;
}
+static void assert_no_pending_aio(struct files_struct *fsp,
+ enum file_close_type close_type)
+{
+ unsigned num_requests = fsp->num_aio_requests;
+
+ if (num_requests == 0) {
+ return;
+ }
+
+ DBG_ERR("fsp->num_aio_requests=%u\n", num_requests);
+ smb_panic("can not close with outstanding aio requests");
+ return;
+}
+
/****************************************************************************
Close a file.
@@ -651,45 +666,7 @@ static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
connection_struct *conn = fsp->conn;
bool is_durable = false;
- if (fsp->num_aio_requests != 0) {
-
- if (close_type != SHUTDOWN_CLOSE) {
- /*
- * reply_close and the smb2 close must have
- * taken care of this. No other callers of
- * close_file should ever have created async
- * I/O.
- *
- * We need to panic here because if we close()
- * the fd while we have outstanding async I/O
- * requests, in the worst case we could end up
- * writing to the wrong file.
- */
- DEBUG(0, ("fsp->num_aio_requests=%u\n",
- fsp->num_aio_requests));
- smb_panic("can not close with outstanding aio "
- "requests");
- }
-
- /*
- * For shutdown close, just drop the async requests
- * including a potential close request pending for
- * this fsp. Drop the close request first, the
- * destructor for the aio_requests would execute it.
- */
- TALLOC_FREE(fsp->deferred_close);
-
- while (fsp->num_aio_requests != 0) {
- /*
- * The destructor of the req will remove
- * itself from the fsp.
- * Don't use TALLOC_FREE here, this will overwrite
- * what the destructor just wrote into
- * aio_requests[0].
- */
- talloc_free(fsp->aio_requests[0]);
- }
- }
+ assert_no_pending_aio(fsp, close_type);
while (talloc_array_length(fsp->blocked_smb1_lock_reqs) != 0) {
smbd_smb1_brl_finish_by_req(
@@ -1134,30 +1111,7 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
notify_status = NT_STATUS_OK;
}
- if (fsp->num_aio_requests != 0) {
- if (close_type != SHUTDOWN_CLOSE) {
- /*
- * We panic here because if we close() the fd while we
- * have outstanding async I/O requests, an async IO
- * request might use the fd. For directories the fd is
- * read-only, so this is not as bad as with files, but
- * still, better safe then sorry.
- */
- DBG_ERR("fsp->num_aio_requests=%u\n",
- fsp->num_aio_requests);
- smb_panic("close with outstanding aio requests");
- return NT_STATUS_INTERNAL_ERROR;
- }
-
- while (fsp->num_aio_requests != 0) {
- /*
- * The destructor of the req will remove itself from the
- * fsp. Don't use TALLOC_FREE here, this will overwrite
- * what the destructor just wrote into aio_requests[0].
- */
- talloc_free(fsp->aio_requests[0]);
- }
- }
+ assert_no_pending_aio(fsp, close_type);
/*
* NT can set delete_on_close of the last open