Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * aio_target.c
4 : * AIO - Functionality related to executing IO for different targets
5 : *
6 : * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7 : * Portions Copyright (c) 1994, Regents of the University of California
8 : *
9 : * IDENTIFICATION
10 : * src/backend/storage/aio/aio_target.c
11 : *
12 : *-------------------------------------------------------------------------
13 : */
14 :
15 : #include "postgres.h"
16 :
17 : #include "storage/aio.h"
18 : #include "storage/aio_internal.h"
19 : #include "storage/smgr.h"
20 :
21 :
22 : /*
23 : * Registry for entities that can be the target of AIO.
24 : */
25 : static const PgAioTargetInfo *pgaio_target_info[] = {
26 : [PGAIO_TID_INVALID] = &(PgAioTargetInfo) {
27 : .name = "invalid",
28 : },
29 : [PGAIO_TID_SMGR] = &aio_smgr_target_info,
30 : };
31 :
32 :
33 :
34 : /* --------------------------------------------------------------------------------
35 : * Public target related functions operating on IO Handles
36 : * --------------------------------------------------------------------------------
37 : */
38 :
39 : bool
40 0 : pgaio_io_has_target(PgAioHandle *ioh)
41 : {
42 0 : return ioh->target != PGAIO_TID_INVALID;
43 : }
44 :
45 : /*
46 : * Return the name for the target associated with the IO. Mostly useful for
47 : * debugging/logging.
48 : */
49 : const char *
50 7238 : pgaio_io_get_target_name(PgAioHandle *ioh)
51 : {
52 : /* explicitly allow INVALID here, function used by debug messages */
53 : Assert(ioh->target >= PGAIO_TID_INVALID && ioh->target < PGAIO_TID_COUNT);
54 :
55 7238 : return pgaio_target_info[ioh->target]->name;
56 : }
57 :
58 : /*
59 : * Assign a target to the IO.
60 : *
61 : * This has to be called exactly once before pgaio_io_start_*() is called.
62 : */
63 : void
64 1316121 : pgaio_io_set_target(PgAioHandle *ioh, PgAioTargetID targetid)
65 : {
66 : Assert(ioh->state == PGAIO_HS_HANDED_OUT);
67 : Assert(ioh->target == PGAIO_TID_INVALID);
68 :
69 1316121 : ioh->target = targetid;
70 1316121 : }
71 :
72 : PgAioTargetData *
73 4217338 : pgaio_io_get_target_data(PgAioHandle *ioh)
74 : {
75 4217338 : return &ioh->target_data;
76 : }
77 :
78 : /*
79 : * Return a stringified description of the IO's target.
80 : *
81 : * The string is localized and allocated in the current memory context.
82 : */
83 : char *
84 0 : pgaio_io_get_target_description(PgAioHandle *ioh)
85 : {
86 : /* disallow INVALID, there wouldn't be a description */
87 : Assert(ioh->target > PGAIO_TID_INVALID && ioh->target < PGAIO_TID_COUNT);
88 :
89 0 : return pgaio_target_info[ioh->target]->describe_identity(&ioh->target_data);
90 : }
91 :
92 :
93 :
94 : /* --------------------------------------------------------------------------------
95 : * Internal target related functions operating on IO Handles
96 : * --------------------------------------------------------------------------------
97 : */
98 :
99 : /*
100 : * Internal: Check if pgaio_io_reopen() is available for the IO.
101 : */
102 : bool
103 586942 : pgaio_io_can_reopen(PgAioHandle *ioh)
104 : {
105 : Assert(ioh->target > PGAIO_TID_INVALID && ioh->target < PGAIO_TID_COUNT);
106 :
107 586942 : return pgaio_target_info[ioh->target]->reopen != NULL;
108 : }
109 :
110 : /*
111 : * Internal: Before executing an IO outside of the context of the process the
112 : * IO has been staged in, the file descriptor has to be reopened - any FD
113 : * referenced in the IO itself, won't be valid in the separate process.
114 : */
115 : void
116 480945 : pgaio_io_reopen(PgAioHandle *ioh)
117 : {
118 : Assert(ioh->target > PGAIO_TID_INVALID && ioh->target < PGAIO_TID_COUNT);
119 : Assert(ioh->op > PGAIO_OP_INVALID && ioh->op < PGAIO_OP_COUNT);
120 :
121 480945 : pgaio_target_info[ioh->target]->reopen(ioh);
122 480945 : }
|