75 "RELSEG_SIZE must fit in an integer");
101#define INIT_MD_FILETAG(a,xx_rlocator,xx_forknum,xx_segno) \
103 memset(&(a), 0, sizeof(FileTag)), \
104 (a).handler = SYNC_HANDLER_MD, \
105 (a).rlocator = (xx_rlocator), \
106 (a).forknum = (xx_forknum), \
107 (a).segno = (xx_segno) \
113#define EXTENSION_FAIL (1 << 0)
115#define EXTENSION_RETURN_NULL (1 << 1)
117#define EXTENSION_CREATE (1 << 2)
119#define EXTENSION_CREATE_RECOVERY (1 << 3)
121#define EXTENSION_DONT_OPEN (1 << 5)
131#define SEGMENT_CHARS OIDCHARS
132#define MD_PATH_STR_MAXLEN \
134 REL_PATH_STR_MAXLEN \
135 + sizeof((char)'.') \
228 if (
isRedo &&
reln->md_num_open_segs[forknum] > 0)
243 reln->smgr_rlocator.locator.dbOid,
262 errmsg(
"could not create file \"%s\": %m", path.
str)));
267 mdfd = &
reln->md_seg_fds[forknum][0];
269 mdfd->mdfd_segno = 0;
342 for (forknum = 0; forknum <=
MAX_FORKNUM; forknum++)
366 errmsg(
"could not truncate file \"%s\": %m", path)));
380 path =
relpath(rlocator, forknum);
411 errmsg(
"could not remove file \"%s\": %m", path.
str)));
444 for (segno = 1;; segno++)
499#ifdef CHECK_WRITE_VS_EXTEND
512 errmsg(
"cannot extend file \"%s\" beyond %u blocks",
527 errmsg(
"could not extend file \"%s\": %m",
529 errhint(
"Check free disk space.")));
533 errmsg(
"could not extend file \"%s\": wrote only %d of %d bytes at block %u",
535 nbytes,
BLCKSZ, blocknum),
536 errhint(
"Check free disk space.")));
562#ifdef CHECK_WRITE_VS_EXTEND
574 errmsg(
"cannot extend file \"%s\" beyond %u blocks",
616 errmsg(
"could not extend file \"%s\" with FileFallocate(): %m",
618 errhint(
"Check free disk space."));
638 errmsg(
"could not extend file \"%s\": %m",
640 errhint(
"Check free disk space."));
671 if (
reln->md_num_open_segs[forknum] > 0)
672 return &
reln->md_seg_fds[forknum][0];
685 errmsg(
"could not open file \"%s\": %m", path.
str)));
689 mdfd = &
reln->md_seg_fds[forknum][0];
691 mdfd->mdfd_segno = 0;
705 for (
int forknum = 0; forknum <=
MAX_FORKNUM; forknum++)
706 reln->md_num_open_segs[forknum] = 0;
792 for (
int i = 0;
i < nblocks; ++
i)
801 iovp->iov_base = buffers[0];
806 for (
int i = 1;
i < nblocks; ++
i)
808 void *buffer = buffers[
i];
810 if (((
char *)
iovp->iov_base +
iovp->iov_len) == buffer)
819 iovp->iov_base = buffer;
874 elog(
ERROR,
"read crosses segment boundary");
888 reln->smgr_rlocator.locator.spcOid,
889 reln->smgr_rlocator.locator.dbOid,
890 reln->smgr_rlocator.locator.relNumber,
891 reln->smgr_rlocator.backend);
895 reln->smgr_rlocator.locator.spcOid,
896 reln->smgr_rlocator.locator.dbOid,
897 reln->smgr_rlocator.locator.relNumber,
898 reln->smgr_rlocator.backend,
902#ifdef SIMULATE_SHORT_READ
903 nbytes =
Min(nbytes, 4096);
909 errmsg(
"could not read blocks %u..%u in file \"%s\": %m",
956 errmsg(
"could not read blocks %u..%u in file \"%s\": read only %zu of %zu bytes",
1008 elog(
ERROR,
"read crossing segment boundary");
1033 errmsg(
"could not start reading blocks %u..%u in file \"%s\": %m",
1063#ifdef CHECK_WRITE_VS_EXTEND
1091 elog(
ERROR,
"write crosses segment boundary");
1105 reln->smgr_rlocator.locator.spcOid,
1106 reln->smgr_rlocator.locator.dbOid,
1107 reln->smgr_rlocator.locator.relNumber,
1108 reln->smgr_rlocator.backend);
1112 reln->smgr_rlocator.locator.spcOid,
1113 reln->smgr_rlocator.locator.dbOid,
1114 reln->smgr_rlocator.locator.relNumber,
1115 reln->smgr_rlocator.backend,
1119#ifdef SIMULATE_SHORT_WRITE
1120 nbytes =
Min(nbytes, 4096);
1129 errmsg(
"could not write blocks %u..%u in file \"%s\": %m",
1247 segno =
reln->md_num_open_segs[forknum] - 1;
1248 v = &
reln->md_seg_fds[forknum][segno];
1302 (
errmsg(
"could not truncate file \"%s\" to %u blocks: it's only %u blocks now",
1331 errmsg(
"could not truncate file \"%s\": %m",
1357 errmsg(
"could not truncate file \"%s\" to %u blocks: %m",
1403 MdfdVec *v = &
reln->md_seg_fds[forknum][segno - 1];
1454 MdfdVec *v = &
reln->md_seg_fds[forknum][segno - 1];
1468 errmsg(
"could not fsync file \"%s\": %m",
1521 (
errmsg_internal(
"could not forward fsync request because request queue is full")));
1528 errmsg(
"could not fsync file \"%s\": %m",
1587 rlocator.
dbOid = dbid;
1638 if (
reln->md_num_open_segs[forknum] > 0)
1644 else if (
reln->md_num_open_segs[forknum] == 0)
1646 reln->md_seg_fds[forknum] =
1649 else if (
nseg >
reln->md_num_open_segs[forknum])
1657 reln->md_seg_fds[forknum] =
1672 reln->md_num_open_segs[forknum] =
nseg;
1719 Assert(segno ==
reln->md_num_open_segs[forknum]);
1724 v = &
reln->md_seg_fds[forknum][segno];
1775 if (
reln->md_num_open_segs[forknum] > 0)
1776 v = &
reln->md_seg_fds[forknum][
reln->md_num_open_segs[forknum] - 1];
1845 errmsg(
"could not open file \"%s\" (target block %u): previous segment is only %u blocks",
1859 errmsg(
"could not open file \"%s\" (target block %u): %m",
1880 errmsg(
"could not seek to end of file \"%s\": %m",
2060 errmsg(
"could not read blocks %u..%u in file \"%s\": %m",
2073 errmsg(
"could not read blocks %u..%u in file \"%s\": read only %zu of %zu bytes",
void pgaio_io_set_flag(PgAioHandle *ioh, PgAioHandleFlags flag)
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)
int pgaio_io_get_iovec(PgAioHandle *ioh, struct iovec **iov)
PgAioTargetData * pgaio_io_get_target_data(PgAioHandle *ioh)
void TablespaceCreateDbspace(Oid spcOid, Oid dbOid, bool isRedo)
#define InvalidBlockNumber
#define TYPEALIGN(ALIGNVAL, LEN)
#define Assert(condition)
#define StaticAssertDecl(condition, errmessage)
int errmsg_internal(const char *fmt,...)
int errcode_for_file_access(void)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
int pg_truncate(const char *path, pgoff_t length)
int FileGetRawDesc(File file)
void FileWriteback(File file, pgoff_t offset, pgoff_t nbytes, uint32 wait_event_info)
char * FilePathName(File file)
int FileSync(File file, uint32 wait_event_info)
int FileStartReadV(PgAioHandle *ioh, File file, int iovcnt, pgoff_t offset, uint32 wait_event_info)
ssize_t FileReadV(File file, const struct iovec *iov, int iovcnt, pgoff_t offset, uint32 wait_event_info)
int FileFallocate(File file, pgoff_t offset, pgoff_t amount, uint32 wait_event_info)
pgoff_t FileSize(File file)
void FileClose(File file)
int data_sync_elevel(int elevel)
File PathNameOpenFile(const char *fileName, int fileFlags)
int FileTruncate(File file, pgoff_t offset, uint32 wait_event_info)
int FileZero(File file, pgoff_t offset, pgoff_t amount, uint32 wait_event_info)
int FilePrefetch(File file, pgoff_t offset, pgoff_t amount, uint32 wait_event_info)
ssize_t FileWriteV(File file, const struct iovec *iov, int iovcnt, pgoff_t offset, uint32 wait_event_info)
static ssize_t FileWrite(File file, const void *buffer, size_t amount, pgoff_t offset, uint32 wait_event_info)
#define FILE_POSSIBLY_DELETED(err)
#define palloc_array(type, count)
int compute_remaining_iovec(struct iovec *destination, const struct iovec *source, int iovcnt, size_t transferred)
void * MemoryContextAlloc(MemoryContext context, Size size)
void * repalloc(void *pointer, Size size)
void pfree(void *pointer)
MemoryContext TopMemoryContext
void * palloc_aligned(Size size, Size alignto, int flags)
void mdunlink(RelFileLocatorBackend rlocator, ForkNumber forknum, bool isRedo)
static void md_readv_report(PgAioResult result, const PgAioTargetData *td, int elevel)
static void register_forget_request(RelFileLocatorBackend rlocator, ForkNumber forknum, BlockNumber segno)
#define EXTENSION_CREATE_RECOVERY
void mdtruncate(SMgrRelation reln, ForkNumber forknum, BlockNumber curnblk, BlockNumber nblocks)
static BlockNumber _mdnblocks(SMgrRelation reln, ForkNumber forknum, MdfdVec *seg)
static void mdunlinkfork(RelFileLocatorBackend rlocator, ForkNumber forknum, bool isRedo)
void mdwritev(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, const void **buffers, BlockNumber nblocks, bool skipFsync)
bool mdfiletagmatches(const FileTag *ftag, const FileTag *candidate)
bool mdexists(SMgrRelation reln, ForkNumber forknum)
void mdreadv(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, void **buffers, BlockNumber nblocks)
static MdPathStr _mdfd_segpath(SMgrRelation reln, ForkNumber forknum, BlockNumber segno)
static void register_unlink_segment(RelFileLocatorBackend rlocator, ForkNumber forknum, BlockNumber segno)
#define EXTENSION_DONT_OPEN
BlockNumber mdnblocks(SMgrRelation reln, ForkNumber forknum)
int mdunlinkfiletag(const FileTag *ftag, char *path)
static MemoryContext MdCxt
void mdcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo)
int mdfd(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, uint32 *off)
void mdextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, const void *buffer, bool skipFsync)
static PgAioResult md_readv_complete(PgAioHandle *ioh, PgAioResult prior_result, uint8 cb_data)
static int do_truncate(const char *path)
void mdclose(SMgrRelation reln, ForkNumber forknum)
void mdzeroextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, int nblocks, bool skipFsync)
static MdfdVec * _mdfd_openseg(SMgrRelation reln, ForkNumber forknum, BlockNumber segno, int oflags)
static void register_dirty_segment(SMgrRelation reln, ForkNumber forknum, MdfdVec *seg)
int mdsyncfiletag(const FileTag *ftag, char *path)
void mdwriteback(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, BlockNumber nblocks)
uint32 mdmaxcombine(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum)
static MdfdVec * _mdfd_getseg(SMgrRelation reln, ForkNumber forknum, BlockNumber blkno, bool skipFsync, int behavior)
#define EXTENSION_RETURN_NULL
void mdstartreadv(PgAioHandle *ioh, SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, void **buffers, BlockNumber nblocks)
bool mdprefetch(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, int nblocks)
void mdregistersync(SMgrRelation reln, ForkNumber forknum)
void mdopen(SMgrRelation reln)
const PgAioHandleCallbacks aio_md_readv_cb
static int _mdfd_open_flags(void)
#define INIT_MD_FILETAG(a, xx_rlocator, xx_forknum, xx_segno)
static MdfdVec * mdopenfork(SMgrRelation reln, ForkNumber forknum, int behavior)
void DropRelationFiles(RelFileLocator *delrels, int ndelrels, bool isRedo)
static int buffers_to_iovec(struct iovec *iov, void **buffers, int nblocks)
#define MD_PATH_STR_MAXLEN
static void _fdvec_resize(SMgrRelation reln, ForkNumber forknum, int nseg)
void ForgetDatabaseSyncRequests(Oid dbid)
void mdimmedsync(SMgrRelation reln, ForkNumber forknum)
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
#define ERRCODE_DATA_CORRUPTED
instr_time pgstat_prepare_io_time(bool track_io_guc)
void pgstat_count_io_op_time(IOObject io_object, IOContext io_context, IOOp io_op, instr_time start_time, uint32 cnt, uint64 bytes)
size_t strlcpy(char *dst, const char *src, size_t siz)
static int fd(const char *x, int i)
#define INVALID_PROC_NUMBER
#define RelFileLocatorBackendIsTemp(rlocator)
#define relpath(rlocator, forknum)
#define relpathbackend(rlocator, backend, forknum)
#define relpathperm(rlocator, forknum)
SMgrRelation smgropen(RelFileLocator rlocator, ProcNumber backend)
void smgrclose(SMgrRelation reln)
void smgrdounlinkall(SMgrRelation *rels, int nrels, bool isRedo)
void pgaio_io_set_target_smgr(PgAioHandle *ioh, SMgrRelationData *smgr, ForkNumber forknum, BlockNumber blocknum, int nblocks, bool skip_fsync)
char str[MD_PATH_STR_MAXLEN+1]
PgAioHandleCallbackComplete complete_shared
char str[REL_PATH_STR_MAXLEN+1]
bool RegisterSyncRequest(const FileTag *ftag, SyncRequestType type, bool retryOnError)
struct PgAioTargetData::@126 smgr
void XLogDropRelation(RelFileLocator rlocator, ForkNumber forknum)