mirror of
https://github.com/postgres/postgres.git
synced 2025-09-02 04:21:28 +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:
@@ -99,7 +99,7 @@ static BufFile *makeBufFile(File firstfile);
|
||||
static void extendBufFile(BufFile *file);
|
||||
static void BufFileLoadBuffer(BufFile *file);
|
||||
static void BufFileDumpBuffer(BufFile *file);
|
||||
static int BufFileFlush(BufFile *file);
|
||||
static void BufFileFlush(BufFile *file);
|
||||
static File MakeNewSharedSegment(BufFile *file, int segment);
|
||||
|
||||
/*
|
||||
@@ -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)
|
||||
@@ -490,7 +497,10 @@ BufFileDumpBuffer(BufFile *file)
|
||||
file->curOffset,
|
||||
WAIT_EVENT_BUFFILE_WRITE);
|
||||
if (bytestowrite <= 0)
|
||||
return; /* failed to write */
|
||||
ereport(ERROR,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("could not write to file \"%s\" : %m",
|
||||
FilePathName(thisfile))));
|
||||
file->curOffset += bytestowrite;
|
||||
wpos += bytestowrite;
|
||||
|
||||
@@ -522,7 +532,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)
|
||||
@@ -530,12 +541,7 @@ BufFileRead(BufFile *file, void *ptr, size_t size)
|
||||
size_t nread = 0;
|
||||
size_t nthistime;
|
||||
|
||||
if (file->dirty)
|
||||
{
|
||||
if (BufFileFlush(file) != 0)
|
||||
return 0; /* could not flush... */
|
||||
Assert(!file->dirty);
|
||||
}
|
||||
BufFileFlush(file);
|
||||
|
||||
while (size > 0)
|
||||
{
|
||||
@@ -569,7 +575,8 @@ BufFileRead(BufFile *file, void *ptr, size_t size)
|
||||
/*
|
||||
* BufFileWrite
|
||||
*
|
||||
* Like fwrite() except we assume 1-byte element size.
|
||||
* Like fwrite() except we assume 1-byte element size and report errors via
|
||||
* ereport().
|
||||
*/
|
||||
size_t
|
||||
BufFileWrite(BufFile *file, void *ptr, size_t size)
|
||||
@@ -585,11 +592,7 @@ BufFileWrite(BufFile *file, void *ptr, size_t size)
|
||||
{
|
||||
/* Buffer full, dump it out */
|
||||
if (file->dirty)
|
||||
{
|
||||
BufFileDumpBuffer(file);
|
||||
if (file->dirty)
|
||||
break; /* I/O error */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Hmm, went directly from reading to writing? */
|
||||
@@ -621,19 +624,15 @@ BufFileWrite(BufFile *file, void *ptr, size_t size)
|
||||
/*
|
||||
* BufFileFlush
|
||||
*
|
||||
* Like fflush()
|
||||
* Like fflush(), except that I/O errors are reported with ereport().
|
||||
*/
|
||||
static int
|
||||
static void
|
||||
BufFileFlush(BufFile *file)
|
||||
{
|
||||
if (file->dirty)
|
||||
{
|
||||
BufFileDumpBuffer(file);
|
||||
if (file->dirty)
|
||||
return EOF;
|
||||
}
|
||||
|
||||
return 0;
|
||||
Assert(!file->dirty);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -642,6 +641,7 @@ BufFileFlush(BufFile *file)
|
||||
* Like fseek(), except that target position needs two values in order to
|
||||
* work when logical filesize exceeds maximum value representable by off_t.
|
||||
* We do not support relative seeks across more than that, however.
|
||||
* I/O errors are reported by ereport().
|
||||
*
|
||||
* Result is 0 if OK, EOF if not. Logical position is not moved if an
|
||||
* impossible seek is attempted.
|
||||
@@ -699,8 +699,7 @@ BufFileSeek(BufFile *file, int fileno, off_t offset, int whence)
|
||||
return 0;
|
||||
}
|
||||
/* Otherwise, must reposition buffer, so flush any dirty data */
|
||||
if (BufFileFlush(file) != 0)
|
||||
return EOF;
|
||||
BufFileFlush(file);
|
||||
|
||||
/*
|
||||
* At this point and no sooner, check for seek past last segment. The
|
||||
|
Reference in New Issue
Block a user