int
pg_fsync_no_writethrough(int fd)
{
- if (enableFsync)
- return fsync(fd);
- else
+ int rc;
+
+ if (!enableFsync)
return 0;
+
+retry:
+ rc = fsync(fd);
+
+ if (rc == -1 && errno == EINTR)
+ goto retry;
+
+ return rc;
}
/*
int
pg_fdatasync(int fd)
{
- if (enableFsync)
- return fdatasync(fd);
- else
+ int rc;
+
+ if (!enableFsync)
return 0;
+
+retry:
+ rc = fdatasync(fd);
+
+ if (rc == -1 && errno == EINTR)
+ goto retry;
+
+ return rc;
}
/*
if (not_implemented_by_kernel)
return;
+retry:
/*
* sync_file_range(SYNC_FILE_RANGE_WRITE), currently linux specific,
* tells the OS that writeback for the specified blocks should be
{
int elevel;
+ if (rc == EINTR)
+ goto retry;
+
/*
* For systems that don't have an implementation of
* sync_file_range() such as Windows WSL, generate only one
#endif
}
+/*
+ * Truncate an open file to a given length.
+ */
+static int
+pg_ftruncate(int fd, off_t length)
+{
+ int ret;
+
+retry:
+ ret = ftruncate(fd, length);
+
+ if (ret == -1 && errno == EINTR)
+ goto retry;
+
+ return ret;
+}
+
/*
* Truncate a file to a given length by name.
*/
int
pg_truncate(const char *path, off_t length)
{
+ int ret;
#ifdef WIN32
int save_errno;
- int ret;
int fd;
fd = OpenTransientFile(path, O_RDWR | PG_BINARY);
if (fd >= 0)
{
- ret = ftruncate(fd, length);
+ ret = pg_ftruncate(fd, length);
save_errno = errno;
CloseTransientFile(fd);
errno = save_errno;
}
else
ret = -1;
-
- return ret;
#else
- return truncate(path, length);
+
+retry:
+ ret = truncate(path, length);
+
+ if (ret == -1 && errno == EINTR)
+ goto retry;
#endif
+
+ return ret;
}
/*
if (returnCode < 0)
return returnCode;
+retry:
pgstat_report_wait_start(wait_event_info);
returnCode = posix_fadvise(VfdCache[file].fd, offset, amount,
POSIX_FADV_WILLNEED);
pgstat_report_wait_end();
+ if (returnCode == EINTR)
+ goto retry;
+
return returnCode;
#else
Assert(FileIsValid(file));
if (returnCode < 0)
return -1;
+retry:
pgstat_report_wait_start(wait_event_info);
returnCode = posix_fallocate(VfdCache[file].fd, offset, amount);
pgstat_report_wait_end();
if (returnCode == 0)
return 0;
+ else if (returnCode == EINTR)
+ goto retry;
/* for compatibility with %m printing etc */
errno = returnCode;
return returnCode;
pgstat_report_wait_start(wait_event_info);
- returnCode = ftruncate(VfdCache[file].fd, offset);
+ returnCode = pg_ftruncate(VfdCache[file].fd, offset);
pgstat_report_wait_end();
if (returnCode == 0 && VfdCache[file].fileSize > offset)