aboutsummaryrefslogtreecommitdiff
path: root/src/backend/storage/file/fd.c
diff options
context:
space:
mode:
authorTeodor Sigaev <teodor@sigaev.ru>2017-03-27 19:33:01 +0300
committerTeodor Sigaev <teodor@sigaev.ru>2017-03-27 19:33:01 +0300
commit1b02be21f271db6bd3cd43abb23fa596fcb6bac3 (patch)
tree1052877089af6b9cf2c8cc4f91d365147de40575 /src/backend/storage/file/fd.c
parent1f171a1803c28d3ae24636c9ca3352ec82c39e5f (diff)
downloadpostgresql-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.c37
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