aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/storage/file/fd.c73
1 files changed, 61 insertions, 12 deletions
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index 173476789c7..db39186f058 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -415,10 +415,18 @@ pg_fsync(int fd)
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;
}
/*
@@ -448,10 +456,18 @@ pg_fsync_writethrough(int fd)
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;
}
/*
@@ -483,6 +499,7 @@ pg_flush_data(int fd, off_t offset, off_t nbytes)
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
@@ -498,6 +515,9 @@ pg_flush_data(int fd, off_t offset, off_t nbytes)
{
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
@@ -630,31 +650,53 @@ pg_flush_data(int fd, off_t offset, off_t nbytes)
}
/*
+ * 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;
}
/*
@@ -2001,11 +2043,15 @@ FilePrefetch(File file, off_t offset, off_t amount, uint32 wait_event_info)
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));
@@ -2281,12 +2327,15 @@ FileFallocate(File file, off_t offset, off_t amount, uint32 wait_event_info)
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;
@@ -2334,7 +2383,7 @@ FileTruncate(File file, off_t offset, uint32 wait_event_info)
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)