From: Robert Haas Date: Mon, 4 May 2015 16:52:29 +0000 (-0400) Subject: Backport "Expose fsync_fname as a public API". X-Git-Tag: REL9_0_20~27 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f1d7516770739e1af5cf517c01aa3bfa7b02b86b;p=thirdparty%2Fpostgresql.git Backport "Expose fsync_fname as a public API". Backport commit b0a48e996bd7ff336ea26344d3d97ad32b22a61a back to 9.0 to allow back-patching another fix that uses fsync_fname. --- diff --git a/src/backend/storage/file/copydir.c b/src/backend/storage/file/copydir.c index fe44180c937..7299d78ed44 100644 --- a/src/backend/storage/file/copydir.c +++ b/src/backend/storage/file/copydir.c @@ -38,7 +38,6 @@ static void copy_file(char *fromfile, char *tofile); -static void fsync_fname(char *fname, bool isdir); /* @@ -214,59 +213,3 @@ copy_file(char *fromfile, char *tofile) pfree(buffer); } - - -/* - * fsync a file - * - * Try to fsync directories but ignore errors that indicate the OS - * just doesn't allow/require fsyncing directories. - */ -static 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 = BasicOpenFile(fname, - O_RDWR | PG_BINARY, - S_IRUSR | S_IWUSR); - else - fd = BasicOpenFile(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) - { - close(fd); - return; - } - - if (returncode != 0) - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not fsync file \"%s\": %m", fname))); - - close(fd); -} diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c index 4364340845f..ba80f70e083 100644 --- a/src/backend/storage/file/fd.c +++ b/src/backend/storage/file/fd.c @@ -1948,3 +1948,59 @@ RemovePgTempFilesInDir(const char *tmpdirname) FreeDir(temp_dir); } + + +/* + * fsync a file + * + * Try to fsync directories but 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 = BasicOpenFile(fname, + O_RDWR | PG_BINARY, + S_IRUSR | S_IWUSR); + else + fd = BasicOpenFile(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) + { + close(fd); + return; + } + + if (returncode != 0) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not fsync file \"%s\": %m", fname))); + + close(fd); +} diff --git a/src/include/storage/fd.h b/src/include/storage/fd.h index 5798ee38565..014e0f86679 100644 --- a/src/include/storage/fd.h +++ b/src/include/storage/fd.h @@ -99,6 +99,7 @@ extern int pg_fsync_no_writethrough(int fd); extern int pg_fsync_writethrough(int fd); extern int pg_fdatasync(int fd); extern int pg_flush_data(int fd, off_t offset, off_t amount); +extern void fsync_fname(char *fname, bool isdir); /* Filename components for OpenTemporaryFile */ #define PG_TEMP_FILES_DIR "pgsql_tmp"