Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit b6d8a60

Browse files
committed
Restore pg_pread and friends.
Commits cf112c1 and a0dc827 were a little too hasty in getting rid of the pg_ prefixes where we use pread(), pwrite() and vectored variants. We dropped support for ancient Unixes where we needed to use lseek() to implement replacements for those, but it turns out that Windows also changes the current position even when you pass in an offset to ReadFile() and WriteFile() if the file handle is synchronous, despite its documentation saying otherwise. Switching to asynchronous file handles would fix that, but have other complications. For now let's just put back the pg_ prefix and add some comments to highlight the non-standard side-effect, which we can now describe as Windows-only. Reported-by: Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com> Reviewed-by: Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com> Discussion: https://postgr.es/m/20220923202439.GA1156054%40nathanxps13
1 parent 3a58176 commit b6d8a60

File tree

19 files changed

+75
-55
lines changed

19 files changed

+75
-55
lines changed

contrib/pg_stat_statements/pg_stat_statements.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2103,9 +2103,9 @@ qtext_store(const char *query, int query_len,
21032103
if (fd < 0)
21042104
goto error;
21052105

2106-
if (pwrite(fd, query, query_len, off) != query_len)
2106+
if (pg_pwrite(fd, query, query_len, off) != query_len)
21072107
goto error;
2108-
if (pwrite(fd, "\0", 1, off + query_len) != 1)
2108+
if (pg_pwrite(fd, "\0", 1, off + query_len) != 1)
21092109
goto error;
21102110

21112111
CloseTransientFile(fd);

src/backend/access/heap/rewriteheap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1150,7 +1150,7 @@ heap_xlog_logical_rewrite(XLogReaderState *r)
11501150
/* write out tail end of mapping file (again) */
11511151
errno = 0;
11521152
pgstat_report_wait_start(WAIT_EVENT_LOGICAL_REWRITE_MAPPING_WRITE);
1153-
if (pwrite(fd, data, len, xlrec->offset) != len)
1153+
if (pg_pwrite(fd, data, len, xlrec->offset) != len)
11541154
{
11551155
/* if write didn't set errno, assume problem is no disk space */
11561156
if (errno == 0)

src/backend/access/transam/slru.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,7 @@ SlruPhysicalReadPage(SlruCtl ctl, int pageno, int slotno)
718718

719719
errno = 0;
720720
pgstat_report_wait_start(WAIT_EVENT_SLRU_READ);
721-
if (pread(fd, shared->page_buffer[slotno], BLCKSZ, offset) != BLCKSZ)
721+
if (pg_pread(fd, shared->page_buffer[slotno], BLCKSZ, offset) != BLCKSZ)
722722
{
723723
pgstat_report_wait_end();
724724
slru_errcause = SLRU_READ_FAILED;
@@ -873,7 +873,7 @@ SlruPhysicalWritePage(SlruCtl ctl, int pageno, int slotno, SlruWriteAll fdata)
873873

874874
errno = 0;
875875
pgstat_report_wait_start(WAIT_EVENT_SLRU_WRITE);
876-
if (pwrite(fd, shared->page_buffer[slotno], BLCKSZ, offset) != BLCKSZ)
876+
if (pg_pwrite(fd, shared->page_buffer[slotno], BLCKSZ, offset) != BLCKSZ)
877877
{
878878
pgstat_report_wait_end();
879879
/* if write didn't set errno, assume problem is no disk space */

src/backend/access/transam/xlog.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2196,7 +2196,7 @@ XLogWrite(XLogwrtRqst WriteRqst, TimeLineID tli, bool flexible)
21962196
INSTR_TIME_SET_CURRENT(start);
21972197

21982198
pgstat_report_wait_start(WAIT_EVENT_WAL_WRITE);
2199-
written = pwrite(openLogFile, from, nleft, startoffset);
2199+
written = pg_pwrite(openLogFile, from, nleft, startoffset);
22002200
pgstat_report_wait_end();
22012201

22022202
/*
@@ -3018,7 +3018,7 @@ XLogFileInitInternal(XLogSegNo logsegno, TimeLineID logtli,
30183018
* enough.
30193019
*/
30203020
errno = 0;
3021-
if (pwrite(fd, zbuffer.data, 1, wal_segment_size - 1) != 1)
3021+
if (pg_pwrite(fd, zbuffer.data, 1, wal_segment_size - 1) != 1)
30223022
{
30233023
/* if write didn't set errno, assume no disk space */
30243024
save_errno = errno ? errno : ENOSPC;

src/backend/access/transam/xlogreader.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1544,7 +1544,7 @@ WALRead(XLogReaderState *state,
15441544

15451545
/* Reset errno first; eases reporting non-errno-affecting errors */
15461546
errno = 0;
1547-
readbytes = pread(state->seg.ws_file, p, segbytes, (off_t) startoff);
1547+
readbytes = pg_pread(state->seg.ws_file, p, segbytes, (off_t) startoff);
15481548

15491549
#ifndef FRONTEND
15501550
pgstat_report_wait_end();

src/backend/access/transam/xlogrecovery.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3271,7 +3271,7 @@ XLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen,
32713271
readOff = targetPageOff;
32723272

32733273
pgstat_report_wait_start(WAIT_EVENT_WAL_READ);
3274-
r = pread(readFile, readBuf, XLOG_BLCKSZ, (off_t) readOff);
3274+
r = pg_pread(readFile, readBuf, XLOG_BLCKSZ, (off_t) readOff);
32753275
if (r != XLOG_BLCKSZ)
32763276
{
32773277
char fname[MAXFNAMELEN];

src/backend/backup/basebackup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1828,7 +1828,7 @@ basebackup_read_file(int fd, char *buf, size_t nbytes, off_t offset,
18281828
int rc;
18291829

18301830
pgstat_report_wait_start(WAIT_EVENT_BASEBACKUP_READ);
1831-
rc = pread(fd, buf, nbytes, offset);
1831+
rc = pg_pread(fd, buf, nbytes, offset);
18321832
pgstat_report_wait_end();
18331833

18341834
if (rc < 0)

src/backend/replication/walreceiver.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -915,7 +915,7 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr, TimeLineID tli)
915915
/* OK to write the logs */
916916
errno = 0;
917917

918-
byteswritten = pwrite(recvFile, buf, segbytes, (off_t) startoff);
918+
byteswritten = pg_pwrite(recvFile, buf, segbytes, (off_t) startoff);
919919
if (byteswritten <= 0)
920920
{
921921
char xlogfname[MAXFNAMELEN];

src/backend/storage/file/fd.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2053,7 +2053,7 @@ FileRead(File file, char *buffer, int amount, off_t offset,
20532053

20542054
retry:
20552055
pgstat_report_wait_start(wait_event_info);
2056-
returnCode = pread(vfdP->fd, buffer, amount, offset);
2056+
returnCode = pg_pread(vfdP->fd, buffer, amount, offset);
20572057
pgstat_report_wait_end();
20582058

20592059
if (returnCode < 0)
@@ -2135,7 +2135,7 @@ FileWrite(File file, char *buffer, int amount, off_t offset,
21352135
retry:
21362136
errno = 0;
21372137
pgstat_report_wait_start(wait_event_info);
2138-
returnCode = pwrite(VfdCache[file].fd, buffer, amount, offset);
2138+
returnCode = pg_pwrite(VfdCache[file].fd, buffer, amount, offset);
21392139
pgstat_report_wait_end();
21402140

21412141
/* if write didn't set errno, assume problem is no disk space */
@@ -3740,7 +3740,7 @@ data_sync_elevel(int elevel)
37403740
}
37413741

37423742
/*
3743-
* A convenience wrapper for pwritev() that retries on partial write. If an
3743+
* A convenience wrapper for pg_pwritev() that retries on partial write. If an
37443744
* error is returned, it is unspecified how much has been written.
37453745
*/
37463746
ssize_t
@@ -3760,7 +3760,7 @@ pg_pwritev_with_retry(int fd, const struct iovec *iov, int iovcnt, off_t offset)
37603760
for (;;)
37613761
{
37623762
/* Write as much as we can. */
3763-
part = pwritev(fd, iov, iovcnt, offset);
3763+
part = pg_pwritev(fd, iov, iovcnt, offset);
37643764
if (part < 0)
37653765
return -1;
37663766

src/backend/utils/init/miscinit.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1527,7 +1527,7 @@ AddToDataDirLockFile(int target_line, const char *str)
15271527
len = strlen(destbuffer);
15281528
errno = 0;
15291529
pgstat_report_wait_start(WAIT_EVENT_LOCK_FILE_ADDTODATADIR_WRITE);
1530-
if (pwrite(fd, destbuffer, len, 0) != len)
1530+
if (pg_pwrite(fd, destbuffer, len, 0) != len)
15311531
{
15321532
pgstat_report_wait_end();
15331533
/* if write didn't set errno, assume problem is no disk space */

src/bin/pg_test_fsync/pg_test_fsync.c

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -312,10 +312,10 @@ test_sync(int writes_per_op)
312312
for (ops = 0; alarm_triggered == false; ops++)
313313
{
314314
for (writes = 0; writes < writes_per_op; writes++)
315-
if (pwrite(tmpfile,
316-
buf,
317-
XLOG_BLCKSZ,
318-
writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
315+
if (pg_pwrite(tmpfile,
316+
buf,
317+
XLOG_BLCKSZ,
318+
writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
319319
die("write failed");
320320
}
321321
STOP_TIMER;
@@ -337,10 +337,10 @@ test_sync(int writes_per_op)
337337
for (ops = 0; alarm_triggered == false; ops++)
338338
{
339339
for (writes = 0; writes < writes_per_op; writes++)
340-
if (pwrite(tmpfile,
341-
buf,
342-
XLOG_BLCKSZ,
343-
writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
340+
if (pg_pwrite(tmpfile,
341+
buf,
342+
XLOG_BLCKSZ,
343+
writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
344344
die("write failed");
345345
fdatasync(tmpfile);
346346
}
@@ -359,10 +359,10 @@ test_sync(int writes_per_op)
359359
for (ops = 0; alarm_triggered == false; ops++)
360360
{
361361
for (writes = 0; writes < writes_per_op; writes++)
362-
if (pwrite(tmpfile,
363-
buf,
364-
XLOG_BLCKSZ,
365-
writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
362+
if (pg_pwrite(tmpfile,
363+
buf,
364+
XLOG_BLCKSZ,
365+
writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
366366
die("write failed");
367367
if (fsync(tmpfile) != 0)
368368
die("fsync failed");
@@ -383,10 +383,10 @@ test_sync(int writes_per_op)
383383
for (ops = 0; alarm_triggered == false; ops++)
384384
{
385385
for (writes = 0; writes < writes_per_op; writes++)
386-
if (pwrite(tmpfile,
387-
buf,
388-
XLOG_BLCKSZ,
389-
writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
386+
if (pg_pwrite(tmpfile,
387+
buf,
388+
XLOG_BLCKSZ,
389+
writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
390390
die("write failed");
391391
if (pg_fsync_writethrough(tmpfile) != 0)
392392
die("fsync failed");
@@ -415,10 +415,10 @@ test_sync(int writes_per_op)
415415
for (ops = 0; alarm_triggered == false; ops++)
416416
{
417417
for (writes = 0; writes < writes_per_op; writes++)
418-
if (pwrite(tmpfile,
419-
buf,
420-
XLOG_BLCKSZ,
421-
writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
418+
if (pg_pwrite(tmpfile,
419+
buf,
420+
XLOG_BLCKSZ,
421+
writes * XLOG_BLCKSZ) != XLOG_BLCKSZ)
422422

423423
/*
424424
* This can generate write failures if the filesystem has
@@ -480,10 +480,10 @@ test_open_sync(const char *msg, int writes_size)
480480
for (ops = 0; alarm_triggered == false; ops++)
481481
{
482482
for (writes = 0; writes < 16 / writes_size; writes++)
483-
if (pwrite(tmpfile,
484-
buf,
485-
writes_size * 1024,
486-
writes * writes_size * 1024) !=
483+
if (pg_pwrite(tmpfile,
484+
buf,
485+
writes_size * 1024,
486+
writes * writes_size * 1024) !=
487487
writes_size * 1024)
488488
die("write failed");
489489
}
@@ -582,7 +582,7 @@ test_non_sync(void)
582582
START_TIMER;
583583
for (ops = 0; alarm_triggered == false; ops++)
584584
{
585-
if (pwrite(tmpfile, buf, XLOG_BLCKSZ, 0) != XLOG_BLCKSZ)
585+
if (pg_pwrite(tmpfile, buf, XLOG_BLCKSZ, 0) != XLOG_BLCKSZ)
586586
die("write failed");
587587
}
588588
STOP_TIMER;

src/include/access/xlogreader.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -378,11 +378,11 @@ extern void XLogReaderResetError(XLogReaderState *state);
378378

379379
/*
380380
* Error information from WALRead that both backend and frontend caller can
381-
* process. Currently only errors from pread can be reported.
381+
* process. Currently only errors from pg_pread can be reported.
382382
*/
383383
typedef struct WALReadError
384384
{
385-
int wre_errno; /* errno set by the last pread() */
385+
int wre_errno; /* errno set by the last pg_pread() */
386386
int wre_off; /* Offset we tried to read from. */
387387
int wre_req; /* Bytes requested to be read. */
388388
int wre_read; /* Bytes read by the last read(). */

src/include/port.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,15 @@ extern int pg_fprintf(FILE *stream, const char *fmt,...) pg_attribute_printf(2,
213213
extern int pg_vprintf(const char *fmt, va_list args) pg_attribute_printf(1, 0);
214214
extern int pg_printf(const char *fmt,...) pg_attribute_printf(1, 2);
215215

216+
#ifndef WIN32
217+
/*
218+
* We add a pg_ prefix as a warning that the Windows implementations have the
219+
* non-standard side-effect of changing the current file position.
220+
*/
221+
#define pg_pread pread
222+
#define pg_pwrite pwrite
223+
#endif
224+
216225
/*
217226
* We use __VA_ARGS__ for printf to prevent replacing references to
218227
* the "printf" format archetype in format() attribute declarations.

src/include/port/pg_iovec.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,21 @@ struct iovec
3535
/* Define a reasonable maximum that is safe to use on the stack. */
3636
#define PG_IOV_MAX Min(IOV_MAX, 32)
3737

38-
#if !HAVE_DECL_PREADV
39-
extern ssize_t preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset);
38+
/*
39+
* Note that pg_preadv and pg_writev have a pg_ prefix as a warning that the
40+
* Windows implementations have the side-effect of changing the file position.
41+
*/
42+
43+
#if HAVE_DECL_PREADV
44+
#define pg_preadv preadv
45+
#else
46+
extern ssize_t pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset);
4047
#endif
4148

42-
#if !HAVE_DECL_PWRITEV
43-
extern ssize_t pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset);
49+
#if HAVE_DECL_PWRITEV
50+
#define pg_pwritev pwritev
51+
#else
52+
extern ssize_t pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset);
4453
#endif
4554

4655
#endif /* PG_IOVEC_H */

src/include/port/win32_port.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -564,9 +564,9 @@ typedef unsigned short mode_t;
564564
#endif
565565

566566
/* in port/win32pread.c */
567-
extern ssize_t pread(int fd, void *buf, size_t nbyte, off_t offset);
567+
extern ssize_t pg_pread(int fd, void *buf, size_t nbyte, off_t offset);
568568

569569
/* in port/win32pwrite.c */
570-
extern ssize_t pwrite(int fd, const void *buf, size_t nbyte, off_t offset);
570+
extern ssize_t pg_pwrite(int fd, const void *buf, size_t nbyte, off_t offset);
571571

572572
#endif /* PG_WIN32_PORT_H */

src/port/preadv.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@
1919
#include "port/pg_iovec.h"
2020

2121
ssize_t
22-
preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
22+
pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
2323
{
2424
ssize_t sum = 0;
2525
ssize_t part;
2626

2727
for (int i = 0; i < iovcnt; ++i)
2828
{
29-
part = pread(fd, iov[i].iov_base, iov[i].iov_len, offset);
29+
part = pg_pread(fd, iov[i].iov_base, iov[i].iov_len, offset);
3030
if (part < 0)
3131
{
3232
if (i == 0)

src/port/pwritev.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@
1919
#include "port/pg_iovec.h"
2020

2121
ssize_t
22-
pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
22+
pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
2323
{
2424
ssize_t sum = 0;
2525
ssize_t part;
2626

2727
for (int i = 0; i < iovcnt; ++i)
2828
{
29-
part = pwrite(fd, iov[i].iov_base, iov[i].iov_len, offset);
29+
part = pg_pwrite(fd, iov[i].iov_base, iov[i].iov_len, offset);
3030
if (part < 0)
3131
{
3232
if (i == 0)

src/port/win32pread.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#include <windows.h>
1818

1919
ssize_t
20-
pread(int fd, void *buf, size_t size, off_t offset)
20+
pg_pread(int fd, void *buf, size_t size, off_t offset)
2121
{
2222
OVERLAPPED overlapped = {0};
2323
HANDLE handle;
@@ -30,6 +30,7 @@ pread(int fd, void *buf, size_t size, off_t offset)
3030
return -1;
3131
}
3232

33+
/* Note that this changes the file position, despite not using it. */
3334
overlapped.Offset = offset;
3435
if (!ReadFile(handle, buf, size, &result, &overlapped))
3536
{

src/port/win32pwrite.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#include <windows.h>
1818

1919
ssize_t
20-
pwrite(int fd, const void *buf, size_t size, off_t offset)
20+
pg_pwrite(int fd, const void *buf, size_t size, off_t offset)
2121
{
2222
OVERLAPPED overlapped = {0};
2323
HANDLE handle;
@@ -30,6 +30,7 @@ pwrite(int fd, const void *buf, size_t size, off_t offset)
3030
return -1;
3131
}
3232

33+
/* Note that this changes the file position, despite not using it. */
3334
overlapped.Offset = offset;
3435
if (!WriteFile(handle, buf, size, &result, &overlapped))
3536
{

0 commit comments

Comments
 (0)