summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Paquier2025-11-13 03:41:40 +0000
committerMichael Paquier2025-11-13 03:41:40 +0000
commit84fb27511dbeaa0fb0d48249083d71f6cbbd4b98 (patch)
tree48b648a79136eff087d322cc8f7099c24a832455 /src
parent705601c5aeab56aef62dd69ac2b7acf662f08e9c (diff)
Replace off_t by pgoff_t in I/O routinesHEADmaster
PostgreSQL's Windows port has never been able to handle files larger than 2GB due to the use of off_t for file offsets, only 32-bit on Windows. This causes signed integer overflow at exactly 2^31 bytes when trying to handle files larger than 2GB, for the routines touched by this commit. Note that large files are forbidden by ./configure (3c6248a828af) and meson (recent change, see 79cd66f28c65). This restriction also exists in v16 and older versions for the now-dead MSVC scripts. The code base already defines pgoff_t as __int64 (64-bit) on Windows for this purpose, and some function declarations in headers use it, but many internals still rely on off_t. This commit switches more routines to use pgoff_t, offering more portability, for areas mainly related to file extensions and storage. These are not critical for WAL segments yet, which have currently a maximum size allowed of 1GB (well, this opens the door at allowing a larger size for them). This matters more for segment files if we want to lift the large file restriction in ./configure and meson in the future, which would make sense to remove once/if all traces of off_t are gone from the tree. This can additionally matter for out-of-core code that may want files larger than 2GB in places where off_t is four bytes in size. Note that off_t is still used in other parts of the tree like buffile.c, WAL sender/receiver, base backup, pg_combinebackup, etc. These other code paths can be addressed separately, and their update will be required if we want to remove the large file restriction in the future. This commit is a good first cut in itself towards more portability, hopefully. On Unix-like systems, pgoff_t is defined as off_t, so this change only affects Windows behavior. Author: Bryan Green <[email protected]> Reviewed-by: Thomas Munro <[email protected]> Reviewed-by: Michael Paquier <[email protected]> Discussion: https://postgr.es/m/[email protected]
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/transam/xlogreader.c2
-rw-r--r--src/backend/access/transam/xlogrecovery.c2
-rw-r--r--src/backend/replication/walreceiver.c2
-rw-r--r--src/backend/storage/file/fd.c36
-rw-r--r--src/backend/storage/smgr/md.c50
-rw-r--r--src/common/file_utils.c4
-rw-r--r--src/include/common/file_utils.h4
-rw-r--r--src/include/port/pg_iovec.h4
-rw-r--r--src/include/port/win32_port.h4
-rw-r--r--src/include/storage/fd.h26
-rw-r--r--src/port/win32pread.c6
-rw-r--r--src/port/win32pwrite.c6
-rw-r--r--src/tools/pgindent/typedefs.list1
13 files changed, 76 insertions, 71 deletions
diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c
index 755f351143a..9cc7488e892 100644
--- a/src/backend/access/transam/xlogreader.c
+++ b/src/backend/access/transam/xlogreader.c
@@ -1574,7 +1574,7 @@ WALRead(XLogReaderState *state,
/* Reset errno first; eases reporting non-errno-affecting errors */
errno = 0;
- readbytes = pg_pread(state->seg.ws_file, p, segbytes, (off_t) startoff);
+ readbytes = pg_pread(state->seg.ws_file, p, segbytes, (pgoff_t) startoff);
#ifndef FRONTEND
pgstat_report_wait_end();
diff --git a/src/backend/access/transam/xlogrecovery.c b/src/backend/access/transam/xlogrecovery.c
index eddc22fc5ad..21b8f179ba0 100644
--- a/src/backend/access/transam/xlogrecovery.c
+++ b/src/backend/access/transam/xlogrecovery.c
@@ -3429,7 +3429,7 @@ retry:
io_start = pgstat_prepare_io_time(track_wal_io_timing);
pgstat_report_wait_start(WAIT_EVENT_WAL_READ);
- r = pg_pread(readFile, readBuf, XLOG_BLCKSZ, (off_t) readOff);
+ r = pg_pread(readFile, readBuf, XLOG_BLCKSZ, (pgoff_t) readOff);
if (r != XLOG_BLCKSZ)
{
char fname[MAXFNAMELEN];
diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c
index 2ee8fecee26..4217fc54e2e 100644
--- a/src/backend/replication/walreceiver.c
+++ b/src/backend/replication/walreceiver.c
@@ -928,7 +928,7 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr, TimeLineID tli)
start = pgstat_prepare_io_time(track_wal_io_timing);
pgstat_report_wait_start(WAIT_EVENT_WAL_WRITE);
- byteswritten = pg_pwrite(recvFile, buf, segbytes, (off_t) startoff);
+ byteswritten = pg_pwrite(recvFile, buf, segbytes, (pgoff_t) startoff);
pgstat_report_wait_end();
pgstat_count_io_op_time(IOOBJECT_WAL, IOCONTEXT_NORMAL,
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index a4ec7959f31..e9eaaf9c829 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -201,7 +201,7 @@ typedef struct vfd
File nextFree; /* link to next free VFD, if in freelist */
File lruMoreRecently; /* doubly linked recency-of-use list */
File lruLessRecently;
- off_t fileSize; /* current size of file (0 if not temporary) */
+ pgoff_t fileSize; /* current size of file (0 if not temporary) */
char *fileName; /* name of file, or NULL for unused VFD */
/* NB: fileName is malloc'd, and must be free'd when closing the VFD */
int fileFlags; /* open(2) flags for (re)opening the file */
@@ -519,7 +519,7 @@ pg_file_exists(const char *name)
* offset of 0 with nbytes 0 means that the entire file should be flushed
*/
void
-pg_flush_data(int fd, off_t offset, off_t nbytes)
+pg_flush_data(int fd, pgoff_t offset, pgoff_t nbytes)
{
/*
* Right now file flushing is primarily used to avoid making later
@@ -635,7 +635,7 @@ retry:
* may simply not be enough address space. If so, silently fall
* through to the next implementation.
*/
- if (nbytes <= (off_t) SSIZE_MAX)
+ if (nbytes <= (pgoff_t) SSIZE_MAX)
p = mmap(NULL, nbytes, PROT_READ, MAP_SHARED, fd, offset);
else
p = MAP_FAILED;
@@ -697,7 +697,7 @@ retry:
* Truncate an open file to a given length.
*/
static int
-pg_ftruncate(int fd, off_t length)
+pg_ftruncate(int fd, pgoff_t length)
{
int ret;
@@ -714,7 +714,7 @@ retry:
* Truncate a file to a given length by name.
*/
int
-pg_truncate(const char *path, off_t length)
+pg_truncate(const char *path, pgoff_t length)
{
int ret;
#ifdef WIN32
@@ -1526,7 +1526,7 @@ FileAccess(File file)
* Called whenever a temporary file is deleted to report its size.
*/
static void
-ReportTemporaryFileUsage(const char *path, off_t size)
+ReportTemporaryFileUsage(const char *path, pgoff_t size)
{
pgstat_report_tempfile(size);
@@ -2077,7 +2077,7 @@ FileClose(File file)
* this.
*/
int
-FilePrefetch(File file, off_t offset, off_t amount, uint32 wait_event_info)
+FilePrefetch(File file, pgoff_t offset, pgoff_t amount, uint32 wait_event_info)
{
Assert(FileIsValid(file));
@@ -2133,7 +2133,7 @@ retry:
}
void
-FileWriteback(File file, off_t offset, off_t nbytes, uint32 wait_event_info)
+FileWriteback(File file, pgoff_t offset, pgoff_t nbytes, uint32 wait_event_info)
{
int returnCode;
@@ -2159,7 +2159,7 @@ FileWriteback(File file, off_t offset, off_t nbytes, uint32 wait_event_info)
}
ssize_t
-FileReadV(File file, const struct iovec *iov, int iovcnt, off_t offset,
+FileReadV(File file, const struct iovec *iov, int iovcnt, pgoff_t offset,
uint32 wait_event_info)
{
ssize_t returnCode;
@@ -2216,7 +2216,7 @@ retry:
int
FileStartReadV(PgAioHandle *ioh, File file,
- int iovcnt, off_t offset,
+ int iovcnt, pgoff_t offset,
uint32 wait_event_info)
{
int returnCode;
@@ -2241,7 +2241,7 @@ FileStartReadV(PgAioHandle *ioh, File file,
}
ssize_t
-FileWriteV(File file, const struct iovec *iov, int iovcnt, off_t offset,
+FileWriteV(File file, const struct iovec *iov, int iovcnt, pgoff_t offset,
uint32 wait_event_info)
{
ssize_t returnCode;
@@ -2270,7 +2270,7 @@ FileWriteV(File file, const struct iovec *iov, int iovcnt, off_t offset,
*/
if (temp_file_limit >= 0 && (vfdP->fdstate & FD_TEMP_FILE_LIMIT))
{
- off_t past_write = offset;
+ pgoff_t past_write = offset;
for (int i = 0; i < iovcnt; ++i)
past_write += iov[i].iov_len;
@@ -2309,7 +2309,7 @@ retry:
*/
if (vfdP->fdstate & FD_TEMP_FILE_LIMIT)
{
- off_t past_write = offset + returnCode;
+ pgoff_t past_write = offset + returnCode;
if (past_write > vfdP->fileSize)
{
@@ -2373,7 +2373,7 @@ FileSync(File file, uint32 wait_event_info)
* appropriate error.
*/
int
-FileZero(File file, off_t offset, off_t amount, uint32 wait_event_info)
+FileZero(File file, pgoff_t offset, pgoff_t amount, uint32 wait_event_info)
{
int returnCode;
ssize_t written;
@@ -2418,7 +2418,7 @@ FileZero(File file, off_t offset, off_t amount, uint32 wait_event_info)
* appropriate error.
*/
int
-FileFallocate(File file, off_t offset, off_t amount, uint32 wait_event_info)
+FileFallocate(File file, pgoff_t offset, pgoff_t amount, uint32 wait_event_info)
{
#ifdef HAVE_POSIX_FALLOCATE
int returnCode;
@@ -2457,7 +2457,7 @@ retry:
return FileZero(file, offset, amount, wait_event_info);
}
-off_t
+pgoff_t
FileSize(File file)
{
Assert(FileIsValid(file));
@@ -2468,14 +2468,14 @@ FileSize(File file)
if (FileIsNotOpen(file))
{
if (FileAccess(file) < 0)
- return (off_t) -1;
+ return (pgoff_t) -1;
}
return lseek(VfdCache[file].fd, 0, SEEK_END);
}
int
-FileTruncate(File file, off_t offset, uint32 wait_event_info)
+FileTruncate(File file, pgoff_t offset, uint32 wait_event_info)
{
int returnCode;
diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c
index 235ba7e1914..e3f335a8340 100644
--- a/src/backend/storage/smgr/md.c
+++ b/src/backend/storage/smgr/md.c
@@ -487,7 +487,7 @@ void
mdextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
const void *buffer, bool skipFsync)
{
- off_t seekpos;
+ pgoff_t seekpos;
int nbytes;
MdfdVec *v;
@@ -515,9 +515,9 @@ mdextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
v = _mdfd_getseg(reln, forknum, blocknum, skipFsync, EXTENSION_CREATE);
- seekpos = (off_t) BLCKSZ * (blocknum % ((BlockNumber) RELSEG_SIZE));
+ seekpos = (pgoff_t) BLCKSZ * (blocknum % ((BlockNumber) RELSEG_SIZE));
- Assert(seekpos < (off_t) BLCKSZ * RELSEG_SIZE);
+ Assert(seekpos < (pgoff_t) BLCKSZ * RELSEG_SIZE);
if ((nbytes = FileWrite(v->mdfd_vfd, buffer, BLCKSZ, seekpos, WAIT_EVENT_DATA_FILE_EXTEND)) != BLCKSZ)
{
@@ -578,7 +578,7 @@ mdzeroextend(SMgrRelation reln, ForkNumber forknum,
while (remblocks > 0)
{
BlockNumber segstartblock = curblocknum % ((BlockNumber) RELSEG_SIZE);
- off_t seekpos = (off_t) BLCKSZ * segstartblock;
+ pgoff_t seekpos = (pgoff_t) BLCKSZ * segstartblock;
int numblocks;
if (segstartblock + remblocks > RELSEG_SIZE)
@@ -607,7 +607,7 @@ mdzeroextend(SMgrRelation reln, ForkNumber forknum,
int ret;
ret = FileFallocate(v->mdfd_vfd,
- seekpos, (off_t) BLCKSZ * numblocks,
+ seekpos, (pgoff_t) BLCKSZ * numblocks,
WAIT_EVENT_DATA_FILE_EXTEND);
if (ret != 0)
{
@@ -630,7 +630,7 @@ mdzeroextend(SMgrRelation reln, ForkNumber forknum,
* whole length of the extension.
*/
ret = FileZero(v->mdfd_vfd,
- seekpos, (off_t) BLCKSZ * numblocks,
+ seekpos, (pgoff_t) BLCKSZ * numblocks,
WAIT_EVENT_DATA_FILE_EXTEND);
if (ret < 0)
ereport(ERROR,
@@ -745,7 +745,7 @@ mdprefetch(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
while (nblocks > 0)
{
- off_t seekpos;
+ pgoff_t seekpos;
MdfdVec *v;
int nblocks_this_segment;
@@ -754,9 +754,9 @@ mdprefetch(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
if (v == NULL)
return false;
- seekpos = (off_t) BLCKSZ * (blocknum % ((BlockNumber) RELSEG_SIZE));
+ seekpos = (pgoff_t) BLCKSZ * (blocknum % ((BlockNumber) RELSEG_SIZE));
- Assert(seekpos < (off_t) BLCKSZ * RELSEG_SIZE);
+ Assert(seekpos < (pgoff_t) BLCKSZ * RELSEG_SIZE);
nblocks_this_segment =
Min(nblocks,
@@ -851,7 +851,7 @@ mdreadv(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
{
struct iovec iov[PG_IOV_MAX];
int iovcnt;
- off_t seekpos;
+ pgoff_t seekpos;
int nbytes;
MdfdVec *v;
BlockNumber nblocks_this_segment;
@@ -861,9 +861,9 @@ mdreadv(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
v = _mdfd_getseg(reln, forknum, blocknum, false,
EXTENSION_FAIL | EXTENSION_CREATE_RECOVERY);
- seekpos = (off_t) BLCKSZ * (blocknum % ((BlockNumber) RELSEG_SIZE));
+ seekpos = (pgoff_t) BLCKSZ * (blocknum % ((BlockNumber) RELSEG_SIZE));
- Assert(seekpos < (off_t) BLCKSZ * RELSEG_SIZE);
+ Assert(seekpos < (pgoff_t) BLCKSZ * RELSEG_SIZE);
nblocks_this_segment =
Min(nblocks,
@@ -986,7 +986,7 @@ mdstartreadv(PgAioHandle *ioh,
SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
void **buffers, BlockNumber nblocks)
{
- off_t seekpos;
+ pgoff_t seekpos;
MdfdVec *v;
BlockNumber nblocks_this_segment;
struct iovec *iov;
@@ -996,9 +996,9 @@ mdstartreadv(PgAioHandle *ioh,
v = _mdfd_getseg(reln, forknum, blocknum, false,
EXTENSION_FAIL | EXTENSION_CREATE_RECOVERY);
- seekpos = (off_t) BLCKSZ * (blocknum % ((BlockNumber) RELSEG_SIZE));
+ seekpos = (pgoff_t) BLCKSZ * (blocknum % ((BlockNumber) RELSEG_SIZE));
- Assert(seekpos < (off_t) BLCKSZ * RELSEG_SIZE);
+ Assert(seekpos < (pgoff_t) BLCKSZ * RELSEG_SIZE);
nblocks_this_segment =
Min(nblocks,
@@ -1068,7 +1068,7 @@ mdwritev(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
{
struct iovec iov[PG_IOV_MAX];
int iovcnt;
- off_t seekpos;
+ pgoff_t seekpos;
int nbytes;
MdfdVec *v;
BlockNumber nblocks_this_segment;
@@ -1078,9 +1078,9 @@ mdwritev(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
v = _mdfd_getseg(reln, forknum, blocknum, skipFsync,
EXTENSION_FAIL | EXTENSION_CREATE_RECOVERY);
- seekpos = (off_t) BLCKSZ * (blocknum % ((BlockNumber) RELSEG_SIZE));
+ seekpos = (pgoff_t) BLCKSZ * (blocknum % ((BlockNumber) RELSEG_SIZE));
- Assert(seekpos < (off_t) BLCKSZ * RELSEG_SIZE);
+ Assert(seekpos < (pgoff_t) BLCKSZ * RELSEG_SIZE);
nblocks_this_segment =
Min(nblocks,
@@ -1173,7 +1173,7 @@ mdwriteback(SMgrRelation reln, ForkNumber forknum,
while (nblocks > 0)
{
BlockNumber nflush = nblocks;
- off_t seekpos;
+ pgoff_t seekpos;
MdfdVec *v;
int segnum_start,
segnum_end;
@@ -1202,9 +1202,9 @@ mdwriteback(SMgrRelation reln, ForkNumber forknum,
Assert(nflush >= 1);
Assert(nflush <= nblocks);
- seekpos = (off_t) BLCKSZ * (blocknum % ((BlockNumber) RELSEG_SIZE));
+ seekpos = (pgoff_t) BLCKSZ * (blocknum % ((BlockNumber) RELSEG_SIZE));
- FileWriteback(v->mdfd_vfd, seekpos, (off_t) BLCKSZ * nflush, WAIT_EVENT_DATA_FILE_FLUSH);
+ FileWriteback(v->mdfd_vfd, seekpos, (pgoff_t) BLCKSZ * nflush, WAIT_EVENT_DATA_FILE_FLUSH);
nblocks -= nflush;
blocknum += nflush;
@@ -1348,7 +1348,7 @@ mdtruncate(SMgrRelation reln, ForkNumber forknum,
*/
BlockNumber lastsegblocks = nblocks - priorblocks;
- if (FileTruncate(v->mdfd_vfd, (off_t) lastsegblocks * BLCKSZ, WAIT_EVENT_DATA_FILE_TRUNCATE) < 0)
+ if (FileTruncate(v->mdfd_vfd, (pgoff_t) lastsegblocks * BLCKSZ, WAIT_EVENT_DATA_FILE_TRUNCATE) < 0)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not truncate file \"%s\" to %u blocks: %m",
@@ -1484,9 +1484,9 @@ mdfd(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, uint32 *off)
v = _mdfd_getseg(reln, forknum, blocknum, false,
EXTENSION_FAIL);
- *off = (off_t) BLCKSZ * (blocknum % ((BlockNumber) RELSEG_SIZE));
+ *off = (pgoff_t) BLCKSZ * (blocknum % ((BlockNumber) RELSEG_SIZE));
- Assert(*off < (off_t) BLCKSZ * RELSEG_SIZE);
+ Assert(*off < (pgoff_t) BLCKSZ * RELSEG_SIZE);
return FileGetRawDesc(v->mdfd_vfd);
}
@@ -1868,7 +1868,7 @@ _mdfd_getseg(SMgrRelation reln, ForkNumber forknum, BlockNumber blkno,
static BlockNumber
_mdnblocks(SMgrRelation reln, ForkNumber forknum, MdfdVec *seg)
{
- off_t len;
+ pgoff_t len;
len = FileSize(seg->mdfd_vfd);
if (len < 0)
diff --git a/src/common/file_utils.c b/src/common/file_utils.c
index 7b62687a2aa..cdf08ab5cbc 100644
--- a/src/common/file_utils.c
+++ b/src/common/file_utils.c
@@ -656,7 +656,7 @@ compute_remaining_iovec(struct iovec *destination,
* error is returned, it is unspecified how much has been written.
*/
ssize_t
-pg_pwritev_with_retry(int fd, const struct iovec *iov, int iovcnt, off_t offset)
+pg_pwritev_with_retry(int fd, const struct iovec *iov, int iovcnt, pgoff_t offset)
{
struct iovec iov_copy[PG_IOV_MAX];
ssize_t sum = 0;
@@ -706,7 +706,7 @@ pg_pwritev_with_retry(int fd, const struct iovec *iov, int iovcnt, off_t offset)
* is returned with errno set.
*/
ssize_t
-pg_pwrite_zeros(int fd, size_t size, off_t offset)
+pg_pwrite_zeros(int fd, size_t size, pgoff_t offset)
{
static const PGIOAlignedBlock zbuffer = {0}; /* worth BLCKSZ */
void *zerobuf_addr = unconstify(PGIOAlignedBlock *, &zbuffer)->data;
diff --git a/src/include/common/file_utils.h b/src/include/common/file_utils.h
index 9fd88953e43..42397138037 100644
--- a/src/include/common/file_utils.h
+++ b/src/include/common/file_utils.h
@@ -55,9 +55,9 @@ extern int compute_remaining_iovec(struct iovec *destination,
extern ssize_t pg_pwritev_with_retry(int fd,
const struct iovec *iov,
int iovcnt,
- off_t offset);
+ pgoff_t offset);
-extern ssize_t pg_pwrite_zeros(int fd, size_t size, off_t offset);
+extern ssize_t pg_pwrite_zeros(int fd, size_t size, pgoff_t offset);
/* Filename components */
#define PG_TEMP_FILES_DIR "pgsql_tmp"
diff --git a/src/include/port/pg_iovec.h b/src/include/port/pg_iovec.h
index 90be3af449d..845ded8c71e 100644
--- a/src/include/port/pg_iovec.h
+++ b/src/include/port/pg_iovec.h
@@ -51,7 +51,7 @@ struct iovec
* this changes the current file position.
*/
static inline ssize_t
-pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
+pg_preadv(int fd, const struct iovec *iov, int iovcnt, pgoff_t offset)
{
#if HAVE_DECL_PREADV
/*
@@ -90,7 +90,7 @@ pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
* this changes the current file position.
*/
static inline ssize_t
-pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
+pg_pwritev(int fd, const struct iovec *iov, int iovcnt, pgoff_t offset)
{
#if HAVE_DECL_PWRITEV
/*
diff --git a/src/include/port/win32_port.h b/src/include/port/win32_port.h
index ff7028bdc81..f54ccef7db8 100644
--- a/src/include/port/win32_port.h
+++ b/src/include/port/win32_port.h
@@ -584,9 +584,9 @@ typedef unsigned short mode_t;
#endif
/* in port/win32pread.c */
-extern ssize_t pg_pread(int fd, void *buf, size_t nbyte, off_t offset);
+extern ssize_t pg_pread(int fd, void *buf, size_t nbyte, pgoff_t offset);
/* in port/win32pwrite.c */
-extern ssize_t pg_pwrite(int fd, const void *buf, size_t nbyte, off_t offset);
+extern ssize_t pg_pwrite(int fd, const void *buf, size_t nbyte, pgoff_t offset);
#endif /* PG_WIN32_PORT_H */
diff --git a/src/include/storage/fd.h b/src/include/storage/fd.h
index b77d8e5e30e..3e821ce8fb7 100644
--- a/src/include/storage/fd.h
+++ b/src/include/storage/fd.h
@@ -108,17 +108,17 @@ extern File PathNameOpenFile(const char *fileName, int fileFlags);
extern File PathNameOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode);
extern File OpenTemporaryFile(bool interXact);
extern void FileClose(File file);
-extern int FilePrefetch(File file, off_t offset, off_t amount, uint32 wait_event_info);
-extern ssize_t FileReadV(File file, const struct iovec *iov, int iovcnt, off_t offset, uint32 wait_event_info);
-extern ssize_t FileWriteV(File file, const struct iovec *iov, int iovcnt, off_t offset, uint32 wait_event_info);
-extern int FileStartReadV(struct PgAioHandle *ioh, File file, int iovcnt, off_t offset, uint32 wait_event_info);
+extern int FilePrefetch(File file, pgoff_t offset, pgoff_t amount, uint32 wait_event_info);
+extern ssize_t FileReadV(File file, const struct iovec *iov, int iovcnt, pgoff_t offset, uint32 wait_event_info);
+extern ssize_t FileWriteV(File file, const struct iovec *iov, int iovcnt, pgoff_t offset, uint32 wait_event_info);
+extern int FileStartReadV(struct PgAioHandle *ioh, File file, int iovcnt, pgoff_t offset, uint32 wait_event_info);
extern int FileSync(File file, uint32 wait_event_info);
-extern int FileZero(File file, off_t offset, off_t amount, uint32 wait_event_info);
-extern int FileFallocate(File file, off_t offset, off_t amount, uint32 wait_event_info);
+extern int FileZero(File file, pgoff_t offset, pgoff_t amount, uint32 wait_event_info);
+extern int FileFallocate(File file, pgoff_t offset, pgoff_t amount, uint32 wait_event_info);
-extern off_t FileSize(File file);
-extern int FileTruncate(File file, off_t offset, uint32 wait_event_info);
-extern void FileWriteback(File file, off_t offset, off_t nbytes, uint32 wait_event_info);
+extern pgoff_t FileSize(File file);
+extern int FileTruncate(File file, pgoff_t offset, uint32 wait_event_info);
+extern void FileWriteback(File file, pgoff_t offset, pgoff_t nbytes, uint32 wait_event_info);
extern char *FilePathName(File file);
extern int FileGetRawDesc(File file);
extern int FileGetRawFlags(File file);
@@ -186,8 +186,8 @@ extern int pg_fsync_no_writethrough(int fd);
extern int pg_fsync_writethrough(int fd);
extern int pg_fdatasync(int fd);
extern bool pg_file_exists(const char *name);
-extern void pg_flush_data(int fd, off_t offset, off_t nbytes);
-extern int pg_truncate(const char *path, off_t length);
+extern void pg_flush_data(int fd, pgoff_t offset, pgoff_t nbytes);
+extern int pg_truncate(const char *path, pgoff_t length);
extern void fsync_fname(const char *fname, bool isdir);
extern int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel);
extern int durable_rename(const char *oldfile, const char *newfile, int elevel);
@@ -196,7 +196,7 @@ extern void SyncDataDirectory(void);
extern int data_sync_elevel(int elevel);
static inline ssize_t
-FileRead(File file, void *buffer, size_t amount, off_t offset,
+FileRead(File file, void *buffer, size_t amount, pgoff_t offset,
uint32 wait_event_info)
{
struct iovec iov = {
@@ -208,7 +208,7 @@ FileRead(File file, void *buffer, size_t amount, off_t offset,
}
static inline ssize_t
-FileWrite(File file, const void *buffer, size_t amount, off_t offset,
+FileWrite(File file, const void *buffer, size_t amount, pgoff_t offset,
uint32 wait_event_info)
{
struct iovec iov = {
diff --git a/src/port/win32pread.c b/src/port/win32pread.c
index 32d56c462ec..857a55e781d 100644
--- a/src/port/win32pread.c
+++ b/src/port/win32pread.c
@@ -17,7 +17,7 @@
#include <windows.h>
ssize_t
-pg_pread(int fd, void *buf, size_t size, off_t offset)
+pg_pread(int fd, void *buf, size_t size, pgoff_t offset)
{
OVERLAPPED overlapped = {0};
HANDLE handle;
@@ -34,7 +34,9 @@ pg_pread(int fd, void *buf, size_t size, off_t offset)
size = Min(size, 1024 * 1024 * 1024);
/* Note that this changes the file position, despite not using it. */
- overlapped.Offset = offset;
+ overlapped.Offset = (DWORD) offset;
+ overlapped.OffsetHigh = (DWORD) (offset >> 32);
+
if (!ReadFile(handle, buf, size, &result, &overlapped))
{
if (GetLastError() == ERROR_HANDLE_EOF)
diff --git a/src/port/win32pwrite.c b/src/port/win32pwrite.c
index 249aa6c4685..8085c00e38e 100644
--- a/src/port/win32pwrite.c
+++ b/src/port/win32pwrite.c
@@ -17,7 +17,7 @@
#include <windows.h>
ssize_t
-pg_pwrite(int fd, const void *buf, size_t size, off_t offset)
+pg_pwrite(int fd, const void *buf, size_t size, pgoff_t offset)
{
OVERLAPPED overlapped = {0};
HANDLE handle;
@@ -34,7 +34,9 @@ pg_pwrite(int fd, const void *buf, size_t size, off_t offset)
size = Min(size, 1024 * 1024 * 1024);
/* Note that this changes the file position, despite not using it. */
- overlapped.Offset = offset;
+ overlapped.Offset = (DWORD) offset;
+ overlapped.OffsetHigh = (DWORD) (offset >> 32);
+
if (!WriteFile(handle, buf, size, &result, &overlapped))
{
_dosmaperr(GetLastError());
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index 432509277c9..23bce72ae64 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -3860,6 +3860,7 @@ pe_test_vector
pendingPosition
pending_label
pgParameterStatus
+pgoff_t
pg_atomic_flag
pg_atomic_uint32
pg_atomic_uint64