From 1b02be21f271db6bd3cd43abb23fa596fcb6bac3 Mon Sep 17 00:00:00 2001 From: Teodor Sigaev Date: Mon, 27 Mar 2017 19:33:01 +0300 Subject: 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 --- src/backend/storage/file/fd.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'src/backend/storage/file/fd.c') 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 @@ -657,6 +657,43 @@ durable_rename(const char *oldfile, const char *newfile, int elevel) return 0; } +/* + * 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. * -- cgit v1.2.3