]> granicus.if.org Git - postgresql/commitdiff
Tolerate ENOSYS failure from sync_file_range().
authorThomas Munro <tmunro@postgresql.org>
Sun, 24 Feb 2019 00:38:15 +0000 (13:38 +1300)
committerThomas Munro <tmunro@postgresql.org>
Sun, 24 Feb 2019 09:37:20 +0000 (22:37 +1300)
One unintended consequence of commit 9ccdd7f6 was that Windows WSL
users started getting a panic whenever we tried to initiate data
flushing with sync_file_range(), because WSL does not implement that
system call.  Previously, they got a stream of periodic warnings,
which was also undesirable but at least ignorable.

Prevent the panic by handling ENOSYS specially and skipping the panic
promotion with data_sync_elevel().  Also suppress future attempts
after the first such failure so that the pre-existing problem of
noisy warnings is improved.

Back-patch to 9.6 (older branches were not affected in this way by
9ccdd7f6).

Author: Thomas Munro and James Sewell
Tested-by: James Sewell
Reported-by: Bruce Klein
Discussion: https://postgr.es/m/CA+mCpegfOUph2U4ZADtQT16dfbkjjYNJL1bSTWErsazaFjQW9A@mail.gmail.com

src/backend/storage/file/fd.c

index 213de7698a4c6af0fba8d5c21c970aaeab247651..d46639d2edeeed9695a9a7efb39644bb503b0709 100644 (file)
@@ -420,6 +420,10 @@ pg_flush_data(int fd, off_t offset, off_t nbytes)
 #if defined(HAVE_SYNC_FILE_RANGE)
        {
                int                     rc;
+               static bool not_implemented_by_kernel = false;
+
+               if (not_implemented_by_kernel)
+                       return;
 
                /*
                 * sync_file_range(SYNC_FILE_RANGE_WRITE), currently linux specific,
@@ -434,7 +438,22 @@ pg_flush_data(int fd, off_t offset, off_t nbytes)
                                                         SYNC_FILE_RANGE_WRITE);
                if (rc != 0)
                {
-                       ereport(data_sync_elevel(WARNING),
+                       int                     elevel;
+
+                       /*
+                        * For systems that don't have an implementation of
+                        * sync_file_range() such as Windows WSL, generate only one
+                        * warning and then suppress all further attempts by this process.
+                        */
+                       if (errno == ENOSYS)
+                       {
+                               elevel = WARNING;
+                               not_implemented_by_kernel = true;
+                       }
+                       else
+                               elevel = data_sync_elevel(WARNING);
+
+                       ereport(elevel,
                                        (errcode_for_file_access(),
                                         errmsg("could not flush dirty data: %m")));
                }