diff options
| author | Michael Paquier | 2025-11-13 03:41:40 +0000 |
|---|---|---|
| committer | Michael Paquier | 2025-11-13 03:41:40 +0000 |
| commit | 84fb27511dbeaa0fb0d48249083d71f6cbbd4b98 (patch) | |
| tree | 48b648a79136eff087d322cc8f7099c24a832455 /src | |
| parent | 705601c5aeab56aef62dd69ac2b7acf662f08e9c (diff) | |
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.c | 2 | ||||
| -rw-r--r-- | src/backend/access/transam/xlogrecovery.c | 2 | ||||
| -rw-r--r-- | src/backend/replication/walreceiver.c | 2 | ||||
| -rw-r--r-- | src/backend/storage/file/fd.c | 36 | ||||
| -rw-r--r-- | src/backend/storage/smgr/md.c | 50 | ||||
| -rw-r--r-- | src/common/file_utils.c | 4 | ||||
| -rw-r--r-- | src/include/common/file_utils.h | 4 | ||||
| -rw-r--r-- | src/include/port/pg_iovec.h | 4 | ||||
| -rw-r--r-- | src/include/port/win32_port.h | 4 | ||||
| -rw-r--r-- | src/include/storage/fd.h | 26 | ||||
| -rw-r--r-- | src/port/win32pread.c | 6 | ||||
| -rw-r--r-- | src/port/win32pwrite.c | 6 | ||||
| -rw-r--r-- | src/tools/pgindent/typedefs.list | 1 |
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 |
