From 00b2918e1bb18601cd78ac4eebb2f1882a011bd3 Mon Sep 17 00:00:00 2001 From: Thomas Munro Date: Sat, 30 Nov 2019 12:44:47 +1300 Subject: [PATCH 1/3] Raise errors for I/O errors during BufFileRead(). Previously, we returned 0 in case of I/O errors, which was indistinguishable from hitting the end of the file. Remove %m from error messages about short reads, since BufFileRead()t now only returns control if there was no error. Author: Thomas Munro Reported-by: Amit Khandekar Discussion: https://postgr.es/m/CA%2BhUKGJE04G%3D8TLK0DLypT_27D9dR8F1RQgNp0jK6qR0tZGWOw%40mail.gmail.com --- src/backend/access/gist/gistbuildbuffers.c | 2 +- src/backend/executor/nodeHashjoin.c | 4 ++-- src/backend/storage/file/buffile.c | 10 +++++++++- src/backend/utils/sort/logtape.c | 2 +- src/backend/utils/sort/tuplestore.c | 6 +++--- 5 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/backend/access/gist/gistbuildbuffers.c b/src/backend/access/gist/gistbuildbuffers.c index 38f786848d..2feec247cf 100644 --- a/src/backend/access/gist/gistbuildbuffers.c +++ b/src/backend/access/gist/gistbuildbuffers.c @@ -760,7 +760,7 @@ ReadTempFileBlock(BufFile *file, long blknum, void *ptr) if (BufFileSeekBlock(file, blknum) != 0) elog(ERROR, "could not seek temporary file: %m"); if (BufFileRead(file, ptr, BLCKSZ) != BLCKSZ) - elog(ERROR, "could not read temporary file: %m"); + elog(ERROR, "could not read temporary file"); } static void diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c index ec37558c12..35a181632b 100644 --- a/src/backend/executor/nodeHashjoin.c +++ b/src/backend/executor/nodeHashjoin.c @@ -1260,7 +1260,7 @@ ExecHashJoinGetSavedTuple(HashJoinState *hjstate, if (nread != sizeof(header)) ereport(ERROR, (errcode_for_file_access(), - errmsg("could not read from hash-join temporary file: %m"))); + errmsg("could not read from hash-join temporary file"))); *hashvalue = header[0]; tuple = (MinimalTuple) palloc(header[1]); tuple->t_len = header[1]; @@ -1270,7 +1270,7 @@ ExecHashJoinGetSavedTuple(HashJoinState *hjstate, if (nread != header[1] - sizeof(uint32)) ereport(ERROR, (errcode_for_file_access(), - errmsg("could not read from hash-join temporary file: %m"))); + errmsg("could not read from hash-join temporary file"))); ExecForceStoreMinimalTuple(tuple, tupleSlot, true); return tupleSlot; } diff --git a/src/backend/storage/file/buffile.c b/src/backend/storage/file/buffile.c index 440ff77e1f..136f80c64d 100644 --- a/src/backend/storage/file/buffile.c +++ b/src/backend/storage/file/buffile.c @@ -434,7 +434,14 @@ BufFileLoadBuffer(BufFile *file) file->curOffset, WAIT_EVENT_BUFFILE_READ); if (file->nbytes < 0) + { file->nbytes = 0; + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not read file \"%s\": %m", + FilePathName(thisfile)))); + } + /* we choose not to advance curOffset here */ if (file->nbytes > 0) @@ -522,7 +529,8 @@ BufFileDumpBuffer(BufFile *file) /* * BufFileRead * - * Like fread() except we assume 1-byte element size. + * Like fread() except we assume 1-byte element size and report I/O errors via + * ereport(). */ size_t BufFileRead(BufFile *file, void *ptr, size_t size) diff --git a/src/backend/utils/sort/logtape.c b/src/backend/utils/sort/logtape.c index 8985b9e095..a410ff82f8 100644 --- a/src/backend/utils/sort/logtape.c +++ b/src/backend/utils/sort/logtape.c @@ -273,7 +273,7 @@ ltsReadBlock(LogicalTapeSet *lts, long blocknum, void *buffer) BufFileRead(lts->pfile, buffer, BLCKSZ) != BLCKSZ) ereport(ERROR, (errcode_for_file_access(), - errmsg("could not read block %ld of temporary file: %m", + errmsg("could not read block %ld of temporary file", blocknum))); } diff --git a/src/backend/utils/sort/tuplestore.c b/src/backend/utils/sort/tuplestore.c index 3fc7f92182..2761b063a6 100644 --- a/src/backend/utils/sort/tuplestore.c +++ b/src/backend/utils/sort/tuplestore.c @@ -1474,7 +1474,7 @@ getlen(Tuplestorestate *state, bool eofOK) if (nbytes != 0 || !eofOK) ereport(ERROR, (errcode_for_file_access(), - errmsg("could not read from tuplestore temporary file: %m"))); + errmsg("could not read from tuplestore temporary file"))); return 0; } @@ -1547,12 +1547,12 @@ readtup_heap(Tuplestorestate *state, unsigned int len) tupbodylen) != (size_t) tupbodylen) ereport(ERROR, (errcode_for_file_access(), - errmsg("could not read from tuplestore temporary file: %m"))); + errmsg("could not read from tuplestore temporary file"))); if (state->backward) /* need trailing length word? */ if (BufFileRead(state->myfile, (void *) &tuplen, sizeof(tuplen)) != sizeof(tuplen)) ereport(ERROR, (errcode_for_file_access(), - errmsg("could not read from tuplestore temporary file: %m"))); + errmsg("could not read from tuplestore temporary file"))); return (void *) tuple; } -- 2.23.0