PostgreSQL Source Code git master
Loading...
Searching...
No Matches
test_aio.c File Reference
#include "postgres.h"
#include "access/relation.h"
#include "catalog/pg_type.h"
#include "fmgr.h"
#include "funcapi.h"
#include "storage/aio.h"
#include "storage/aio_internal.h"
#include "storage/buf_internals.h"
#include "storage/bufmgr.h"
#include "storage/checksum.h"
#include "storage/condition_variable.h"
#include "storage/lwlock.h"
#include "storage/proc.h"
#include "storage/procnumber.h"
#include "storage/read_stream.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/injection_point.h"
#include "utils/rel.h"
#include "utils/tuplestore.h"
#include "utils/wait_event.h"
Include dependency graph for test_aio.c:

Go to the source code of this file.

Data Structures

struct  InjIoErrorState
 
struct  BlocksReadStreamData
 

Macros

#define MAX_BUFFERS_TO_EXTEND_BY   64
 

Typedefs

typedef struct InjIoErrorState InjIoErrorState
 
typedef struct BlocksReadStreamData BlocksReadStreamData
 

Functions

static void test_aio_shmem_request (void *arg)
 
static void test_aio_shmem_init (void *arg)
 
static void test_aio_shmem_attach (void *arg)
 
void _PG_init (void)
 
 PG_FUNCTION_INFO_V1 (errno_from_string)
 
Datum errno_from_string (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (grow_rel)
 
Datum grow_rel (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (modify_rel_block)
 
Datum modify_rel_block (PG_FUNCTION_ARGS)
 
static Buffer create_toy_buffer (Relation rel, BlockNumber blkno)
 
 PG_FUNCTION_INFO_V1 (read_rel_block_ll)
 
Datum read_rel_block_ll (PG_FUNCTION_ARGS)
 
static void invalidate_one_block (Relation rel, ForkNumber forknum, BlockNumber blkno)
 
 PG_FUNCTION_INFO_V1 (invalidate_rel_block)
 
Datum invalidate_rel_block (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (evict_rel)
 
Datum evict_rel (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (buffer_create_toy)
 
Datum buffer_create_toy (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (buffer_call_start_io)
 
Datum buffer_call_start_io (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (buffer_call_terminate_io)
 
Datum buffer_call_terminate_io (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (read_buffers)
 
Datum read_buffers (PG_FUNCTION_ARGS)
 
static BlockNumber read_stream_for_blocks_cb (ReadStream *stream, void *callback_private_data, void *per_buffer_data)
 
 PG_FUNCTION_INFO_V1 (read_stream_for_blocks)
 
Datum read_stream_for_blocks (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (handle_get)
 
Datum handle_get (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (handle_release_last)
 
Datum handle_release_last (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (handle_get_and_error)
 
Datum handle_get_and_error (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (handle_get_twice)
 
Datum handle_get_twice (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (handle_get_release)
 
Datum handle_get_release (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (batch_start)
 
Datum batch_start (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (batch_end)
 
Datum batch_end (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (inj_io_completion_wait)
 
Datum inj_io_completion_wait (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (inj_io_completion_continue)
 
Datum inj_io_completion_continue (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (inj_io_short_read_attach)
 
Datum inj_io_short_read_attach (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (inj_io_short_read_detach)
 
Datum inj_io_short_read_detach (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (inj_io_reopen_attach)
 
Datum inj_io_reopen_attach (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (inj_io_reopen_detach)
 
Datum inj_io_reopen_detach (PG_FUNCTION_ARGS)
 

Variables

 PG_MODULE_MAGIC
 
static InjIoErrorStateinj_io_error_state
 
static const ShmemCallbacks inj_io_shmem_callbacks
 
static PgAioHandlelast_handle
 

Macro Definition Documentation

◆ MAX_BUFFERS_TO_EXTEND_BY

#define MAX_BUFFERS_TO_EXTEND_BY   64

Typedef Documentation

◆ BlocksReadStreamData

◆ InjIoErrorState

Function Documentation

◆ _PG_init()

void _PG_init ( void  )

Definition at line 145 of file test_aio.c.

146{
148 return;
149
151}
bool process_shared_preload_libraries_in_progress
Definition miscinit.c:1788
void RegisterShmemCallbacks(const ShmemCallbacks *callbacks)
Definition shmem.c:874
static const ShmemCallbacks inj_io_shmem_callbacks
Definition test_aio.c:81

References inj_io_shmem_callbacks, process_shared_preload_libraries_in_progress, and RegisterShmemCallbacks().

◆ batch_end()

Datum batch_end ( PG_FUNCTION_ARGS  )

Definition at line 982 of file test_aio.c.

983{
986}
void pgaio_exit_batchmode(void)
Definition aio.c:1102
#define PG_RETURN_VOID()
Definition fmgr.h:350

References PG_RETURN_VOID, and pgaio_exit_batchmode().

◆ batch_start()

Datum batch_start ( PG_FUNCTION_ARGS  )

Definition at line 974 of file test_aio.c.

975{
978}
void pgaio_enter_batchmode(void)
Definition aio.c:1091

References PG_RETURN_VOID, and pgaio_enter_batchmode().

Referenced by log_newpages().

◆ buffer_call_start_io()

Datum buffer_call_start_io ( PG_FUNCTION_ARGS  )

Definition at line 610 of file test_aio.c.

611{
613 bool for_input = PG_GETARG_BOOL(1);
614 bool wait = PG_GETARG_BOOL(2);
616 bool can_start;
617
618 if (BufferIsLocal(buf))
620 for_input, wait, NULL);
621 else
623 for_input, wait, NULL);
624
626
627 /*
628 * For tests we don't want the resowner release preventing us from
629 * orchestrating odd scenarios.
630 */
631 if (can_start && !BufferIsLocal(buf))
633 buf);
634
635 ereport(LOG,
636 errmsg("buffer %d after StartBufferIO: %s",
638 errhidestmt(true), errhidecontext(true));
639
641}
int Buffer
Definition buf.h:23
#define BufferIsLocal(buffer)
Definition buf.h:37
StartBufferIOResult
@ BUFFER_IO_READY_FOR_IO
static void ResourceOwnerForgetBufferIO(ResourceOwner owner, Buffer buffer)
static BufferDesc * GetLocalBufferDescriptor(uint32 id)
static BufferDesc * GetBufferDescriptor(uint32 id)
char * DebugPrintBufferRefcount(Buffer buffer)
Definition bufmgr.c:4389
StartBufferIOResult StartSharedBufferIO(BufferDesc *buf, bool forInput, bool wait, PgAioWaitRef *io_wref)
Definition bufmgr.c:7241
uint32 result
int int errhidestmt(bool hide_stmt)
#define LOG
Definition elog.h:32
int errhidecontext(bool hide_ctx)
#define ereport(elevel,...)
Definition elog.h:152
#define PG_GETARG_INT32(n)
Definition fmgr.h:269
#define PG_GETARG_BOOL(n)
Definition fmgr.h:274
#define PG_RETURN_BOOL(x)
Definition fmgr.h:360
StartBufferIOResult StartLocalBufferIO(BufferDesc *bufHdr, bool forInput, bool wait, PgAioWaitRef *io_wref)
Definition localbuf.c:524
static char * errmsg
static char buf[DEFAULT_XLOG_SEG_SIZE]
static int fb(int x)
ResourceOwner CurrentResourceOwner
Definition resowner.c:173

References buf, BUFFER_IO_READY_FOR_IO, BufferIsLocal, CurrentResourceOwner, DebugPrintBufferRefcount(), ereport, errhidecontext(), errhidestmt(), errmsg, fb(), GetBufferDescriptor(), GetLocalBufferDescriptor(), LOG, PG_GETARG_BOOL, PG_GETARG_INT32, PG_RETURN_BOOL, ResourceOwnerForgetBufferIO(), result, StartLocalBufferIO(), and StartSharedBufferIO().

◆ buffer_call_terminate_io()

Datum buffer_call_terminate_io ( PG_FUNCTION_ARGS  )

Definition at line 645 of file test_aio.c.

646{
648 bool for_input = PG_GETARG_BOOL(1);
649 bool succeed = PG_GETARG_BOOL(2);
650 bool io_error = PG_GETARG_BOOL(3);
651 bool release_aio = PG_GETARG_BOOL(4);
652 bool clear_dirty = false;
654
655 if (io_error)
657
658 if (for_input)
659 {
660 clear_dirty = false;
661
662 if (succeed)
664 }
665 else
666 {
667 if (succeed)
668 clear_dirty = true;
669 }
670
671 ereport(LOG,
672 errmsg("buffer %d before Terminate[Local]BufferIO: %s",
674 errhidestmt(true), errhidecontext(true));
675
676 if (BufferIsLocal(buf))
679 else
682
683 ereport(LOG,
684 errmsg("buffer %d after Terminate[Local]BufferIO: %s",
686 errhidestmt(true), errhidecontext(true));
687
689}
#define BM_VALID
#define BM_IO_ERROR
void TerminateBufferIO(BufferDesc *buf, bool clear_dirty, uint64 set_flag_bits, bool forget_owner, bool release_aio)
Definition bufmgr.c:7358
uint64_t uint64
Definition c.h:625
void TerminateLocalBufferIO(BufferDesc *bufHdr, bool clear_dirty, uint64 set_flag_bits, bool release_aio)
Definition localbuf.c:578

References BM_IO_ERROR, BM_VALID, buf, BufferIsLocal, DebugPrintBufferRefcount(), ereport, errhidecontext(), errhidestmt(), errmsg, fb(), GetBufferDescriptor(), GetLocalBufferDescriptor(), LOG, PG_GETARG_BOOL, PG_GETARG_INT32, PG_RETURN_VOID, TerminateBufferIO(), and TerminateLocalBufferIO().

◆ buffer_create_toy()

Datum buffer_create_toy ( PG_FUNCTION_ARGS  )

Definition at line 591 of file test_aio.c.

592{
593 Oid relid = PG_GETARG_OID(0);
594 BlockNumber blkno = PG_GETARG_UINT32(1);
595 Relation rel;
596 Buffer buf;
597
599
600 buf = create_toy_buffer(rel, blkno);
602
604
606}
uint32 BlockNumber
Definition block.h:31
void ReleaseBuffer(Buffer buffer)
Definition bufmgr.c:5586
#define PG_GETARG_OID(n)
Definition fmgr.h:275
#define PG_GETARG_UINT32(n)
Definition fmgr.h:270
#define PG_RETURN_INT32(x)
Definition fmgr.h:355
#define NoLock
Definition lockdefs.h:34
#define AccessExclusiveLock
Definition lockdefs.h:43
unsigned int Oid
void relation_close(Relation relation, LOCKMODE lockmode)
Definition relation.c:206
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition relation.c:48
static Buffer create_toy_buffer(Relation rel, BlockNumber blkno)
Definition test_aio.c:325

References AccessExclusiveLock, buf, create_toy_buffer(), NoLock, PG_GETARG_OID, PG_GETARG_UINT32, PG_RETURN_INT32, relation_close(), relation_open(), and ReleaseBuffer().

◆ create_toy_buffer()

static Buffer create_toy_buffer ( Relation  rel,
BlockNumber  blkno 
)
static

Definition at line 325 of file test_aio.c.

326{
327 Buffer buf;
330 bool was_pinned = false;
331 uint64 unset_bits = 0;
332
333 /* place buffer in shared buffers without erroring out */
336
338 {
341 }
342 else
343 {
346 }
347
348 /*
349 * We should be the only backend accessing this buffer. This is just a
350 * small bit of belt-and-suspenders defense, none of this code should ever
351 * run in a cluster with real data.
352 */
354 was_pinned = true;
355 else
357
359 {
362 }
363 else
364 {
366 }
367
368 if (was_pinned)
369 elog(ERROR, "toy buffer %d was already pinned",
370 buf);
371
372 return buf;
373}
static void pg_atomic_unlocked_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition atomics.h:494
static uint64 pg_atomic_read_u64(volatile pg_atomic_uint64 *ptr)
Definition atomics.h:467
static uint64 UnlockBufHdrExt(BufferDesc *desc, uint64 old_buf_state, uint64 set_bits, uint64 unset_bits, int refcount_change)
#define BM_DIRTY
#define BUF_STATE_GET_REFCOUNT(state)
uint64 LockBufHdr(BufferDesc *desc)
Definition bufmgr.c:7518
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
Definition bufmgr.c:926
@ BUFFER_LOCK_UNLOCK
Definition bufmgr.h:207
static void LockBuffer(Buffer buffer, BufferLockMode mode)
Definition bufmgr.h:334
@ RBM_ZERO_AND_LOCK
Definition bufmgr.h:47
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
#define RelationUsesLocalBuffers(relation)
Definition rel.h:648
@ MAIN_FORKNUM
Definition relpath.h:58

References BM_DIRTY, BM_VALID, buf, BUF_STATE_GET_REFCOUNT, BUFFER_LOCK_UNLOCK, elog, ERROR, fb(), GetBufferDescriptor(), GetLocalBufferDescriptor(), LockBuffer(), LockBufHdr(), MAIN_FORKNUM, pg_atomic_read_u64(), pg_atomic_unlocked_write_u64(), RBM_ZERO_AND_LOCK, ReadBufferExtended(), RelationUsesLocalBuffers, and UnlockBufHdrExt().

Referenced by buffer_create_toy(), and read_rel_block_ll().

◆ errno_from_string()

Datum errno_from_string ( PG_FUNCTION_ARGS  )

Definition at line 156 of file test_aio.c.

157{
158 const char *sym = text_to_cstring(PG_GETARG_TEXT_PP(0));
159
160 if (strcmp(sym, "EIO") == 0)
162 else if (strcmp(sym, "EAGAIN") == 0)
164 else if (strcmp(sym, "EINTR") == 0)
166 else if (strcmp(sym, "ENOSPC") == 0)
168 else if (strcmp(sym, "EROFS") == 0)
170
173 errmsg_internal("%s is not a supported errno value", sym));
175}
int errcode(int sqlerrcode)
Definition elog.c:874
int int errmsg_internal(const char *fmt,...) pg_attribute_printf(1
#define PG_GETARG_TEXT_PP(n)
Definition fmgr.h:310
char * text_to_cstring(const text *t)
Definition varlena.c:217
#define EINTR
Definition win32_port.h:361
#define EAGAIN
Definition win32_port.h:359

References EAGAIN, EINTR, ereport, errcode(), errmsg_internal(), ERROR, fb(), PG_GETARG_TEXT_PP, PG_RETURN_INT32, and text_to_cstring().

◆ evict_rel()

Datum evict_rel ( PG_FUNCTION_ARGS  )

Definition at line 542 of file test_aio.c.

543{
544 Oid relid = PG_GETARG_OID(0);
545 Relation rel;
546
548
549 /*
550 * EvictRelUnpinnedBuffers() doesn't support temp tables, so for temp
551 * tables we have to do it the expensive way and evict every possible
552 * buffer.
553 */
555 {
556 SMgrRelation smgr = RelationGetSmgr(rel);
557
558 for (int forknum = MAIN_FORKNUM; forknum <= MAX_FORKNUM; forknum++)
559 {
560 BlockNumber nblocks;
561
562 if (!smgrexists(smgr, forknum))
563 continue;
564
565 nblocks = smgrnblocks(smgr, forknum);
566
567 for (int blkno = 0; blkno < nblocks; blkno++)
568 {
569 invalidate_one_block(rel, forknum, blkno);
570 }
571 }
572 }
573 else
574 {
578
581 }
582
584
585
587}
void EvictRelUnpinnedBuffers(Relation rel, int32 *buffers_evicted, int32 *buffers_flushed, int32 *buffers_skipped)
Definition bufmgr.c:8032
int32_t int32
Definition c.h:620
static SMgrRelation RelationGetSmgr(Relation rel)
Definition rel.h:578
#define MAX_FORKNUM
Definition relpath.h:70
BlockNumber smgrnblocks(SMgrRelation reln, ForkNumber forknum)
Definition smgr.c:819
bool smgrexists(SMgrRelation reln, ForkNumber forknum)
Definition smgr.c:462
static void invalidate_one_block(Relation rel, ForkNumber forknum, BlockNumber blkno)
Definition test_aio.c:481

References AccessExclusiveLock, EvictRelUnpinnedBuffers(), fb(), invalidate_one_block(), MAIN_FORKNUM, MAX_FORKNUM, PG_GETARG_OID, PG_RETURN_VOID, relation_close(), relation_open(), RelationGetSmgr(), RelationUsesLocalBuffers, smgrexists(), and smgrnblocks().

◆ grow_rel()

Datum grow_rel ( PG_FUNCTION_ARGS  )

Definition at line 179 of file test_aio.c.

180{
181 Oid relid = PG_GETARG_OID(0);
182 uint32 nblocks = PG_GETARG_UINT32(1);
183 Relation rel;
184#define MAX_BUFFERS_TO_EXTEND_BY 64
186
188
189 while (nblocks > 0)
190 {
192
194
197 NULL,
198 0,
202
203 nblocks -= extend_by_pages;
204
205 for (uint32 i = 0; i < extend_by_pages; i++)
206 {
208 }
209 }
210
212
214}
BlockNumber ExtendBufferedRelBy(BufferManagerRelation bmr, ForkNumber fork, BufferAccessStrategy strategy, uint32 flags, uint32 extend_by, Buffer *buffers, uint32 *extended_by)
Definition bufmgr.c:1011
#define BMR_REL(p_rel)
Definition bufmgr.h:114
#define Min(x, y)
Definition c.h:1091
uint32_t uint32
Definition c.h:624
int i
Definition isn.c:77
#define MAX_BUFFERS_TO_EXTEND_BY

References AccessExclusiveLock, BMR_REL, ExtendBufferedRelBy(), fb(), i, MAIN_FORKNUM, MAX_BUFFERS_TO_EXTEND_BY, Min, NoLock, PG_GETARG_OID, PG_GETARG_UINT32, PG_RETURN_VOID, relation_close(), relation_open(), and ReleaseBuffer().

◆ handle_get()

Datum handle_get ( PG_FUNCTION_ARGS  )

Definition at line 921 of file test_aio.c.

922{
924
926}
PgAioHandle * pgaio_io_acquire(struct ResourceOwnerData *resowner, PgAioReturn *ret)
Definition aio.c:162
static PgAioHandle * last_handle
Definition test_aio.c:88

References CurrentResourceOwner, fb(), last_handle, PG_RETURN_VOID, and pgaio_io_acquire().

◆ handle_get_and_error()

Datum handle_get_and_error ( PG_FUNCTION_ARGS  )

Definition at line 942 of file test_aio.c.

943{
945
946 elog(ERROR, "as you command");
948}

References CurrentResourceOwner, elog, ERROR, fb(), PG_RETURN_VOID, and pgaio_io_acquire().

◆ handle_get_release()

Datum handle_get_release ( PG_FUNCTION_ARGS  )

Definition at line 962 of file test_aio.c.

963{
964 PgAioHandle *handle;
965
967 pgaio_io_release(handle);
968
970}
void pgaio_io_release(PgAioHandle *ioh)
Definition aio.c:240

References CurrentResourceOwner, fb(), PG_RETURN_VOID, pgaio_io_acquire(), and pgaio_io_release().

◆ handle_get_twice()

◆ handle_release_last()

Datum handle_release_last ( PG_FUNCTION_ARGS  )

Definition at line 930 of file test_aio.c.

931{
932 if (!last_handle)
933 elog(ERROR, "no handle");
934
936
938}

References elog, ERROR, last_handle, PG_RETURN_VOID, and pgaio_io_release().

◆ inj_io_completion_continue()

Datum inj_io_completion_continue ( PG_FUNCTION_ARGS  )

Definition at line 1186 of file test_aio.c.

1187{
1188#ifdef USE_INJECTION_POINTS
1194#else
1195 elog(ERROR, "injection points not supported");
1196#endif
1197
1199}
#define InvalidBlockNumber
Definition block.h:33
void ConditionVariableBroadcast(ConditionVariable *cv)
#define InvalidPid
Definition miscadmin.h:32
#define InvalidOid
ConditionVariable cv
Definition test_aio.c:49
BlockNumber completion_wait_blockno
Definition test_aio.c:56
pid_t completion_wait_pid
Definition test_aio.c:57
bool enabled_completion_wait
Definition test_aio.c:54
Oid completion_wait_relfilenode
Definition test_aio.c:55
static InjIoErrorState * inj_io_error_state
Definition test_aio.c:74

References InjIoErrorState::completion_wait_blockno, InjIoErrorState::completion_wait_pid, InjIoErrorState::completion_wait_relfilenode, ConditionVariableBroadcast(), InjIoErrorState::cv, elog, InjIoErrorState::enabled_completion_wait, ERROR, inj_io_error_state, InvalidBlockNumber, InvalidOid, InvalidPid, and PG_RETURN_VOID.

◆ inj_io_completion_wait()

◆ inj_io_reopen_attach()

Datum inj_io_reopen_attach ( PG_FUNCTION_ARGS  )

Definition at line 1235 of file test_aio.c.

1236{
1237#ifdef USE_INJECTION_POINTS
1239#else
1240 elog(ERROR, "injection points not supported");
1241#endif
1242
1244}
bool enabled_reopen
Definition test_aio.c:52

References elog, InjIoErrorState::enabled_reopen, ERROR, inj_io_error_state, and PG_RETURN_VOID.

◆ inj_io_reopen_detach()

Datum inj_io_reopen_detach ( PG_FUNCTION_ARGS  )

Definition at line 1248 of file test_aio.c.

1249{
1250#ifdef USE_INJECTION_POINTS
1252#else
1253 elog(ERROR, "injection points not supported");
1254#endif
1256}

References elog, InjIoErrorState::enabled_reopen, ERROR, inj_io_error_state, and PG_RETURN_VOID.

◆ inj_io_short_read_attach()

◆ inj_io_short_read_detach()

Datum inj_io_short_read_detach ( PG_FUNCTION_ARGS  )

Definition at line 1223 of file test_aio.c.

1224{
1225#ifdef USE_INJECTION_POINTS
1227#else
1228 elog(ERROR, "injection points not supported");
1229#endif
1231}

References elog, InjIoErrorState::enabled_short_read, ERROR, inj_io_error_state, and PG_RETURN_VOID.

◆ invalidate_one_block()

static void invalidate_one_block ( Relation  rel,
ForkNumber  forknum,
BlockNumber  blkno 
)
static

Definition at line 481 of file test_aio.c.

482{
484 Buffer buf;
485
486 /*
487 * This is a gross hack, but there's no other API exposed that allows to
488 * get a buffer ID without actually reading the block in.
489 */
490 pr = PrefetchBuffer(rel, forknum, blkno);
491 buf = pr.recent_buffer;
492
493 if (BufferIsValid(buf))
494 {
495 /* if the buffer contents aren't valid, this'll return false */
496 if (ReadRecentBuffer(rel->rd_locator, forknum, blkno, buf))
497 {
501 bool flushed;
502
504
505 if (pg_atomic_read_u64(&buf_hdr->state) & BM_DIRTY)
506 {
507 if (BufferIsLocal(buf))
509 else
511 }
513
514 if (BufferIsLocal(buf))
516 else if (!EvictUnpinnedBuffer(buf, &flushed))
517 elog(ERROR, "couldn't evict");
518 }
519 }
520
521}
PrefetchBufferResult PrefetchBuffer(Relation reln, ForkNumber forkNum, BlockNumber blockNum)
Definition bufmgr.c:787
void UnlockReleaseBuffer(Buffer buffer)
Definition bufmgr.c:5603
bool EvictUnpinnedBuffer(Buffer buf, bool *buffer_flushed)
Definition bufmgr.c:7953
bool ReadRecentBuffer(RelFileLocator rlocator, ForkNumber forkNum, BlockNumber blockNum, Buffer recent_buffer)
Definition bufmgr.c:818
void FlushOneBuffer(Buffer buffer)
Definition bufmgr.c:5566
@ BUFFER_LOCK_EXCLUSIVE
Definition bufmgr.h:222
static bool BufferIsValid(Buffer bufnum)
Definition bufmgr.h:419
void FlushLocalBuffer(BufferDesc *bufHdr, SMgrRelation reln)
Definition localbuf.c:183
void InvalidateLocalBuffer(BufferDesc *bufHdr, bool check_unreferenced)
Definition localbuf.c:621
RelFileLocator rd_locator
Definition rel.h:57

References BM_DIRTY, buf, BUFFER_LOCK_EXCLUSIVE, BufferIsLocal, BufferIsValid(), elog, ERROR, EvictUnpinnedBuffer(), fb(), FlushLocalBuffer(), FlushOneBuffer(), GetBufferDescriptor(), GetLocalBufferDescriptor(), InvalidateLocalBuffer(), LockBuffer(), pg_atomic_read_u64(), PrefetchBuffer(), RelationData::rd_locator, ReadRecentBuffer(), and UnlockReleaseBuffer().

Referenced by evict_rel(), and invalidate_rel_block().

◆ invalidate_rel_block()

Datum invalidate_rel_block ( PG_FUNCTION_ARGS  )

◆ modify_rel_block()

Datum modify_rel_block ( PG_FUNCTION_ARGS  )

Definition at line 218 of file test_aio.c.

219{
220 Oid relid = PG_GETARG_OID(0);
221 BlockNumber blkno = PG_GETARG_UINT32(1);
222 bool zero = PG_GETARG_BOOL(2);
226 bool flushed;
227 Relation rel;
228 Buffer buf;
230
232
233 buf = ReadBufferExtended(rel, MAIN_FORKNUM, blkno,
235
237
238 /*
239 * copy the page to local memory, seems nicer than to directly modify in
240 * the buffer pool.
241 */
243
245
246 /*
247 * Don't want to have a buffer in-memory that's marked valid where the
248 * on-disk contents are invalid. Particularly not if the in-memory buffer
249 * could be dirty...
250 *
251 * While we hold an AEL on the relation nobody else should be able to read
252 * the buffer in.
253 *
254 * NB: This is probably racy, better don't copy this to non-test code.
255 */
256 if (BufferIsLocal(buf))
258 else
260
261 /*
262 * Now modify the page as asked for by the caller.
263 */
264 if (zero)
265 memset(page, 0, BufferGetPageSize(buf));
266
268 PageInit(page, BufferGetPageSize(buf), 0);
269
270 ph = (PageHeader) page;
271
272 if (corrupt_header)
273 ph->pd_special = BLCKSZ + 1;
274
276 {
277 bool successfully_corrupted = 0;
278
279 /*
280 * Any single modification of the checksum could just end up being
281 * valid again, due to e.g. corrupt_header changing the data in a way
282 * that'd result in the "corrupted" checksum, or the checksum already
283 * being invalid. Retry in that, unlikely, case.
284 */
285 for (int i = 0; i < 100; i++)
286 {
287 uint16 verify_checksum;
289
290 old_checksum = ph->pd_checksum;
291 ph->pd_checksum = old_checksum + 1;
292
293 elog(LOG, "corrupting checksum of blk %u from %u to %u",
294 blkno, old_checksum, ph->pd_checksum);
295
296 verify_checksum = pg_checksum_page(page, blkno);
297 if (verify_checksum != ph->pd_checksum)
298 {
300 break;
301 }
302 }
303
305 elog(ERROR, "could not corrupt checksum, what's going on?");
306 }
307 else
308 {
309 PageSetChecksum(page, blkno);
310 }
311
313 MAIN_FORKNUM, blkno, page, true);
314
316
318}
static Page BufferGetPage(Buffer buffer)
Definition bufmgr.h:468
static Size BufferGetPageSize(Buffer buffer)
Definition bufmgr.h:457
@ RBM_ZERO_ON_ERROR
Definition bufmgr.h:51
void PageSetChecksum(Page page, BlockNumber blkno)
Definition bufpage.c:1518
void PageInit(Page page, Size pageSize, Size specialSize)
Definition bufpage.c:42
static bool PageIsEmpty(const PageData *page)
Definition bufpage.h:248
PageHeaderData * PageHeader
Definition bufpage.h:199
PageData * Page
Definition bufpage.h:81
uint16_t uint16
Definition c.h:623
uint16 pg_checksum_page(char *page, BlockNumber blkno)
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))
void * palloc_aligned(Size size, Size alignto, int flags)
Definition mcxt.c:1606
#define PG_IO_ALIGN_SIZE
static void smgrwrite(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, const void *buffer, bool skipFsync)
Definition smgr.h:131

References AccessExclusiveLock, buf, BUFFER_LOCK_EXCLUSIVE, BufferGetPage(), BufferGetPageSize(), BufferIsLocal, elog, ERROR, EvictUnpinnedBuffer(), fb(), GetLocalBufferDescriptor(), i, InvalidateLocalBuffer(), LockBuffer(), LOG, MAIN_FORKNUM, memcpy(), NoLock, PageInit(), PageIsEmpty(), PageSetChecksum(), palloc_aligned(), pg_checksum_page(), PG_GETARG_BOOL, PG_GETARG_OID, PG_GETARG_UINT32, PG_IO_ALIGN_SIZE, PG_RETURN_VOID, RBM_ZERO_ON_ERROR, ReadBufferExtended(), relation_close(), relation_open(), RelationGetSmgr(), smgrwrite(), and UnlockReleaseBuffer().

◆ PG_FUNCTION_INFO_V1() [1/24]

PG_FUNCTION_INFO_V1 ( batch_end  )

◆ PG_FUNCTION_INFO_V1() [2/24]

PG_FUNCTION_INFO_V1 ( batch_start  )

◆ PG_FUNCTION_INFO_V1() [3/24]

PG_FUNCTION_INFO_V1 ( buffer_call_start_io  )

◆ PG_FUNCTION_INFO_V1() [4/24]

PG_FUNCTION_INFO_V1 ( buffer_call_terminate_io  )

◆ PG_FUNCTION_INFO_V1() [5/24]

PG_FUNCTION_INFO_V1 ( buffer_create_toy  )

◆ PG_FUNCTION_INFO_V1() [6/24]

PG_FUNCTION_INFO_V1 ( errno_from_string  )

◆ PG_FUNCTION_INFO_V1() [7/24]

PG_FUNCTION_INFO_V1 ( evict_rel  )

◆ PG_FUNCTION_INFO_V1() [8/24]

PG_FUNCTION_INFO_V1 ( grow_rel  )

◆ PG_FUNCTION_INFO_V1() [9/24]

PG_FUNCTION_INFO_V1 ( handle_get  )

◆ PG_FUNCTION_INFO_V1() [10/24]

PG_FUNCTION_INFO_V1 ( handle_get_and_error  )

◆ PG_FUNCTION_INFO_V1() [11/24]

PG_FUNCTION_INFO_V1 ( handle_get_release  )

◆ PG_FUNCTION_INFO_V1() [12/24]

PG_FUNCTION_INFO_V1 ( handle_get_twice  )

◆ PG_FUNCTION_INFO_V1() [13/24]

PG_FUNCTION_INFO_V1 ( handle_release_last  )

◆ PG_FUNCTION_INFO_V1() [14/24]

PG_FUNCTION_INFO_V1 ( inj_io_completion_continue  )

◆ PG_FUNCTION_INFO_V1() [15/24]

PG_FUNCTION_INFO_V1 ( inj_io_completion_wait  )

◆ PG_FUNCTION_INFO_V1() [16/24]

PG_FUNCTION_INFO_V1 ( inj_io_reopen_attach  )

◆ PG_FUNCTION_INFO_V1() [17/24]

PG_FUNCTION_INFO_V1 ( inj_io_reopen_detach  )

◆ PG_FUNCTION_INFO_V1() [18/24]

PG_FUNCTION_INFO_V1 ( inj_io_short_read_attach  )

◆ PG_FUNCTION_INFO_V1() [19/24]

PG_FUNCTION_INFO_V1 ( inj_io_short_read_detach  )

◆ PG_FUNCTION_INFO_V1() [20/24]

PG_FUNCTION_INFO_V1 ( invalidate_rel_block  )

◆ PG_FUNCTION_INFO_V1() [21/24]

PG_FUNCTION_INFO_V1 ( modify_rel_block  )

◆ PG_FUNCTION_INFO_V1() [22/24]

PG_FUNCTION_INFO_V1 ( read_buffers  )

◆ PG_FUNCTION_INFO_V1() [23/24]

PG_FUNCTION_INFO_V1 ( read_rel_block_ll  )

◆ PG_FUNCTION_INFO_V1() [24/24]

PG_FUNCTION_INFO_V1 ( read_stream_for_blocks  )

◆ read_buffers()

Datum read_buffers ( PG_FUNCTION_ARGS  )

Definition at line 696 of file test_aio.c.

697{
698 Oid relid = PG_GETARG_OID(0);
699 BlockNumber startblock = PG_GETARG_UINT32(1);
700 int32 nblocks = PG_GETARG_INT32(2);
701 ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
702 Relation rel;
703 SMgrRelation smgr;
704 int nblocks_done = 0;
705 int nblocks_disp = 0;
706 int nios = 0;
708 Buffer *buffers;
710 bool *io_reqds;
711 int *nblocks_per_io;
712
713 Assert(nblocks > 0);
714
715 InitMaterializedSRF(fcinfo, 0);
716
717 /* at worst each block gets its own IO */
718 operations = palloc0(sizeof(ReadBuffersOperation) * nblocks);
719 buffers = palloc0(sizeof(Buffer) * nblocks);
720 buffers_datum = palloc0(sizeof(Datum) * nblocks);
721 io_reqds = palloc0(sizeof(bool) * nblocks);
722 nblocks_per_io = palloc0(sizeof(int) * nblocks);
723
724 rel = relation_open(relid, AccessShareLock);
725 smgr = RelationGetSmgr(rel);
726
727 /*
728 * Do StartReadBuffers() until IO for all the required blocks has been
729 * started (if required).
730 */
731 while (nblocks_done < nblocks)
732 {
734 int nblocks_this_io =
735 Min(nblocks - nblocks_done, io_combine_limit);
736
737 operation->rel = rel;
738 operation->smgr = smgr;
739 operation->persistence = rel->rd_rel->relpersistence;
740 operation->strategy = NULL;
741 operation->forknum = MAIN_FORKNUM;
742
744 &buffers[nblocks_done],
745 startblock + nblocks_done,
747 0);
749 nios++;
750 nblocks_done += nblocks_this_io;
751 }
752
753 /*
754 * Now wait for all operations that required IO. This is done at the end,
755 * as otherwise waiting for IO in progress in other backends could
756 * influence the result for subsequent buffers / blocks.
757 */
758 for (int nio = 0; nio < nios; nio++)
759 {
761
762 if (io_reqds[nio])
764 }
765
766 /*
767 * Convert what has been done into SQL SRF return value.
768 */
769 for (int nio = 0; nio < nios; nio++)
770 {
773 Datum values[6] = {0};
774 bool nulls[6] = {0};
776
777 /* convert buffer array to datum array */
778 for (int i = 0; i < nblocks_this_io; i++)
779 {
780 Buffer buf = buffers[nblocks_disp + i];
781
782 Assert(BufferGetBlockNumber(buf) == startblock + nblocks_disp + i);
783
785 }
786
789 INT4OID);
790
791 /* blockoff */
793 nulls[0] = false;
794
795 /* blocknum */
796 values[1] = UInt32GetDatum(startblock + nblocks_disp);
797 nulls[1] = false;
798
799 /* io_reqd */
801 nulls[2] = false;
802
803 /* foreign IO - only valid when IO was required */
804 values[3] = BoolGetDatum(io_reqds[nio] ? operation->foreign_io : false);
805 nulls[3] = false;
806
807 /* nblocks */
809 nulls[4] = false;
810
811 /* array of buffers */
813 nulls[5] = false;
814
815 tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
816
818 }
819
820 /* release pins on all the buffers */
821 for (int i = 0; i < nblocks_done; i++)
822 ReleaseBuffer(buffers[i]);
823
824 /*
825 * Free explicitly, to have a chance to detect potential issues with too
826 * long lived references to the operation.
827 */
829 pfree(buffers);
833
835
836 return (Datum) 0;
837}
ArrayType * construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
static Datum values[MAXATTR]
Definition bootstrap.c:190
BlockNumber BufferGetBlockNumber(Buffer buffer)
Definition bufmgr.c:4446
bool StartReadBuffers(ReadBuffersOperation *operation, Buffer *buffers, BlockNumber blockNum, int *nblocks, int flags)
Definition bufmgr.c:1609
bool WaitReadBuffers(ReadBuffersOperation *operation)
Definition bufmgr.c:1750
int io_combine_limit
Definition bufmgr.c:215
#define Assert(condition)
Definition c.h:943
static DataChecksumsWorkerOperation operation
void InitMaterializedSRF(FunctionCallInfo fcinfo, uint32 flags)
Definition funcapi.c:76
#define false
#define AccessShareLock
Definition lockdefs.h:36
void pfree(void *pointer)
Definition mcxt.c:1616
void * palloc0(Size size)
Definition mcxt.c:1417
static Datum PointerGetDatum(const void *X)
Definition postgres.h:342
static Datum BoolGetDatum(bool X)
Definition postgres.h:112
uint64_t Datum
Definition postgres.h:70
static Datum Int32GetDatum(int32 X)
Definition postgres.h:212
static Datum UInt32GetDatum(uint32 X)
Definition postgres.h:232
Form_pg_class rd_rel
Definition rel.h:111
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, const Datum *values, const bool *isnull)
Definition tuplestore.c:785

References AccessShareLock, Assert, BoolGetDatum(), buf, BufferGetBlockNumber(), construct_array_builtin(), fb(), i, InitMaterializedSRF(), Int32GetDatum(), io_combine_limit, MAIN_FORKNUM, Min, NoLock, operation, palloc0(), pfree(), PG_GETARG_INT32, PG_GETARG_OID, PG_GETARG_UINT32, PointerGetDatum(), RelationData::rd_rel, relation_close(), relation_open(), RelationGetSmgr(), ReleaseBuffer(), StartReadBuffers(), tuplestore_putvalues(), UInt32GetDatum(), values, and WaitReadBuffers().

◆ read_rel_block_ll()

Datum read_rel_block_ll ( PG_FUNCTION_ARGS  )

Definition at line 382 of file test_aio.c.

383{
384 Oid relid = PG_GETARG_OID(0);
385 BlockNumber blkno = PG_GETARG_UINT32(1);
386 int nblocks = PG_GETARG_INT32(2);
392 Relation rel;
395 Page pages[PG_IOV_MAX];
396 uint8 srb_flags = 0;
400 SMgrRelation smgr;
401
403 elog(ERROR, "nblocks is out of range");
404
405 rel = relation_open(relid, AccessShareLock);
406
407 for (int i = 0; i < nblocks; i++)
408 {
409 bufs[i] = create_toy_buffer(rel, blkno + i);
410 pages[i] = BufferGetBlock(bufs[i]);
414 }
415
416 smgr = RelationGetSmgr(rel);
417
419
422
424 {
425 for (int i = 0; i < nblocks; i++)
426 StartLocalBufferIO(buf_hdrs[i], true, true, NULL);
428 }
429 else
430 {
431 for (int i = 0; i < nblocks; i++)
432 StartSharedBufferIO(buf_hdrs[i], true, true, NULL);
433 }
434
436
441
446 srb_flags);
447
448 if (batchmode_enter)
450
451 smgrstartreadv(ioh, smgr, MAIN_FORKNUM, blkno,
452 (void *) pages, nblocks);
453
456
457 if (batchmode_exit)
459
460 for (int i = 0; i < nblocks; i++)
462
463 if (wait_complete)
464 {
466
467 if (ior.result.status != PGAIO_RS_OK)
469 &ior.target_data,
470 ior.result.status == PGAIO_RS_ERROR ?
471 ERROR : WARNING);
472 }
473
475
477}
void pgaio_io_get_wref(PgAioHandle *ioh, PgAioWaitRef *iow)
Definition aio.c:366
void pgaio_io_set_flag(PgAioHandle *ioh, PgAioHandleFlags flag)
Definition aio.c:330
void pgaio_wref_wait(PgAioWaitRef *iow)
Definition aio.c:991
@ PGAIO_HCB_LOCAL_BUFFER_READV
Definition aio.h:200
@ PGAIO_HCB_SHARED_BUFFER_READV
Definition aio.h:198
@ PGAIO_HF_REFERENCES_LOCAL
Definition aio.h:60
void pgaio_io_set_handle_data_32(PgAioHandle *ioh, uint32 *data, uint8 len)
void pgaio_io_register_callbacks(PgAioHandle *ioh, PgAioHandleCallbackID cb_id, uint8 cb_data)
void pgaio_result_report(PgAioResult result, const PgAioTargetData *target_data, int elevel)
@ PGAIO_RS_OK
Definition aio_types.h:81
@ PGAIO_RS_ERROR
Definition aio_types.h:84
bool zero_damaged_pages
Definition bufmgr.c:189
#define READ_BUFFERS_ZERO_ON_ERROR
Definition bufmgr.h:122
static Block BufferGetBlock(Buffer buffer)
Definition bufmgr.h:435
#define READ_BUFFERS_IGNORE_CHECKSUM_FAILURES
Definition bufmgr.h:126
bool ignore_checksum_failure
Definition bufpage.c:27
uint8_t uint8
Definition c.h:622
#define WARNING
Definition elog.h:37
#define PG_IOV_MAX
Definition pg_iovec.h:47
void pgstat_prepare_report_checksum_failure(Oid dboid)
void smgrstartreadv(PgAioHandle *ioh, SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, void **buffers, BlockNumber nblocks)
Definition smgr.c:753
void smgrreleaseall(void)
Definition smgr.c:412
RelFileLocator locator
RelFileLocatorBackend smgr_rlocator
Definition smgr.h:38

References AccessShareLock, BufferGetBlock(), BufferIsLocal, create_toy_buffer(), CurrentResourceOwner, RelFileLocator::dbOid, elog, ERROR, fb(), GetBufferDescriptor(), GetLocalBufferDescriptor(), i, ignore_checksum_failure, RelFileLocatorBackend::locator, MAIN_FORKNUM, NoLock, PG_GETARG_BOOL, PG_GETARG_INT32, PG_GETARG_OID, PG_GETARG_UINT32, PG_IOV_MAX, PG_RETURN_VOID, pgaio_enter_batchmode(), pgaio_exit_batchmode(), PGAIO_HCB_LOCAL_BUFFER_READV, PGAIO_HCB_SHARED_BUFFER_READV, PGAIO_HF_REFERENCES_LOCAL, pgaio_io_acquire(), pgaio_io_get_wref(), pgaio_io_register_callbacks(), pgaio_io_set_flag(), pgaio_io_set_handle_data_32(), pgaio_result_report(), PGAIO_RS_ERROR, PGAIO_RS_OK, pgaio_wref_wait(), pgstat_prepare_report_checksum_failure(), READ_BUFFERS_IGNORE_CHECKSUM_FAILURES, READ_BUFFERS_ZERO_ON_ERROR, relation_close(), relation_open(), RelationGetSmgr(), RelationUsesLocalBuffers, ReleaseBuffer(), SMgrRelationData::smgr_rlocator, smgrreleaseall(), smgrstartreadv(), StartLocalBufferIO(), StartSharedBufferIO(), WARNING, and zero_damaged_pages.

◆ read_stream_for_blocks()

Datum read_stream_for_blocks ( PG_FUNCTION_ARGS  )

Definition at line 854 of file test_aio.c.

855{
856 Oid relid = PG_GETARG_OID(0);
858 ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
859 Relation rel;
861 ReadStream *stream;
862
863 InitMaterializedSRF(fcinfo, 0);
864
865 /*
866 * We expect the input to be an N-element int4 array; verify that. We
867 * don't need to use deconstruct_array() since the array data is just
868 * going to look like a C array of N int4 values.
869 */
870 if (ARR_NDIM(blocksarray) != 1 ||
873 elog(ERROR, "expected 1 dimensional int4 array");
874
875 stream_data.curblock = 0;
876 stream_data.nblocks = ARR_DIMS(blocksarray)[0];
878
879 rel = relation_open(relid, AccessShareLock);
880
882 NULL,
883 rel,
887 0);
888
889 for (int i = 0; i < stream_data.nblocks; i++)
890 {
892 Datum values[3] = {0};
893 bool nulls[3] = {0};
894
895 if (!BufferIsValid(buf))
896 elog(ERROR, "read_stream_next_buffer() call %d is unexpectedly invalid", i);
897
898 values[0] = Int32GetDatum(i);
899 values[1] = UInt32GetDatum(stream_data.blocks[i]);
901
902 tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
903
905 }
906
908 elog(ERROR, "read_stream_next_buffer() call %d is unexpectedly valid",
909 stream_data.nblocks);
910
911 read_stream_end(stream);
912
914
915 return (Datum) 0;
916}
#define ARR_NDIM(a)
Definition array.h:290
#define PG_GETARG_ARRAYTYPE_P(n)
Definition array.h:263
#define ARR_DATA_PTR(a)
Definition array.h:322
#define ARR_ELEMTYPE(a)
Definition array.h:292
#define ARR_DIMS(a)
Definition array.h:294
#define ARR_HASNULL(a)
Definition array.h:291
#define InvalidBuffer
Definition buf.h:25
Buffer read_stream_next_buffer(ReadStream *stream, void **per_buffer_data)
ReadStream * read_stream_begin_relation(int flags, BufferAccessStrategy strategy, Relation rel, ForkNumber forknum, ReadStreamBlockNumberCB callback, void *callback_private_data, size_t per_buffer_data_size)
void read_stream_end(ReadStream *stream)
#define READ_STREAM_FULL
Definition read_stream.h:43
static BlockNumber read_stream_for_blocks_cb(ReadStream *stream, void *callback_private_data, void *per_buffer_data)
Definition test_aio.c:841

References AccessShareLock, ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_NDIM, buf, BufferIsValid(), elog, ERROR, fb(), i, InitMaterializedSRF(), Int32GetDatum(), InvalidBuffer, MAIN_FORKNUM, NoLock, PG_GETARG_ARRAYTYPE_P, PG_GETARG_OID, read_stream_begin_relation(), read_stream_end(), read_stream_for_blocks_cb(), READ_STREAM_FULL, read_stream_next_buffer(), relation_close(), relation_open(), ReleaseBuffer(), tuplestore_putvalues(), UInt32GetDatum(), and values.

◆ read_stream_for_blocks_cb()

static BlockNumber read_stream_for_blocks_cb ( ReadStream stream,
void callback_private_data,
void per_buffer_data 
)
static

Definition at line 841 of file test_aio.c.

844{
845 BlocksReadStreamData *stream_data = callback_private_data;
846
847 if (stream_data->curblock >= stream_data->nblocks)
848 return InvalidBlockNumber;
849 return stream_data->blocks[stream_data->curblock++];
850}

References BlocksReadStreamData::blocks, fb(), and InvalidBlockNumber.

Referenced by read_stream_for_blocks().

◆ test_aio_shmem_attach()

static void test_aio_shmem_attach ( void arg)
static

Definition at line 131 of file test_aio.c.

132{
133 /*
134 * Pre-load the injection points now, so we can call them in a critical
135 * section.
136 */
137#ifdef USE_INJECTION_POINTS
138 InjectionPointLoad("aio-process-completion-before-shared");
139 InjectionPointLoad("aio-worker-after-reopen");
140 elog(LOG, "injection point loaded");
141#endif
142}
void InjectionPointLoad(const char *name)

References elog, InjectionPointLoad(), and LOG.

◆ test_aio_shmem_init()

static void test_aio_shmem_init ( void arg)
static

Definition at line 102 of file test_aio.c.

103{
104 /* First time through, initialize */
108
111
112#ifdef USE_INJECTION_POINTS
113 InjectionPointAttach("aio-process-completion-before-shared",
114 "test_aio",
115 "inj_io_completion_hook",
116 NULL,
117 0);
118 InjectionPointLoad("aio-process-completion-before-shared");
119
120 InjectionPointAttach("aio-worker-after-reopen",
121 "test_aio",
122 "inj_io_reopen",
123 NULL,
124 0);
125 InjectionPointLoad("aio-worker-after-reopen");
126
127#endif
128}
void ConditionVariableInit(ConditionVariable *cv)
void InjectionPointAttach(const char *name, const char *library, const char *function, const void *private_data, int private_data_size)
uint32 completion_wait_event
Definition test_aio.c:58
uint32 WaitEventInjectionPointNew(const char *wait_event_name)
Definition wait_event.c:155

References InjIoErrorState::completion_wait_event, ConditionVariableInit(), InjIoErrorState::cv, InjIoErrorState::enabled_completion_wait, InjIoErrorState::enabled_reopen, InjIoErrorState::enabled_short_read, fb(), inj_io_error_state, InjectionPointAttach(), InjectionPointLoad(), and WaitEventInjectionPointNew().

◆ test_aio_shmem_request()

static void test_aio_shmem_request ( void arg)
static

Definition at line 93 of file test_aio.c.

94{
95 ShmemRequestStruct(.name = "test_aio injection points",
96 .size = sizeof(InjIoErrorState),
97 .ptr = (void **) &inj_io_error_state,
98 );
99}
#define ShmemRequestStruct(...)
Definition shmem.h:176
const char * name

References inj_io_error_state, name, and ShmemRequestStruct.

Variable Documentation

◆ inj_io_error_state

◆ inj_io_shmem_callbacks

const ShmemCallbacks inj_io_shmem_callbacks
static
Initial value:
= {
.request_fn = test_aio_shmem_request,
.init_fn = test_aio_shmem_init,
.attach_fn = test_aio_shmem_attach,
}
static void test_aio_shmem_attach(void *arg)
Definition test_aio.c:131
static void test_aio_shmem_request(void *arg)
Definition test_aio.c:93
static void test_aio_shmem_init(void *arg)
Definition test_aio.c:102

Definition at line 81 of file test_aio.c.

81 {
82 .request_fn = test_aio_shmem_request,
83 .init_fn = test_aio_shmem_init,
84 .attach_fn = test_aio_shmem_attach,
85};

Referenced by _PG_init().

◆ last_handle

PgAioHandle* last_handle
static

Definition at line 88 of file test_aio.c.

Referenced by handle_get(), and handle_release_last().

◆ PG_MODULE_MAGIC

PG_MODULE_MAGIC

Definition at line 43 of file test_aio.c.