1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
/*-------------------------------------------------------------------------
*
* aio_types.h
* AIO related types that are useful to include separately, to reduce the
* "include burden".
*
*
* Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/storage/aio_types.h
*
*-------------------------------------------------------------------------
*/
#ifndef AIO_TYPES_H
#define AIO_TYPES_H
#include "storage/block.h"
#include "storage/relfilelocator.h"
typedef struct PgAioHandle PgAioHandle;
typedef struct PgAioHandleCallbacks PgAioHandleCallbacks;
typedef struct PgAioTargetInfo PgAioTargetInfo;
/*
* A reference to an IO that can be used to wait for the IO (using
* pgaio_wref_wait()) to complete.
*
* These can be passed across process boundaries.
*/
typedef struct PgAioWaitRef
{
/* internal ID identifying the specific PgAioHandle */
uint32 aio_index;
/*
* IO handles are reused. To detect if a handle was reused, and thereby
* avoid unnecessarily waiting for a newer IO, each time the handle is
* reused a generation number is increased.
*
* To avoid requiring alignment sufficient for an int64, split the
* generation into two.
*/
uint32 generation_upper;
uint32 generation_lower;
} PgAioWaitRef;
/*
* Information identifying what the IO is being performed on.
*
* This needs sufficient information to
*
* a) Reopen the file for the IO if the IO is executed in a context that
* cannot use the FD provided initially (e.g. because the IO is executed in
* a worker process).
*
* b) Describe the object the IO is performed on in log / error messages.
*/
typedef union PgAioTargetData
{
struct
{
RelFileLocator rlocator; /* physical relation identifier */
BlockNumber blockNum; /* blknum relative to begin of reln */
BlockNumber nblocks;
ForkNumber forkNum:8; /* don't waste 4 byte for four values */
bool is_temp:1; /* proc can be inferred by owning AIO */
bool skip_fsync:1;
} smgr;
} PgAioTargetData;
/*
* The status of an AIO operation.
*/
typedef enum PgAioResultStatus
{
PGAIO_RS_UNKNOWN, /* not yet completed / uninitialized */
PGAIO_RS_OK,
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:PGAIO_RESULT_ID_BITS;
/* of type PgAioResultStatus, see above */
uint32 status:PGAIO_RESULT_STATUS_BITS;
/* meaning defined by callback->error */
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.
*
* Contains sufficient information to be able, in case the IO [partially]
* fails, to log/raise an error under control of the IO issuing code.
*/
typedef struct PgAioReturn
{
PgAioResult result;
PgAioTargetData target_data;
} PgAioReturn;
#endif /* AIO_TYPES_H */
|