aboutsummaryrefslogtreecommitdiff
path: root/src/backend/storage/file/buffile.c
diff options
context:
space:
mode:
authorThomas Munro <tmunro@postgresql.org>2020-06-16 13:50:56 +1200
committerThomas Munro <tmunro@postgresql.org>2020-06-16 17:01:22 +1200
commit89020a92fb62fe09cd40d651ecbd4cd9912fd9d8 (patch)
tree8a3cada83a0b5d5c0e2fdf5a753b8dcbe57ede58 /src/backend/storage/file/buffile.c
parent39c698cff8a004c0027ffeb8c97b754d08a9a544 (diff)
downloadpostgresql-89020a92fb62fe09cd40d651ecbd4cd9912fd9d8.tar.gz
postgresql-89020a92fb62fe09cd40d651ecbd4cd9912fd9d8.zip
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
Diffstat (limited to 'src/backend/storage/file/buffile.c')
-rw-r--r--src/backend/storage/file/buffile.c57
1 files changed, 31 insertions, 26 deletions
diff --git a/src/backend/storage/file/buffile.c b/src/backend/storage/file/buffile.c
index 9a14addfd7a..1d6b8b4d5ad 100644
--- a/src/backend/storage/file/buffile.c
+++ b/src/backend/storage/file/buffile.c
@@ -93,8 +93,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);
/*
* Create a BufFile given the first underlying physical file.
@@ -247,7 +246,10 @@ BufFileLoadBuffer(BufFile *file)
if (file->curOffset != file->offsets[file->curFile])
{
if (FileSeek(thisfile, file->curOffset, SEEK_SET) != file->curOffset)
- return; /* seek failed, read nothing */
+ ereport(ERROR,
+ (errcode_for_file_access(),
+ errmsg("could not seek in file \"%s\": %m",
+ FilePathName(thisfile))));
file->offsets[file->curFile] = file->curOffset;
}
@@ -256,7 +258,14 @@ BufFileLoadBuffer(BufFile *file)
*/
file->nbytes = FileRead(thisfile, file->buffer.data, sizeof(file->buffer));
if (file->nbytes < 0)
+ {
file->nbytes = 0;
+ ereport(ERROR,
+ (errcode_for_file_access(),
+ errmsg("could not read file \"%s\": %m",
+ FilePathName(thisfile))));
+ }
+
file->offsets[file->curFile] += file->nbytes;
/* we choose not to advance curOffset here */
@@ -314,12 +323,19 @@ BufFileDumpBuffer(BufFile *file)
if (file->curOffset != file->offsets[file->curFile])
{
if (FileSeek(thisfile, file->curOffset, SEEK_SET) != file->curOffset)
- return; /* seek failed, give up */
+ ereport(ERROR,
+ (errcode_for_file_access(),
+ errmsg("could not seek in file \"%s\": %m",
+ FilePathName(thisfile))));
file->offsets[file->curFile] = file->curOffset;
}
bytestowrite = FileWrite(thisfile, file->buffer.data + wpos, bytestowrite);
if (bytestowrite <= 0)
- return; /* failed to write */
+ ereport(ERROR,
+ (errcode_for_file_access(),
+ errmsg("could not write to file \"%s\" : %m",
+ FilePathName(thisfile))));
+
file->offsets[file->curFile] += bytestowrite;
file->curOffset += bytestowrite;
wpos += bytestowrite;
@@ -352,7 +368,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)
@@ -360,12 +377,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)
{
@@ -399,7 +411,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)
@@ -413,11 +426,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? */
@@ -449,19 +458,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);
}
/*
@@ -470,6 +475,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 long.
* We do not support relative seeks across more than LONG_MAX, 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.
@@ -527,8 +533,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