In a case of a corrupted database, I saw an error message like

    Could not read from file ...: Success.

from the SLRU module.  This is because it checks that it reads or writes
exactly BLCKSZ, and else goes to the error path.  The attached patch
gives a different error message in this case.

Because of the structure of this code, we don't have the information to
do the usual "read %d of %zu", but at least this is better than
reporting a "success" error.

-- 
Peter Eisentraut              http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
From 680651938e30b5208a73b9d76813a5880af4ab54 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Tue, 18 Jun 2019 14:27:53 +0200
Subject: [PATCH 1/2] Better error messages for short reads/writes in SLRU

This avoids getting a

    Could not read from file ...: Success.

for a short read or write (since errno is not set in that case).
Instead, report a more specific error messages.
---
 src/backend/access/transam/slru.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/src/backend/access/transam/slru.c 
b/src/backend/access/transam/slru.c
index 2dbc65b125..315c0612e6 100644
--- a/src/backend/access/transam/slru.c
+++ b/src/backend/access/transam/slru.c
@@ -923,15 +923,19 @@ SlruReportIOError(SlruCtl ctl, int pageno, TransactionId 
xid)
                        ereport(ERROR,
                                        (errcode_for_file_access(),
                                         errmsg("could not access status of 
transaction %u", xid),
-                                        errdetail("Could not read from file 
\"%s\" at offset %u: %m.",
-                                                          path, offset)));
+                                        errno == 0
+                                        ? errdetail("Short read from file 
\"%s\" at offset %u.", path, offset)
+                                        : errdetail("Could not read from file 
\"%s\" at offset %u: %m.",
+                                                                path, 
offset)));
                        break;
                case SLRU_WRITE_FAILED:
                        ereport(ERROR,
                                        (errcode_for_file_access(),
                                         errmsg("could not access status of 
transaction %u", xid),
-                                        errdetail("Could not write to file 
\"%s\" at offset %u: %m.",
-                                                          path, offset)));
+                                        errno == 0
+                                        ? errdetail("Short write to file 
\"%s\" at offset %u.", path, offset)
+                                        : errdetail("Could not write to file 
\"%s\" at offset %u: %m.",
+                                                                path, 
offset)));
                        break;
                case SLRU_FSYNC_FAILED:
                        ereport(data_sync_elevel(ERROR),
-- 
2.22.0

From 9d6d381993701fc696466e822d58289c480c358f Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Tue, 18 Jun 2019 14:29:31 +0200
Subject: [PATCH 2/2] Use consistent style for checking return from system
 calls

Use

    if (something() < 0)
        error ...

instead of just

    if (something)
        error ...

The latter is not incorrect, but it's a bit confusing and not the
common style.
---
 src/backend/access/transam/slru.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/backend/access/transam/slru.c 
b/src/backend/access/transam/slru.c
index 315c0612e6..dab5b6ffa0 100644
--- a/src/backend/access/transam/slru.c
+++ b/src/backend/access/transam/slru.c
@@ -697,7 +697,7 @@ SlruPhysicalReadPage(SlruCtl ctl, int pageno, int slotno)
        }
        pgstat_report_wait_end();
 
-       if (CloseTransientFile(fd))
+       if (CloseTransientFile(fd) < 0)
        {
                slru_errcause = SLRU_CLOSE_FAILED;
                slru_errno = errno;
@@ -869,7 +869,7 @@ SlruPhysicalWritePage(SlruCtl ctl, int pageno, int slotno, 
SlruFlush fdata)
        if (!fdata)
        {
                pgstat_report_wait_start(WAIT_EVENT_SLRU_SYNC);
-               if (ctl->do_fsync && pg_fsync(fd))
+               if (ctl->do_fsync && pg_fsync(fd) < 0)
                {
                        pgstat_report_wait_end();
                        slru_errcause = SLRU_FSYNC_FAILED;
@@ -879,7 +879,7 @@ SlruPhysicalWritePage(SlruCtl ctl, int pageno, int slotno, 
SlruFlush fdata)
                }
                pgstat_report_wait_end();
 
-               if (CloseTransientFile(fd))
+               if (CloseTransientFile(fd) < 0)
                {
                        slru_errcause = SLRU_CLOSE_FAILED;
                        slru_errno = errno;
@@ -1150,7 +1150,7 @@ SimpleLruFlush(SlruCtl ctl, bool allow_redirtied)
        for (i = 0; i < fdata.num_files; i++)
        {
                pgstat_report_wait_start(WAIT_EVENT_SLRU_FLUSH_SYNC);
-               if (ctl->do_fsync && pg_fsync(fdata.fd[i]))
+               if (ctl->do_fsync && pg_fsync(fdata.fd[i]) < 0)
                {
                        slru_errcause = SLRU_FSYNC_FAILED;
                        slru_errno = errno;
@@ -1159,7 +1159,7 @@ SimpleLruFlush(SlruCtl ctl, bool allow_redirtied)
                }
                pgstat_report_wait_end();
 
-               if (CloseTransientFile(fdata.fd[i]))
+               if (CloseTransientFile(fdata.fd[i]) < 0)
                {
                        slru_errcause = SLRU_CLOSE_FAILED;
                        slru_errno = errno;
-- 
2.22.0

Reply via email to