diff options
Diffstat (limited to 'src/backend/storage/file/fd.c')
-rw-r--r-- | src/backend/storage/file/fd.c | 36 |
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) { |