Tolerate ENOSYS failure from sync_file_range().

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
This commit is contained in:
Thomas Munro 2019-02-24 13:38:15 +13:00
parent f275225539
commit 483520eca4
1 changed files with 20 additions and 1 deletions

View 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")));
}