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-2025, 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 14310 : 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 14310 : 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 2482158 : 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 2482158 : ioh->target = targetid; 70 2482158 : } 71 : 72 : PgAioTargetData * 73 7966004 : pgaio_io_get_target_data(PgAioHandle *ioh) 74 : { 75 7966004 : 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 1149896 : pgaio_io_can_reopen(PgAioHandle *ioh) 104 : { 105 : Assert(ioh->target > PGAIO_TID_INVALID && ioh->target < PGAIO_TID_COUNT); 106 : 107 1149896 : 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 939758 : 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 939758 : pgaio_target_info[ioh->target]->reopen(ioh); 122 939758 : }