diff options
-rw-r--r-- | src/backend/storage/aio/aio.c | 2 | ||||
-rw-r--r-- | src/backend/storage/aio/aio_callback.c | 1 | ||||
-rw-r--r-- | src/include/storage/aio.h | 6 | ||||
-rw-r--r-- | src/include/storage/aio_types.h | 26 |
4 files changed, 29 insertions, 6 deletions
diff --git a/src/backend/storage/aio/aio.c b/src/backend/storage/aio/aio.c index 91e76113412..e3ed087e8a2 100644 --- a/src/backend/storage/aio/aio.c +++ b/src/backend/storage/aio/aio.c @@ -839,6 +839,8 @@ pgaio_result_status_string(PgAioResultStatus rs) return "UNKNOWN"; case PGAIO_RS_OK: return "OK"; + case PGAIO_RS_WARNING: + return "WARNING"; case PGAIO_RS_PARTIAL: return "PARTIAL"; case PGAIO_RS_ERROR: diff --git a/src/backend/storage/aio/aio_callback.c b/src/backend/storage/aio/aio_callback.c index 53db6e194af..b00b6bc1025 100644 --- a/src/backend/storage/aio/aio_callback.c +++ b/src/backend/storage/aio/aio_callback.c @@ -83,6 +83,7 @@ pgaio_io_register_callbacks(PgAioHandle *ioh, PgAioHandleCallbackID cb_id, { const PgAioHandleCallbacksEntry *ce = &aio_handle_cbs[cb_id]; + Assert(cb_id <= PGAIO_HCB_MAX); if (cb_id >= lengthof(aio_handle_cbs)) elog(ERROR, "callback %d is out of range", cb_id); if (aio_handle_cbs[cb_id].cb->complete_shared == NULL && diff --git a/src/include/storage/aio.h b/src/include/storage/aio.h index c6bf7c4ccf5..4ab4b05145a 100644 --- a/src/include/storage/aio.h +++ b/src/include/storage/aio.h @@ -191,11 +191,15 @@ struct PgAioTargetInfo */ typedef enum PgAioHandleCallbackID { - PGAIO_HCB_INVALID, + PGAIO_HCB_INVALID = 0, PGAIO_HCB_MD_READV, } PgAioHandleCallbackID; +#define PGAIO_HCB_MAX PGAIO_HCB_MD_READV +StaticAssertDecl(PGAIO_HCB_MAX <= (1 << PGAIO_RESULT_ID_BITS), + "PGAIO_HCB_MAX is too big for PGAIO_RESULT_ID_BITS"); + typedef void (*PgAioHandleCallbackStage) (PgAioHandle *ioh, uint8 cb_flags); typedef PgAioResult (*PgAioHandleCallbackComplete) (PgAioHandle *ioh, PgAioResult prior_result, uint8 cb_flags); diff --git a/src/include/storage/aio_types.h b/src/include/storage/aio_types.h index debe8163d4e..18183366077 100644 --- a/src/include/storage/aio_types.h +++ b/src/include/storage/aio_types.h @@ -79,32 +79,48 @@ typedef enum PgAioResultStatus { PGAIO_RS_UNKNOWN, /* not yet completed / uninitialized */ PGAIO_RS_OK, - PGAIO_RS_PARTIAL, /* did not fully succeed, but no error */ - PGAIO_RS_ERROR, + PGAIO_RS_PARTIAL, /* did not fully succeed, no warning/error */ + PGAIO_RS_WARNING, /* [partially] succeeded, with a warning */ + PGAIO_RS_ERROR, /* failed entirely */ } PgAioResultStatus; /* * Result of IO operation, visible only to the initiator of IO. + * + * We need to be careful about the size of PgAioResult, as it is embedded in + * every PgAioHandle, as well as every PgAioReturn. Currently we assume we can + * fit it into one 8 byte value, restricting the space for per-callback error + * data to PGAIO_RESULT_ERROR_BITS. */ +#define PGAIO_RESULT_ID_BITS 6 +#define PGAIO_RESULT_STATUS_BITS 3 +#define PGAIO_RESULT_ERROR_BITS 23 typedef struct PgAioResult { /* * This is of type PgAioHandleCallbackID, but can't use a bitfield of an * enum, because some compilers treat enums as signed. */ - uint32 id:8; + uint32 id:PGAIO_RESULT_ID_BITS; /* of type PgAioResultStatus, see above */ - uint32 status:2; + uint32 status:PGAIO_RESULT_STATUS_BITS; /* meaning defined by callback->error */ - uint32 error_data:22; + uint32 error_data:PGAIO_RESULT_ERROR_BITS; int32 result; } PgAioResult; +StaticAssertDecl(PGAIO_RESULT_ID_BITS + + PGAIO_RESULT_STATUS_BITS + + PGAIO_RESULT_ERROR_BITS == 32, + "PgAioResult bits divided up incorrectly"); +StaticAssertDecl(sizeof(PgAioResult) == 8, + "PgAioResult has unexpected size"); + /* * Combination of PgAioResult with minimal metadata about the IO. * |