diff options
author | Andres Freund <andres@anarazel.de> | 2014-11-15 01:09:05 +0100 |
---|---|---|
committer | Andres Freund <andres@anarazel.de> | 2014-11-15 01:20:29 +0100 |
commit | c7299d32f64d09cfc1f586bdb7902b02259ff202 (patch) | |
tree | f24562cda537a02bb4bc5fdf037d434f6ffaa8fe /src/backend/storage/file/fd.c | |
parent | d45e8dc527f9e66c56dd91ae3e79eac1b094b96e (diff) | |
download | postgresql-c7299d32f64d09cfc1f586bdb7902b02259ff202.tar.gz postgresql-c7299d32f64d09cfc1f586bdb7902b02259ff202.zip |
Backport "Expose fsync_fname as a public API".
Backport commit cc52d5b33ff5df29de57dcae9322214cfe9c8464 back to 9.1
to allow backpatching some unlogged table fixes that use fsync_fname.
Diffstat (limited to 'src/backend/storage/file/fd.c')
-rw-r--r-- | src/backend/storage/file/fd.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c index fa0054701cd..0777a15c900 100644 --- a/src/backend/storage/file/fd.c +++ b/src/backend/storage/file/fd.c @@ -385,6 +385,62 @@ pg_flush_data(int fd, off_t offset, off_t amount) /* + * fsync_fname -- fsync a file or directory, handling errors properly + * + * Try to fsync a file or directory. When doing the latter, ignore errors that + * indicate the OS just doesn't allow/require fsyncing directories. + */ +void +fsync_fname(char *fname, bool isdir) +{ + int fd; + int returncode; + + /* + * Some OSs require directories to be opened read-only whereas other + * systems don't allow us to fsync files opened read-only; so we need both + * cases here + */ + if (!isdir) + fd = OpenTransientFile(fname, + O_RDWR | PG_BINARY, + S_IRUSR | S_IWUSR); + else + fd = OpenTransientFile(fname, + O_RDONLY | PG_BINARY, + S_IRUSR | S_IWUSR); + + /* + * Some OSs don't allow us to open directories at all (Windows returns + * EACCES) + */ + if (fd < 0 && isdir && (errno == EISDIR || errno == EACCES)) + return; + + else if (fd < 0) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not open file \"%s\": %m", fname))); + + returncode = pg_fsync(fd); + + /* Some OSs don't allow us to fsync directories at all */ + if (returncode != 0 && isdir && errno == EBADF) + { + CloseTransientFile(fd); + return; + } + + if (returncode != 0) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not fsync file \"%s\": %m", fname))); + + CloseTransientFile(fd); +} + + +/* * InitFileAccess --- initialize this module during backend startup * * This is called during either normal or standalone backend start. |