diff options
-rw-r--r-- | src/backend/access/gist/gistbuildbuffers.c | 7 | ||||
-rw-r--r-- | src/backend/backup/backup_manifest.c | 9 | ||||
-rw-r--r-- | src/backend/executor/nodeHashjoin.c | 18 | ||||
-rw-r--r-- | src/backend/replication/logical/worker.c | 32 | ||||
-rw-r--r-- | src/backend/storage/file/buffile.c | 50 | ||||
-rw-r--r-- | src/backend/utils/sort/logtape.c | 9 | ||||
-rw-r--r-- | src/backend/utils/sort/sharedtuplestore.c | 49 | ||||
-rw-r--r-- | src/backend/utils/sort/tuplestore.c | 29 | ||||
-rw-r--r-- | src/include/storage/buffile.h | 4 |
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); |