1
0
mirror of https://github.com/postgres/postgres.git synced 2025-04-29 13:56:47 +03:00

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.
This commit is contained in:
Andres Freund 2014-11-15 01:09:05 +01:00
parent 79b2fa5bd2
commit b0a48e996b
3 changed files with 57 additions and 59 deletions

View File

@ -38,9 +38,6 @@
#endif #endif
static void fsync_fname(char *fname, bool isdir);
/* /*
* copydir: copy a directory * copydir: copy a directory
* *
@ -214,59 +211,3 @@ copy_file(char *fromfile, char *tofile)
pfree(buffer); 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);
}

View File

@ -345,6 +345,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 = 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);
}
/* /*
* InitFileAccess --- initialize this module during backend startup * InitFileAccess --- initialize this module during backend startup
* *

View File

@ -99,6 +99,7 @@ extern int pg_fsync_no_writethrough(int fd);
extern int pg_fsync_writethrough(int fd); extern int pg_fsync_writethrough(int fd);
extern int pg_fdatasync(int fd); extern int pg_fdatasync(int fd);
extern int pg_flush_data(int fd, off_t offset, off_t amount); 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 */ /* Filename components for OpenTemporaryFile */
#define PG_TEMP_FILES_DIR "pgsql_tmp" #define PG_TEMP_FILES_DIR "pgsql_tmp"