diff options
author | Andres Freund <andres@anarazel.de> | 2025-03-26 16:06:54 -0400 |
---|---|---|
committer | Andres Freund <andres@anarazel.de> | 2025-03-26 16:06:54 -0400 |
commit | 96da9050a57aece4a48ab34a84bc3b3412708a20 (patch) | |
tree | db94f67398834e9f1d1dd2fb4038b31c8643d635 | |
parent | 47a1f076a7c9789134a29dc738db0152e5f71b4c (diff) | |
download | postgresql-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.c | 6 | ||||
-rw-r--r-- | src/backend/storage/aio/method_worker.c | 9 |
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 { |