mirror of
https://github.com/postgres/postgres.git
synced 2025-11-19 13:42:17 +03:00
Fix buffile.c error handling.
Convert buffile.c error handling to use ereport. This fixes cases where I/O errors were indistinguishable from EOF or not reported. Also remove "%m" from error messages where errno would be bogus. While we're modifying those strings, add block numbers and short read byte counts where appropriate. Back-patch to all supported releases. Reported-by: Amit Khandekar <amitdkhan.pg@gmail.com> Reviewed-by: Melanie Plageman <melanieplageman@gmail.com> Reviewed-by: Alvaro Herrera <alvherre@2ndquadrant.com> Reviewed-by: Robert Haas <robertmhaas@gmail.com> Reviewed-by: Ibrar Ahmed <ibrar.ahmad@gmail.com> Reviewed-by: Michael Paquier <michael@paquier.xyz> Discussion: https://postgr.es/m/CA%2BhUKGJE04G%3D8TLK0DLypT_27D9dR8F1RQgNp0jK6qR0tZGWOw%40mail.gmail.com
This commit is contained in:
@@ -262,12 +262,12 @@ ltsWriteBlock(LogicalTapeSet *lts, long blocknum, void *buffer)
|
||||
}
|
||||
|
||||
/* Write the requested block */
|
||||
if (BufFileSeekBlock(lts->pfile, blocknum) != 0 ||
|
||||
BufFileWrite(lts->pfile, buffer, BLCKSZ) != BLCKSZ)
|
||||
if (BufFileSeekBlock(lts->pfile, blocknum) != 0)
|
||||
ereport(ERROR,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("could not write block %ld of temporary file: %m",
|
||||
errmsg("could not seek to block %ld of temporary file",
|
||||
blocknum)));
|
||||
BufFileWrite(lts->pfile, buffer, BLCKSZ);
|
||||
|
||||
/* Update nBlocksWritten, if we extended the file */
|
||||
if (blocknum == lts->nBlocksWritten)
|
||||
@@ -283,12 +283,19 @@ ltsWriteBlock(LogicalTapeSet *lts, long blocknum, void *buffer)
|
||||
static void
|
||||
ltsReadBlock(LogicalTapeSet *lts, long blocknum, void *buffer)
|
||||
{
|
||||
if (BufFileSeekBlock(lts->pfile, blocknum) != 0 ||
|
||||
BufFileRead(lts->pfile, buffer, BLCKSZ) != BLCKSZ)
|
||||
size_t nread;
|
||||
|
||||
if (BufFileSeekBlock(lts->pfile, blocknum) != 0)
|
||||
ereport(ERROR,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("could not read block %ld of temporary file: %m",
|
||||
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)));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -196,14 +196,9 @@ static void
|
||||
sts_flush_chunk(SharedTuplestoreAccessor *accessor)
|
||||
{
|
||||
size_t size;
|
||||
size_t written;
|
||||
|
||||
size = STS_CHUNK_PAGES * BLCKSZ;
|
||||
written = BufFileWrite(accessor->write_file, accessor->write_chunk, size);
|
||||
if (written != size)
|
||||
ereport(ERROR,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("could not write to temporary file: %m")));
|
||||
BufFileWrite(accessor->write_file, accessor->write_chunk, size);
|
||||
memset(accessor->write_chunk, 0, size);
|
||||
accessor->write_pointer = &accessor->write_chunk->data[0];
|
||||
accessor->sts->participants[accessor->participant].npages +=
|
||||
@@ -555,6 +550,7 @@ 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,14 +566,15 @@ sts_parallel_scan_next(SharedTuplestoreAccessor *accessor, void *meta_data)
|
||||
if (BufFileSeekBlock(accessor->read_file, read_page) != 0)
|
||||
ereport(ERROR,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("could not read from shared tuplestore temporary file"),
|
||||
errdetail_internal("Could not seek to next block.")));
|
||||
if (BufFileRead(accessor->read_file, &chunk_header,
|
||||
STS_CHUNK_HEADER_SIZE) != STS_CHUNK_HEADER_SIZE)
|
||||
errmsg("could not seek 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"),
|
||||
errdetail_internal("Short read while reading chunk header.")));
|
||||
errmsg("could not read from shared tuplestore temporary file: read only %zu of %zu bytes",
|
||||
nread, STS_CHUNK_HEADER_SIZE)));
|
||||
|
||||
/*
|
||||
* If this is an overflow chunk, we skip it and any following
|
||||
|
||||
@@ -515,7 +515,7 @@ tuplestore_select_read_pointer(Tuplestorestate *state, int ptr)
|
||||
SEEK_SET) != 0)
|
||||
ereport(ERROR,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("could not seek in tuplestore temporary file: %m")));
|
||||
errmsg("could not seek in tuplestore temporary file")));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -525,7 +525,7 @@ tuplestore_select_read_pointer(Tuplestorestate *state, int ptr)
|
||||
SEEK_SET) != 0)
|
||||
ereport(ERROR,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("could not seek in tuplestore temporary file: %m")));
|
||||
errmsg("could not seek in tuplestore temporary file")));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -866,7 +866,7 @@ tuplestore_puttuple_common(Tuplestorestate *state, void *tuple)
|
||||
SEEK_SET) != 0)
|
||||
ereport(ERROR,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("could not seek in tuplestore temporary file: %m")));
|
||||
errmsg("could not seek in tuplestore temporary file")));
|
||||
state->status = TSS_WRITEFILE;
|
||||
|
||||
/*
|
||||
@@ -970,7 +970,7 @@ tuplestore_gettuple(Tuplestorestate *state, bool forward,
|
||||
SEEK_SET) != 0)
|
||||
ereport(ERROR,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("could not seek in tuplestore temporary file: %m")));
|
||||
errmsg("could not seek in tuplestore temporary file")));
|
||||
state->status = TSS_READFILE;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
@@ -1034,7 +1034,7 @@ tuplestore_gettuple(Tuplestorestate *state, bool forward,
|
||||
SEEK_CUR) != 0)
|
||||
ereport(ERROR,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("could not seek in tuplestore temporary file: %m")));
|
||||
errmsg("could not seek in tuplestore temporary file")));
|
||||
Assert(!state->truncated);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1051,7 +1051,7 @@ tuplestore_gettuple(Tuplestorestate *state, bool forward,
|
||||
SEEK_CUR) != 0)
|
||||
ereport(ERROR,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("could not seek in tuplestore temporary file: %m")));
|
||||
errmsg("could not seek in tuplestore temporary file")));
|
||||
tup = READTUP(state, tuplen);
|
||||
return tup;
|
||||
|
||||
@@ -1253,7 +1253,7 @@ tuplestore_rescan(Tuplestorestate *state)
|
||||
if (BufFileSeek(state->myfile, 0, 0L, SEEK_SET) != 0)
|
||||
ereport(ERROR,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("could not seek in tuplestore temporary file: %m")));
|
||||
errmsg("could not seek in tuplestore temporary file")));
|
||||
break;
|
||||
default:
|
||||
elog(ERROR, "invalid tuplestore state");
|
||||
@@ -1318,7 +1318,7 @@ tuplestore_copy_read_pointer(Tuplestorestate *state,
|
||||
SEEK_SET) != 0)
|
||||
ereport(ERROR,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("could not seek in tuplestore temporary file: %m")));
|
||||
errmsg("could not seek in tuplestore temporary file")));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1327,7 +1327,7 @@ tuplestore_copy_read_pointer(Tuplestorestate *state,
|
||||
SEEK_SET) != 0)
|
||||
ereport(ERROR,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("could not seek in tuplestore temporary file: %m")));
|
||||
errmsg("could not seek in tuplestore temporary file")));
|
||||
}
|
||||
}
|
||||
else if (srcptr == state->activeptr)
|
||||
@@ -1474,7 +1474,8 @@ 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: read only %zu of %zu bytes",
|
||||
nbytes, sizeof(len))));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1511,22 +1512,10 @@ writetup_heap(Tuplestorestate *state, void *tup)
|
||||
/* total on-disk footprint: */
|
||||
unsigned int tuplen = tupbodylen + sizeof(int);
|
||||
|
||||
if (BufFileWrite(state->myfile, (void *) &tuplen,
|
||||
sizeof(tuplen)) != sizeof(tuplen))
|
||||
ereport(ERROR,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("could not write to tuplestore temporary file: %m")));
|
||||
if (BufFileWrite(state->myfile, (void *) tupbody,
|
||||
tupbodylen) != (size_t) tupbodylen)
|
||||
ereport(ERROR,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("could not write to tuplestore temporary file: %m")));
|
||||
BufFileWrite(state->myfile, (void *) &tuplen, sizeof(tuplen));
|
||||
BufFileWrite(state->myfile, (void *) tupbody, tupbodylen);
|
||||
if (state->backward) /* need trailing length word? */
|
||||
if (BufFileWrite(state->myfile, (void *) &tuplen,
|
||||
sizeof(tuplen)) != sizeof(tuplen))
|
||||
ereport(ERROR,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("could not write to tuplestore temporary file: %m")));
|
||||
BufFileWrite(state->myfile, (void *) &tuplen, sizeof(tuplen));
|
||||
|
||||
FREEMEM(state, GetMemoryChunkSpace(tuple));
|
||||
heap_free_minimal_tuple(tuple);
|
||||
@@ -1539,20 +1528,25 @@ 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;
|
||||
if (BufFileRead(state->myfile, (void *) tupbody,
|
||||
tupbodylen) != (size_t) tupbodylen)
|
||||
nread = BufFileRead(state->myfile, (void *) tupbody, tupbodylen);
|
||||
if (nread != (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: read only %zu of %zu bytes",
|
||||
nread, (size_t) tupbodylen)));
|
||||
if (state->backward) /* need trailing length word? */
|
||||
if (BufFileRead(state->myfile, (void *) &tuplen,
|
||||
sizeof(tuplen)) != sizeof(tuplen))
|
||||
{
|
||||
nread = BufFileRead(state->myfile, (void *) &tuplen, sizeof(tuplen));
|
||||
if (nread != 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: read only %zu of %zu bytes",
|
||||
nread, sizeof(tuplen))));
|
||||
}
|
||||
return (void *) tuple;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user