summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/access/gist/gistbuildbuffers.c7
-rw-r--r--src/backend/backup/backup_manifest.c9
-rw-r--r--src/backend/executor/nodeHashjoin.c18
-rw-r--r--src/backend/replication/logical/worker.c32
-rw-r--r--src/backend/storage/file/buffile.c50
-rw-r--r--src/backend/utils/sort/logtape.c9
-rw-r--r--src/backend/utils/sort/sharedtuplestore.c49
-rw-r--r--src/backend/utils/sort/tuplestore.c29
-rw-r--r--src/include/storage/buffile.h4
9 files changed, 73 insertions, 134 deletions
diff --git a/src/backend/access/gist/gistbuildbuffers.c b/src/backend/access/gist/gistbuildbuffers.c
index 1a732dd5cf..3399a6ae68 100644
--- a/src/backend/access/gist/gistbuildbuffers.c
+++ b/src/backend/access/gist/gistbuildbuffers.c
@@ -753,14 +753,9 @@ gistRelocateBuildBuffersOnSplit(GISTBuildBuffers *gfbb, GISTSTATE *giststate,
static void
ReadTempFileBlock(BufFile *file, long blknum, void *ptr)
{
- size_t nread;
-
if (BufFileSeekBlock(file, blknum) != 0)
elog(ERROR, "could not seek to block %ld in temporary file", blknum);
- nread = BufFileRead(file, ptr, BLCKSZ);
- if (nread != BLCKSZ)
- elog(ERROR, "could not read temporary file: read only %zu of %zu bytes",
- nread, (size_t) BLCKSZ);
+ BufFileReadExact(file, ptr, BLCKSZ);
}
static void
diff --git a/src/backend/backup/backup_manifest.c b/src/backend/backup/backup_manifest.c
index d325ef047a..fabd2ca299 100644
--- a/src/backend/backup/backup_manifest.c
+++ b/src/backend/backup/backup_manifest.c
@@ -362,17 +362,10 @@ SendBackupManifest(backup_manifest_info *manifest, bbsink *sink)
while (manifest_bytes_done < manifest->manifest_size)
{
size_t bytes_to_read;
- size_t rc;
bytes_to_read = Min(sink->bbs_buffer_length,
manifest->manifest_size - manifest_bytes_done);
- rc = BufFileRead(manifest->buffile, sink->bbs_buffer,
- bytes_to_read);
- if (rc != bytes_to_read)
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not read from temporary file: read only %zu of %zu bytes",
- rc, bytes_to_read)));
+ BufFileReadExact(manifest->buffile, sink->bbs_buffer, bytes_to_read);
bbsink_manifest_contents(sink, bytes_to_read);
manifest_bytes_done += bytes_to_read;
}
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index 9dbbd7f8c3..b215e3f59a 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -1260,28 +1260,18 @@ ExecHashJoinGetSavedTuple(HashJoinState *hjstate,
* we can read them both in one BufFileRead() call without any type
* cheating.
*/
- nread = BufFileRead(file, header, sizeof(header));
+ nread = BufFileReadMaybeEOF(file, header, sizeof(header), true);
if (nread == 0) /* end of file */
{
ExecClearTuple(tupleSlot);
return NULL;
}
- if (nread != sizeof(header))
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not read from hash-join temporary file: read only %zu of %zu bytes",
- nread, sizeof(header))));
*hashvalue = header[0];
tuple = (MinimalTuple) palloc(header[1]);
tuple->t_len = header[1];
- nread = BufFileRead(file,
- ((char *) tuple + sizeof(uint32)),
- header[1] - sizeof(uint32));
- if (nread != header[1] - sizeof(uint32))
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not read from hash-join temporary file: read only %zu of %zu bytes",
- nread, header[1] - sizeof(uint32))));
+ BufFileReadExact(file,
+ (char *) tuple + sizeof(uint32),
+ header[1] - sizeof(uint32));
ExecForceStoreMinimalTuple(tuple, tupleSlot, true);
return tupleSlot;
}
diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c
index f3856c9843..d8b8a374c6 100644
--- a/src/backend/replication/logical/worker.c
+++ b/src/backend/replication/logical/worker.c
@@ -2069,19 +2069,13 @@ apply_spooled_messages(FileSet *stream_fileset, TransactionId xid,
CHECK_FOR_INTERRUPTS();
/* read length of the on-disk record */
- nbytes = BufFileRead(stream_fd, &len, sizeof(len));
+ nbytes = BufFileReadMaybeEOF(stream_fd, &len, sizeof(len), true);
/* have we reached end of the file? */
if (nbytes == 0)
break;
/* do we have a correct length? */
- if (nbytes != sizeof(len))
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not read from streaming transaction's changes file \"%s\": read only %zu of %zu bytes",
- path, nbytes, sizeof(len))));
-
if (len <= 0)
elog(ERROR, "incorrect length %d in streaming transaction's changes file \"%s\"",
len, path);
@@ -2090,12 +2084,7 @@ apply_spooled_messages(FileSet *stream_fileset, TransactionId xid,
buffer = repalloc(buffer, len);
/* and finally read the data into the buffer */
- nbytes = BufFileRead(stream_fd, buffer, len);
- if (nbytes != len)
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not read from streaming transaction's changes file \"%s\": read only %zu of %zu bytes",
- path, nbytes, (size_t) len)));
+ BufFileReadExact(stream_fd, buffer, len);
BufFileTell(stream_fd, &fileno, &offset);
@@ -3993,7 +3982,6 @@ static void
subxact_info_read(Oid subid, TransactionId xid)
{
char path[MAXPGPATH];
- size_t nread;
Size len;
BufFile *fd;
MemoryContext oldctx;
@@ -4013,12 +4001,7 @@ subxact_info_read(Oid subid, TransactionId xid)
return;
/* read number of subxact items */
- nread = BufFileRead(fd, &subxact_data.nsubxacts, sizeof(subxact_data.nsubxacts));
- if (nread != sizeof(subxact_data.nsubxacts))
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not read from streaming transaction's subxact file \"%s\": read only %zu of %zu bytes",
- path, nread, sizeof(subxact_data.nsubxacts))));
+ BufFileReadExact(fd, &subxact_data.nsubxacts, sizeof(subxact_data.nsubxacts));
len = sizeof(SubXactInfo) * subxact_data.nsubxacts;
@@ -4037,14 +4020,7 @@ subxact_info_read(Oid subid, TransactionId xid)
MemoryContextSwitchTo(oldctx);
if (len > 0)
- {
- nread = BufFileRead(fd, subxact_data.subxacts, len);
- if (nread != len)
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not read from streaming transaction's subxact file \"%s\": read only %zu of %zu bytes",
- path, nread, len)));
- }
+ BufFileReadExact(fd, subxact_data.subxacts, len);
BufFileClose(fd);
}
diff --git a/src/backend/storage/file/buffile.c b/src/backend/storage/file/buffile.c
index 4a5bd0e224..c5464b6aa6 100644
--- a/src/backend/storage/file/buffile.c
+++ b/src/backend/storage/file/buffile.c
@@ -573,14 +573,19 @@ BufFileDumpBuffer(BufFile *file)
}
/*
- * BufFileRead
+ * BufFileRead variants
*
* Like fread() except we assume 1-byte element size and report I/O errors via
* ereport().
+ *
+ * If 'exact' is true, then an error is also raised if the number of bytes
+ * read is not exactly 'size' (no short reads). If 'exact' and 'eofOK' are
+ * true, then reading zero bytes is ok.
*/
-size_t
-BufFileRead(BufFile *file, void *ptr, size_t size)
+static size_t
+BufFileReadCommon(BufFile *file, void *ptr, size_t size, bool exact, bool eofOK)
{
+ size_t start_size = size;
size_t nread = 0;
size_t nthistime;
@@ -612,10 +617,49 @@ BufFileRead(BufFile *file, void *ptr, size_t size)
nread += nthistime;
}
+ if (exact &&
+ (nread != start_size && !(nread == 0 && eofOK)))
+ ereport(ERROR,
+ errcode_for_file_access(),
+ file->name ?
+ errmsg("could not read from file set \"%s\": read only %zu of %zu bytes",
+ file->name, nread, start_size) :
+ errmsg("could not read from temporary file: read only %zu of %zu bytes",
+ nread, start_size));
+
return nread;
}
/*
+ * Legacy interface where the caller needs to check for end of file or short
+ * reads.
+ */
+size_t
+BufFileRead(BufFile *file, void *ptr, size_t size)
+{
+ return BufFileReadCommon(file, ptr, size, false, false);
+}
+
+/*
+ * Require read of exactly the specified size.
+ */
+void
+BufFileReadExact(BufFile *file, void *ptr, size_t size)
+{
+ BufFileReadCommon(file, ptr, size, true, false);
+}
+
+/*
+ * Require read of exactly the specified size, but optionally allow end of
+ * file (in which case 0 is returned).
+ */
+size_t
+BufFileReadMaybeEOF(BufFile *file, void *ptr, size_t size, bool eofOK)
+{
+ return BufFileReadCommon(file, ptr, size, true, eofOK);
+}
+
+/*
* BufFileWrite
*
* Like fwrite() except we assume 1-byte element size and report errors via
diff --git a/src/backend/utils/sort/logtape.c b/src/backend/utils/sort/logtape.c
index 907dd8f0a7..56ac0298c5 100644
--- a/src/backend/utils/sort/logtape.c
+++ b/src/backend/utils/sort/logtape.c
@@ -281,19 +281,12 @@ ltsWriteBlock(LogicalTapeSet *lts, long blocknum, const void *buffer)
static void
ltsReadBlock(LogicalTapeSet *lts, long blocknum, void *buffer)
{
- size_t nread;
-
if (BufFileSeekBlock(lts->pfile, blocknum) != 0)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not seek to block %ld of temporary file",
blocknum)));
- nread = BufFileRead(lts->pfile, buffer, BLCKSZ);
- if (nread != BLCKSZ)
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not read block %ld of temporary file: read only %zu of %zu bytes",
- blocknum, nread, (size_t) BLCKSZ)));
+ BufFileReadExact(lts->pfile, buffer, BLCKSZ);
}
/*
diff --git a/src/backend/utils/sort/sharedtuplestore.c b/src/backend/utils/sort/sharedtuplestore.c
index 65bbe0a52d..e3da83f10b 100644
--- a/src/backend/utils/sort/sharedtuplestore.c
+++ b/src/backend/utils/sort/sharedtuplestore.c
@@ -422,23 +422,10 @@ sts_read_tuple(SharedTuplestoreAccessor *accessor, void *meta_data)
*/
if (accessor->sts->meta_data_size > 0)
{
- if (BufFileRead(accessor->read_file,
- meta_data,
- accessor->sts->meta_data_size) !=
- accessor->sts->meta_data_size)
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not read from shared tuplestore temporary file"),
- errdetail_internal("Short read while reading meta-data.")));
+ BufFileReadExact(accessor->read_file, meta_data, accessor->sts->meta_data_size);
accessor->read_bytes += accessor->sts->meta_data_size;
}
- if (BufFileRead(accessor->read_file,
- &size,
- sizeof(size)) != sizeof(size))
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not read from shared tuplestore temporary file"),
- errdetail_internal("Short read while reading size.")));
+ BufFileReadExact(accessor->read_file, &size, sizeof(size));
accessor->read_bytes += sizeof(size);
if (size > accessor->read_buffer_size)
{
@@ -455,13 +442,7 @@ sts_read_tuple(SharedTuplestoreAccessor *accessor, void *meta_data)
this_chunk_size = Min(remaining_size,
BLCKSZ * STS_CHUNK_PAGES - accessor->read_bytes);
destination = accessor->read_buffer + sizeof(uint32);
- if (BufFileRead(accessor->read_file,
- destination,
- this_chunk_size) != this_chunk_size)
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not read from shared tuplestore temporary file"),
- errdetail_internal("Short read while reading tuple.")));
+ BufFileReadExact(accessor->read_file, destination, this_chunk_size);
accessor->read_bytes += this_chunk_size;
remaining_size -= this_chunk_size;
destination += this_chunk_size;
@@ -473,12 +454,7 @@ sts_read_tuple(SharedTuplestoreAccessor *accessor, void *meta_data)
/* We are now positioned at the start of an overflow chunk. */
SharedTuplestoreChunk chunk_header;
- if (BufFileRead(accessor->read_file, &chunk_header, STS_CHUNK_HEADER_SIZE) !=
- STS_CHUNK_HEADER_SIZE)
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not read from shared tuplestore temporary file"),
- errdetail_internal("Short read while reading overflow chunk header.")));
+ BufFileReadExact(accessor->read_file, &chunk_header, STS_CHUNK_HEADER_SIZE);
accessor->read_bytes = STS_CHUNK_HEADER_SIZE;
if (chunk_header.overflow == 0)
ereport(ERROR,
@@ -489,13 +465,7 @@ sts_read_tuple(SharedTuplestoreAccessor *accessor, void *meta_data)
this_chunk_size = Min(remaining_size,
BLCKSZ * STS_CHUNK_PAGES -
STS_CHUNK_HEADER_SIZE);
- if (BufFileRead(accessor->read_file,
- destination,
- this_chunk_size) != this_chunk_size)
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not read from shared tuplestore temporary file"),
- errdetail_internal("Short read while reading tuple.")));
+ BufFileReadExact(accessor->read_file, destination, this_chunk_size);
accessor->read_bytes += this_chunk_size;
remaining_size -= this_chunk_size;
destination += this_chunk_size;
@@ -551,7 +521,6 @@ sts_parallel_scan_next(SharedTuplestoreAccessor *accessor, void *meta_data)
if (!eof)
{
SharedTuplestoreChunk chunk_header;
- size_t nread;
/* Make sure we have the file open. */
if (accessor->read_file == NULL)
@@ -570,13 +539,7 @@ sts_parallel_scan_next(SharedTuplestoreAccessor *accessor, void *meta_data)
(errcode_for_file_access(),
errmsg("could not seek to block %u in shared tuplestore temporary file",
read_page)));
- nread = BufFileRead(accessor->read_file, &chunk_header,
- STS_CHUNK_HEADER_SIZE);
- if (nread != STS_CHUNK_HEADER_SIZE)
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not read from shared tuplestore temporary file: read only %zu of %zu bytes",
- nread, STS_CHUNK_HEADER_SIZE)));
+ BufFileReadExact(accessor->read_file, &chunk_header, STS_CHUNK_HEADER_SIZE);
/*
* If this is an overflow chunk, we skip it and any following
diff --git a/src/backend/utils/sort/tuplestore.c b/src/backend/utils/sort/tuplestore.c
index 44f1d9e855..bc36662198 100644
--- a/src/backend/utils/sort/tuplestore.c
+++ b/src/backend/utils/sort/tuplestore.c
@@ -1468,15 +1468,11 @@ getlen(Tuplestorestate *state, bool eofOK)
unsigned int len;
size_t nbytes;
- nbytes = BufFileRead(state->myfile, &len, sizeof(len));
- if (nbytes == sizeof(len))
+ nbytes = BufFileReadMaybeEOF(state->myfile, &len, sizeof(len), eofOK);
+ if (nbytes == 0)
+ return 0;
+ else
return len;
- if (nbytes != 0 || !eofOK)
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not read from tuplestore temporary file: read only %zu of %zu bytes",
- nbytes, sizeof(len))));
- return 0;
}
@@ -1528,25 +1524,12 @@ readtup_heap(Tuplestorestate *state, unsigned int len)
unsigned int tuplen = tupbodylen + MINIMAL_TUPLE_DATA_OFFSET;
MinimalTuple tuple = (MinimalTuple) palloc(tuplen);
char *tupbody = (char *) tuple + MINIMAL_TUPLE_DATA_OFFSET;
- size_t nread;
USEMEM(state, GetMemoryChunkSpace(tuple));
/* read in the tuple proper */
tuple->t_len = tuplen;
- nread = BufFileRead(state->myfile, tupbody, tupbodylen);
- if (nread != (size_t) tupbodylen)
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not read from tuplestore temporary file: read only %zu of %zu bytes",
- nread, (size_t) tupbodylen)));
+ BufFileReadExact(state->myfile, tupbody, tupbodylen);
if (state->backward) /* need trailing length word? */
- {
- nread = BufFileRead(state->myfile, &tuplen, sizeof(tuplen));
- if (nread != sizeof(tuplen))
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not read from tuplestore temporary file: read only %zu of %zu bytes",
- nread, sizeof(tuplen))));
- }
+ BufFileReadExact(state->myfile, &tuplen, sizeof(tuplen));
return (void *) tuple;
}
diff --git a/src/include/storage/buffile.h b/src/include/storage/buffile.h
index 7ed5b03516..6583766719 100644
--- a/src/include/storage/buffile.h
+++ b/src/include/storage/buffile.h
@@ -38,7 +38,9 @@ typedef struct BufFile BufFile;
extern BufFile *BufFileCreateTemp(bool interXact);
extern void BufFileClose(BufFile *file);
-extern size_t BufFileRead(BufFile *file, void *ptr, size_t size);
+extern pg_nodiscard size_t BufFileRead(BufFile *file, void *ptr, size_t size);
+extern void BufFileReadExact(BufFile *file, void *ptr, size_t size);
+extern size_t BufFileReadMaybeEOF(BufFile *file, void *ptr, size_t size, bool eofOK);
extern void BufFileWrite(BufFile *file, const void *ptr, size_t size);
extern int BufFileSeek(BufFile *file, int fileno, off_t offset, int whence);
extern void BufFileTell(BufFile *file, int *fileno, off_t *offset);