Skip to content

Commit ef64fe2

Browse files
committed
aio: Add WARNING result status
If an IO succeeds, but issues a warning, e.g. due to a page verification failure with zero_damaged_pages, we want to issue that warning in the context of the issuer of the IO, not the process that executes the completion (always the case for worker). It's already possible for a completion callback to report a custom error message, we just didn't have a result status that allowed a user of AIO to know that a warning should be emitted even though the IO request succeeded. All that's needed for that is a dedicated PGAIO_RS_ value. Previously there were not enough bits in PgAioResult.id for the new value. Increase. While at that, add defines for the amount of bits and static asserts to check that the widths are appropriate. Reviewed-by: Noah Misch <noah@leadboat.com> Discussion: https://postgr.es/m/20250329212929.a6.nmisch@google.com
1 parent d445990 commit ef64fe2

File tree

4 files changed

+29
-6
lines changed

4 files changed

+29
-6
lines changed

src/backend/storage/aio/aio.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,8 @@ pgaio_result_status_string(PgAioResultStatus rs)
839839
return "UNKNOWN";
840840
case PGAIO_RS_OK:
841841
return "OK";
842+
case PGAIO_RS_WARNING:
843+
return "WARNING";
842844
case PGAIO_RS_PARTIAL:
843845
return "PARTIAL";
844846
case PGAIO_RS_ERROR:

src/backend/storage/aio/aio_callback.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ pgaio_io_register_callbacks(PgAioHandle *ioh, PgAioHandleCallbackID cb_id,
8383
{
8484
const PgAioHandleCallbacksEntry *ce = &aio_handle_cbs[cb_id];
8585

86+
Assert(cb_id <= PGAIO_HCB_MAX);
8687
if (cb_id >= lengthof(aio_handle_cbs))
8788
elog(ERROR, "callback %d is out of range", cb_id);
8889
if (aio_handle_cbs[cb_id].cb->complete_shared == NULL &&

src/include/storage/aio.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,11 +191,15 @@ struct PgAioTargetInfo
191191
*/
192192
typedef enum PgAioHandleCallbackID
193193
{
194-
PGAIO_HCB_INVALID,
194+
PGAIO_HCB_INVALID = 0,
195195

196196
PGAIO_HCB_MD_READV,
197197
} PgAioHandleCallbackID;
198198

199+
#define PGAIO_HCB_MAX PGAIO_HCB_MD_READV
200+
StaticAssertDecl(PGAIO_HCB_MAX <= (1 << PGAIO_RESULT_ID_BITS),
201+
"PGAIO_HCB_MAX is too big for PGAIO_RESULT_ID_BITS");
202+
199203

200204
typedef void (*PgAioHandleCallbackStage) (PgAioHandle *ioh, uint8 cb_flags);
201205
typedef PgAioResult (*PgAioHandleCallbackComplete) (PgAioHandle *ioh, PgAioResult prior_result, uint8 cb_flags);

src/include/storage/aio_types.h

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,32 +79,48 @@ typedef enum PgAioResultStatus
7979
{
8080
PGAIO_RS_UNKNOWN, /* not yet completed / uninitialized */
8181
PGAIO_RS_OK,
82-
PGAIO_RS_PARTIAL, /* did not fully succeed, but no error */
83-
PGAIO_RS_ERROR,
82+
PGAIO_RS_PARTIAL, /* did not fully succeed, no warning/error */
83+
PGAIO_RS_WARNING, /* [partially] succeeded, with a warning */
84+
PGAIO_RS_ERROR, /* failed entirely */
8485
} PgAioResultStatus;
8586

8687

8788
/*
8889
* Result of IO operation, visible only to the initiator of IO.
90+
*
91+
* We need to be careful about the size of PgAioResult, as it is embedded in
92+
* every PgAioHandle, as well as every PgAioReturn. Currently we assume we can
93+
* fit it into one 8 byte value, restricting the space for per-callback error
94+
* data to PGAIO_RESULT_ERROR_BITS.
8995
*/
96+
#define PGAIO_RESULT_ID_BITS 6
97+
#define PGAIO_RESULT_STATUS_BITS 3
98+
#define PGAIO_RESULT_ERROR_BITS 23
9099
typedef struct PgAioResult
91100
{
92101
/*
93102
* This is of type PgAioHandleCallbackID, but can't use a bitfield of an
94103
* enum, because some compilers treat enums as signed.
95104
*/
96-
uint32 id:8;
105+
uint32 id:PGAIO_RESULT_ID_BITS;
97106

98107
/* of type PgAioResultStatus, see above */
99-
uint32 status:2;
108+
uint32 status:PGAIO_RESULT_STATUS_BITS;
100109

101110
/* meaning defined by callback->error */
102-
uint32 error_data:22;
111+
uint32 error_data:PGAIO_RESULT_ERROR_BITS;
103112

104113
int32 result;
105114
} PgAioResult;
106115

107116

117+
StaticAssertDecl(PGAIO_RESULT_ID_BITS +
118+
PGAIO_RESULT_STATUS_BITS +
119+
PGAIO_RESULT_ERROR_BITS == 32,
120+
"PgAioResult bits divided up incorrectly");
121+
StaticAssertDecl(sizeof(PgAioResult) == 8,
122+
"PgAioResult has unexpected size");
123+
108124
/*
109125
* Combination of PgAioResult with minimal metadata about the IO.
110126
*

0 commit comments

Comments
 (0)