aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndres Freund <andres@anarazel.de>2025-03-26 16:06:54 -0400
committerAndres Freund <andres@anarazel.de>2025-03-26 16:06:54 -0400
commit96da9050a57aece4a48ab34a84bc3b3412708a20 (patch)
treedb94f67398834e9f1d1dd2fb4038b31c8643d635
parent47a1f076a7c9789134a29dc738db0152e5f71b4c (diff)
downloadpostgresql-96da9050a57aece4a48ab34a84bc3b3412708a20.tar.gz
postgresql-96da9050a57aece4a48ab34a84bc3b3412708a20.zip
aio: Be more paranoid about interrupts
As reported by Noah, it's possible, although practically very unlikely, that interrupts could be processed in between pgaio_io_reopen() and pgaio_io_perform_synchronously(). Prevent that by explicitly holding interrupts. It also seems good to add an assertion to pgaio_io_before_prep() to ensure that interrupts are held, as otherwise FDs referenced by the IO could be closed during interrupt processing. All code in the aio series currently runs the code with interrupts held, but it seems better to be paranoid. Reviewed-by: Noah Misch <noah@leadboat.com> Reported-by: Noah Misch <noah@leadboat.com> Discussion: https://postgr.es/m/20250324002939.5c.nmisch@google.com
-rw-r--r--src/backend/storage/aio/aio_io.c6
-rw-r--r--src/backend/storage/aio/method_worker.c9
2 files changed, 15 insertions, 0 deletions
diff --git a/src/backend/storage/aio/aio_io.c b/src/backend/storage/aio/aio_io.c
index 36d2c1f492d..cc6d999a6fb 100644
--- a/src/backend/storage/aio/aio_io.c
+++ b/src/backend/storage/aio/aio_io.c
@@ -159,6 +159,12 @@ pgaio_io_before_prep(PgAioHandle *ioh)
Assert(pgaio_my_backend->handed_out_io == ioh);
Assert(pgaio_io_has_target(ioh));
Assert(ioh->op == PGAIO_OP_INVALID);
+
+ /*
+ * Otherwise the FDs referenced by the IO could be closed due to interrupt
+ * processing.
+ */
+ Assert(!INTERRUPTS_CAN_BE_PROCESSED());
}
/*
diff --git a/src/backend/storage/aio/method_worker.c b/src/backend/storage/aio/method_worker.c
index 2be6bb8972b..4a7853d13fa 100644
--- a/src/backend/storage/aio/method_worker.c
+++ b/src/backend/storage/aio/method_worker.c
@@ -477,6 +477,13 @@ IoWorkerMain(const void *startup_data, size_t startup_data_len)
MyIoWorkerId);
/*
+ * Prevent interrupts between pgaio_io_reopen() and
+ * pgaio_io_perform_synchronously() that otherwise could lead to
+ * the FD getting closed in that window.
+ */
+ HOLD_INTERRUPTS();
+
+ /*
* It's very unlikely, but possible, that reopen fails. E.g. due
* to memory allocations failing or file permissions changing or
* such. In that case we need to fail the IO.
@@ -502,6 +509,8 @@ IoWorkerMain(const void *startup_data, size_t startup_data_len)
* ensure we don't accidentally fail.
*/
pgaio_io_perform_synchronously(ioh);
+
+ RESUME_INTERRUPTS();
}
else
{