read-errno-handling.patch
text/x-diff
Filename: read-errno-handling.patch
Type: text/x-diff
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/access/transam/slru.c | 5 | 0 |
| src/backend/access/transam/twophase.c | 19 | 5 |
| src/backend/access/transam/xlog.c | 28 | 9 |
| src/backend/replication/logical/origin.c | 10 | 3 |
| src/backend/replication/slot.c | 17 | 9 |
| src/backend/utils/cache/relmapper.c | 14 | 5 |
| src/bin/pg_rewind/file_ops.c | 12 | 3 |
| src/bin/pg_rewind/parsexlog.c | 11 | 3 |
| src/bin/pg_waldump/pg_waldump.c | 5 | 2 |
diff --git a/src/backend/access/transam/slru.c b/src/backend/access/transam/slru.c
index 87942b4cca..d487347cc6 100644
--- a/src/backend/access/transam/slru.c
+++ b/src/backend/access/transam/slru.c
@@ -683,6 +683,11 @@ SlruPhysicalReadPage(SlruCtl ctl, int pageno, int slotno)
pgstat_report_wait_start(WAIT_EVENT_SLRU_READ);
if (read(fd, shared->page_buffer[slotno], BLCKSZ) != BLCKSZ)
{
+ /*
+ * XXX: Note that this may actually report sucess if the number
+ * of bytes read is positive, but lacking data so that errno is
+ * not set.
+ */
pgstat_report_wait_end();
slru_errcause = SLRU_READ_FAILED;
slru_errno = errno;
diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c
index 65194db70e..52f634e706 100644
--- a/src/backend/access/transam/twophase.c
+++ b/src/backend/access/transam/twophase.c
@@ -1219,6 +1219,7 @@ ReadTwoPhaseFile(TransactionId xid, bool give_warnings)
uint32 crc_offset;
pg_crc32c calc_crc,
file_crc;
+ int r;
TwoPhaseFilePath(path, xid);
@@ -1272,15 +1273,28 @@ ReadTwoPhaseFile(TransactionId xid, bool give_warnings)
buf = (char *) palloc(stat.st_size);
pgstat_report_wait_start(WAIT_EVENT_TWOPHASE_FILE_READ);
- if (read(fd, buf, stat.st_size) != stat.st_size)
+ r = read(fd, buf, stat.st_size);
+ if (r != stat.st_size)
{
+ int save_errno = errno;
+
pgstat_report_wait_end();
CloseTransientFile(fd);
if (give_warnings)
- ereport(WARNING,
- (errcode_for_file_access(),
- errmsg("could not read two-phase state file \"%s\": %m",
- path)));
+ {
+ if (r < 0)
+ {
+ errno = save_errno;
+ ereport(WARNING,
+ (errcode_for_file_access(),
+ errmsg("could not read two-phase state file \"%s\": %m",
+ path)));
+ }
+ else
+ ereport(WARNING,
+ (errmsg("could not read two-phase state file \"%s\": %d read, expected %zu",
+ path, r, stat.st_size)));
+ }
pfree(buf);
return NULL;
}
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index adbd6a2126..72fd800646 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -3395,21 +3395,24 @@ XLogFileCopy(XLogSegNo destsegno, TimeLineID srcTLI, XLogSegNo srcsegno,
if (nread > 0)
{
+ int r;
+
if (nread > sizeof(buffer))
nread = sizeof(buffer);
errno = 0;
pgstat_report_wait_start(WAIT_EVENT_WAL_COPY_READ);
- if (read(srcfd, buffer, nread) != nread)
+ r = read(srcfd, buffer, nread);
+ if (r != nread)
{
- if (errno != 0)
+ if (r < 0)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not read file \"%s\": %m",
path)));
else
ereport(ERROR,
- (errmsg("not enough data in file \"%s\"",
- path)));
+ (errmsg("not enough data in file \"%s\": read %d, expected %d",
+ path, r, nread)));
}
pgstat_report_wait_end();
}
@@ -11594,6 +11597,7 @@ XLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen,
int emode = private->emode;
uint32 targetPageOff;
XLogSegNo targetSegNo PG_USED_FOR_ASSERTS_ONLY;
+ int r;
XLByteToSeg(targetPagePtr, targetSegNo, wal_segment_size);
targetPageOff = XLogSegmentOffset(targetPagePtr, wal_segment_size);
@@ -11675,8 +11679,10 @@ retry:
if (lseek(readFile, (off_t) readOff, SEEK_SET) < 0)
{
char fname[MAXFNAMELEN];
+ int save_errno = errno;
XLogFileName(fname, curFileTLI, readSegNo, wal_segment_size);
+ errno = save_errno;
ereport(emode_for_corrupt_record(emode, targetPagePtr + reqLen),
(errcode_for_file_access(),
errmsg("could not seek in log segment %s to offset %u: %m",
@@ -11685,16 +11691,29 @@ retry:
}
pgstat_report_wait_start(WAIT_EVENT_WAL_READ);
- if (read(readFile, readBuf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
+ r = read(readFile, readBuf, XLOG_BLCKSZ);
+ if (r != XLOG_BLCKSZ)
{
char fname[MAXFNAMELEN];
+ int save_errno = errno;
pgstat_report_wait_end();
XLogFileName(fname, curFileTLI, readSegNo, wal_segment_size);
- ereport(emode_for_corrupt_record(emode, targetPagePtr + reqLen),
- (errcode_for_file_access(),
- errmsg("could not read from log segment %s, offset %u: %m",
- fname, readOff)));
+
+ if (r < 0)
+ {
+ errno = save_errno;
+ ereport(emode_for_corrupt_record(emode, targetPagePtr + reqLen),
+ (errcode_for_file_access(),
+ errmsg("could not read from log segment %s, offset %u: %m",
+ fname, readOff)));
+ }
+ else
+ ereport(emode_for_corrupt_record(emode, targetPagePtr + reqLen),
+ (errcode_for_file_access(),
+ errmsg("could not read from log segment %s, offset %u: read %d, expected %d",
+ fname, readOff, r, XLOG_BLCKSZ)));
+
goto next_record_is_invalid;
}
pgstat_report_wait_end();
diff --git a/src/backend/replication/logical/origin.c b/src/backend/replication/logical/origin.c
index 963878a5d8..c39d023d22 100644
--- a/src/backend/replication/logical/origin.c
+++ b/src/backend/replication/logical/origin.c
@@ -697,9 +697,16 @@ StartupReplicationOrigin(void)
/* verify magic, that is written even if nothing was active */
readBytes = read(fd, &magic, sizeof(magic));
if (readBytes != sizeof(magic))
- ereport(PANIC,
- (errmsg("could not read file \"%s\": %m",
- path)));
+ {
+ if (readBytes < 0)
+ ereport(PANIC,
+ (errmsg("could not read file \"%s\": %m",
+ path)));
+ else
+ ereport(PANIC,
+ (errmsg("could not read file \"%s\": %d read of %zu",
+ path, readBytes, sizeof(magic))));
+ }
COMP_CRC32C(crc, &magic, sizeof(magic));
if (magic != REPLICATION_STATE_MAGIC)
diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index 056628fe8e..cc64ff22ac 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -1394,11 +1394,15 @@ RestoreSlotFromDisk(const char *name)
CloseTransientFile(fd);
errno = saved_errno;
- ereport(PANIC,
- (errcode_for_file_access(),
- errmsg("could not read file \"%s\", read %d of %u: %m",
- path, readBytes,
- (uint32) ReplicationSlotOnDiskConstantSize)));
+ if (readBytes < 0)
+ ereport(PANIC,
+ (errcode_for_file_access(),
+ errmsg("could not read file \"%s\": %m", path)));
+ else
+ ereport(PANIC,
+ (errmsg("could not read file \"%s\": read %d of %u",
+ path, readBytes,
+ (uint32) ReplicationSlotOnDiskConstantSize)));
}
/* verify magic */
@@ -1434,10 +1438,14 @@ RestoreSlotFromDisk(const char *name)
CloseTransientFile(fd);
errno = saved_errno;
- ereport(PANIC,
- (errcode_for_file_access(),
- errmsg("could not read file \"%s\", read %d of %u: %m",
- path, readBytes, cp.length)));
+ if (readBytes < 0)
+ ereport(PANIC,
+ (errcode_for_file_access(),
+ errmsg("could not read file \"%s\": %m", path)));
+ else
+ ereport(PANIC,
+ (errmsg("could not read file \"%s\": read %d of %u",
+ path, readBytes, cp.length)));
}
CloseTransientFile(fd);
diff --git a/src/backend/utils/cache/relmapper.c b/src/backend/utils/cache/relmapper.c
index 99d095f2df..c4839b11f6 100644
--- a/src/backend/utils/cache/relmapper.c
+++ b/src/backend/utils/cache/relmapper.c
@@ -629,6 +629,7 @@ load_relmap_file(bool shared)
char mapfilename[MAXPGPATH];
pg_crc32c crc;
int fd;
+ int r;
if (shared)
{
@@ -659,11 +660,19 @@ load_relmap_file(bool shared)
* are able to access any relation that's affected by the change.
*/
pgstat_report_wait_start(WAIT_EVENT_RELATION_MAP_READ);
- if (read(fd, map, sizeof(RelMapFile)) != sizeof(RelMapFile))
- ereport(FATAL,
- (errcode_for_file_access(),
- errmsg("could not read relation mapping file \"%s\": %m",
- mapfilename)));
+ r = read(fd, map, sizeof(RelMapFile));
+ if (r != sizeof(RelMapFile))
+ {
+ if (r < 0)
+ ereport(FATAL,
+ (errcode_for_file_access(),
+ errmsg("could not read relation mapping file \"%s\": %m",
+ mapfilename)));
+ else
+ ereport(FATAL,
+ (errmsg("could not read relation mapping file \"%s\": %d read, expected %zu",
+ mapfilename, r, sizeof(RelMapFile))));
+ }
pgstat_report_wait_end();
CloseTransientFile(fd);
diff --git a/src/bin/pg_rewind/file_ops.c b/src/bin/pg_rewind/file_ops.c
index 94bcc13ae8..174ca7216d 100644
--- a/src/bin/pg_rewind/file_ops.c
+++ b/src/bin/pg_rewind/file_ops.c
@@ -289,6 +289,7 @@ slurpFile(const char *datadir, const char *path, size_t *filesize)
struct stat statbuf;
char fullpath[MAXPGPATH];
int len;
+ int r;
snprintf(fullpath, sizeof(fullpath), "%s/%s", datadir, path);
@@ -304,9 +305,17 @@ slurpFile(const char *datadir, const char *path, size_t *filesize)
buffer = pg_malloc(len + 1);
- if (read(fd, buffer, len) != len)
- pg_fatal("could not read file \"%s\": %s\n",
- fullpath, strerror(errno));
+ r = read(fd, buffer, len);
+ if (r != len)
+ {
+ if (r < 0)
+ pg_fatal("could not read file \"%s\": %s\n",
+ fullpath, strerror(errno));
+ else
+ pg_fatal("could not read file \"%s\": read %d, expected %d\n",
+ fullpath, r, len);
+
+ }
close(fd);
/* Zero-terminate the buffer. */
diff --git a/src/bin/pg_rewind/parsexlog.c b/src/bin/pg_rewind/parsexlog.c
index b4c1f827a6..4f27cfe42b 100644
--- a/src/bin/pg_rewind/parsexlog.c
+++ b/src/bin/pg_rewind/parsexlog.c
@@ -246,6 +246,7 @@ SimpleXLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr,
uint32 targetPageOff;
XLogRecPtr targetSegEnd;
XLogSegNo targetSegNo;
+ int r;
XLByteToSeg(targetPagePtr, targetSegNo, WalSegSz);
XLogSegNoOffsetToRecPtr(targetSegNo + 1, 0, targetSegEnd, WalSegSz);
@@ -309,10 +310,17 @@ SimpleXLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr,
return -1;
}
- if (read(xlogreadfd, readBuf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
+
+ r = read(xlogreadfd, readBuf, XLOG_BLCKSZ);
+ if (r != XLOG_BLCKSZ)
{
- printf(_("could not read from file \"%s\": %s\n"), xlogfpath,
- strerror(errno));
+ if (r < 0)
+ printf(_("could not read from file \"%s\": %s\n"), xlogfpath,
+ strerror(errno));
+ else
+ printf(_("could not read from file \"%s\": read %d, expected %d\n"),
+ xlogfpath, r, XLOG_BLCKSZ);
+
return -1;
}
diff --git a/src/bin/pg_waldump/pg_waldump.c b/src/bin/pg_waldump/pg_waldump.c
index 5c4f38e597..64391a7e5c 100644
--- a/src/bin/pg_waldump/pg_waldump.c
+++ b/src/bin/pg_waldump/pg_waldump.c
@@ -210,8 +210,10 @@ search_directory(const char *directory, const char *fname)
if (fd >= 0)
{
char buf[XLOG_BLCKSZ];
+ int r;
- if (read(fd, buf, XLOG_BLCKSZ) == XLOG_BLCKSZ)
+ r = read(fd, buf, XLOG_BLCKSZ);
+ if (r == XLOG_BLCKSZ)
{
XLogLongPageHeader longhdr = (XLogLongPageHeader) buf;
@@ -229,7 +231,8 @@ search_directory(const char *directory, const char *fname)
fatal_error("could not read file \"%s\": %s",
fname, strerror(errno));
else
- fatal_error("not enough data in file \"%s\"", fname);
+ fatal_error("not enough data in file \"%s\": %d read, %d expected",
+ fname, r, XLOG_BLCKSZ);
}
close(fd);
return true;