diff options
author | Teodor Sigaev <teodor@sigaev.ru> | 2017-03-27 19:33:01 +0300 |
---|---|---|
committer | Teodor Sigaev <teodor@sigaev.ru> | 2017-03-27 19:33:01 +0300 |
commit | 1b02be21f271db6bd3cd43abb23fa596fcb6bac3 (patch) | |
tree | 1052877089af6b9cf2c8cc4f91d365147de40575 /src/backend/storage/file/fd.c | |
parent | 1f171a1803c28d3ae24636c9ca3352ec82c39e5f (diff) | |
download | postgresql-1b02be21f271db6bd3cd43abb23fa596fcb6bac3.tar.gz postgresql-1b02be21f271db6bd3cd43abb23fa596fcb6bac3.zip |
Fsync directory after creating or unlinking file.
If file was created/deleted just before powerloss it's possible that
file system will miss that. To prevent it, call fsync() where creating/
unlinkg file is critical.
Author: Michael Paquier
Reviewed-by: Ashutosh Bapat, Takayuki Tsunakawa, me
Diffstat (limited to 'src/backend/storage/file/fd.c')
-rw-r--r-- | src/backend/storage/file/fd.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c index f0ed2e9b5f4..b14979496c7 100644 --- a/src/backend/storage/file/fd.c +++ b/src/backend/storage/file/fd.c @@ -658,6 +658,43 @@ durable_rename(const char *oldfile, const char *newfile, int elevel) } /* + * durable_unlink -- remove a file in a durable manner + * + * This routine ensures that, after returning, the effect of removing file + * persists in case of a crash. A crash while this routine is running will + * leave the system in no mixed state. + * + * It does so by using fsync on the parent directory of the file after the + * actual removal is done. + * + * Log errors with the severity specified by caller. + * + * Returns 0 if the operation succeeded, -1 otherwise. Note that errno is not + * valid upon return. + */ +int +durable_unlink(const char *fname, int elevel) +{ + if (unlink(fname) < 0) + { + ereport(elevel, + (errcode_for_file_access(), + errmsg("could not remove file \"%s\": %m", + fname))); + return -1; + } + + /* + * To guarantee that the removal of the file is persistent, fsync + * its parent directory. + */ + if (fsync_parent_path(fname, elevel) != 0) + return -1; + + return 0; +} + +/* * durable_link_or_rename -- rename a file in a durable manner. * * Similar to durable_rename(), except that this routine tries (but does not |