1
0
mirror of https://github.com/postgres/postgres.git synced 2025-04-27 22:56:53 +03:00

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
This commit is contained in:
Andres Freund 2025-03-26 16:06:54 -04:00
parent 47a1f076a7
commit 96da9050a5
2 changed files with 15 additions and 0 deletions

View File

@ -159,6 +159,12 @@ pgaio_io_before_prep(PgAioHandle *ioh)
Assert(pgaio_my_backend->handed_out_io == ioh); Assert(pgaio_my_backend->handed_out_io == ioh);
Assert(pgaio_io_has_target(ioh)); Assert(pgaio_io_has_target(ioh));
Assert(ioh->op == PGAIO_OP_INVALID); 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());
} }
/* /*

View File

@ -476,6 +476,13 @@ IoWorkerMain(const void *startup_data, size_t startup_data_len)
"worker %d processing IO", "worker %d processing IO",
MyIoWorkerId); 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 * It's very unlikely, but possible, that reopen fails. E.g. due
* to memory allocations failing or file permissions changing or * to memory allocations failing or file permissions changing or
@ -502,6 +509,8 @@ IoWorkerMain(const void *startup_data, size_t startup_data_len)
* ensure we don't accidentally fail. * ensure we don't accidentally fail.
*/ */
pgaio_io_perform_synchronously(ioh); pgaio_io_perform_synchronously(ioh);
RESUME_INTERRUPTS();
} }
else else
{ {