aboutsummaryrefslogtreecommitdiff
path: root/src/backend/storage/file/fd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/storage/file/fd.c')
-rw-r--r--src/backend/storage/file/fd.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index a340a5f6afe..0792c08ce1b 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -1057,10 +1057,46 @@ BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
int fd;
tryAgain:
+#ifdef PG_O_DIRECT_USE_F_NOCACHE
+
+ /*
+ * The value we defined to stand in for O_DIRECT when simulating it with
+ * F_NOCACHE had better not collide with any of the standard flags.
+ */
+ StaticAssertStmt((PG_O_DIRECT &
+ (O_APPEND |
+ O_CLOEXEC |
+ O_CREAT |
+ O_DSYNC |
+ O_RDWR |
+ O_RDONLY |
+ O_SYNC |
+ O_TRUNC |
+ O_WRONLY)) == 0,
+ "PG_O_DIRECT value collides with standard flag");
+ fd = open(fileName, fileFlags & ~PG_O_DIRECT, fileMode);
+#else
fd = open(fileName, fileFlags, fileMode);
+#endif
if (fd >= 0)
+ {
+#ifdef PG_O_DIRECT_USE_F_NOCACHE
+ if (fileFlags & PG_O_DIRECT)
+ {
+ if (fcntl(fd, F_NOCACHE, 1) < 0)
+ {
+ int save_errno = errno;
+
+ close(fd);
+ errno = save_errno;
+ return -1;
+ }
+ }
+#endif
+
return fd; /* success! */
+ }
if (errno == EMFILE || errno == ENFILE)
{