Thanks for reporting the problem. It's annoying that gzip must invoke fsync, as
that's way overkill compared to the write-ordering that is needed and fsync will
slow gzip down, but I don't see any safe and reasonably portable alternative so
I installed the attached patch on Savannah, here:
http://git.savannah.gnu.org/cgit/gzip.git/commit/?id=22aac8f8a616a72dbbe0e4119db8ddda0f076c04
From c8367d7660239b1aedce7850c766c0c0f8938d1c Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Mon, 22 Feb 2016 23:21:49 -0800
Subject: [PATCH] fsync output file before closing
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Problem reported by Yanyan Jiang 蒋炎岩 in: http://bugs.gnu.org/22768
* NEWS: Document this.
* bootstrap.conf (gnulib_modules): Add fsync.
* gzip.c (treat_file): Call fsync just before closing the output.
* lib/.gitignore, m4/.gitignore: Add fsync-related gnulib files.
---
NEWS | 4 ++++
bootstrap.conf | 1 +
gzip.c | 11 ++++++++++-
lib/.gitignore | 1 +
m4/.gitignore | 1 +
5 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/NEWS b/NEWS
index a1c668f..31472cc 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,10 @@ GNU gzip NEWS -*- outline
-*-
** Changes in behavior
+ When acting in-place, gzip now fsyncs the output before closing it.
+ This is slower, but on many file systems it is safer if the system
+ is about to crash.
+
The GZIP environment variable is now obsolescent; gzip now warns if
it is used, and rejects attempts to use dangerous options or operands.
You can use an alias or script instead.
diff --git a/bootstrap.conf b/bootstrap.conf
index 13a485d..b15caa3 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -31,6 +31,7 @@ fcntl-safer
fdl
fdopendir
fprintf-posix
+fsync
getopt-gnu
git-version-gen
gitlog-to-changelog
diff --git a/gzip.c b/gzip.c
index a013540..b872383 100644
--- a/gzip.c
+++ b/gzip.c
@@ -926,8 +926,17 @@ local void treat_file(iname)
if (!to_stdout)
{
-
copy_stat (&istat);
+
+ /* Transfer output data to the output file's storage device.
+ Otherwise, if the system crashed now the user might lose
+ both input and output data. See: Pillai TS et al. All
+ file systems are not created equal: on the complexity of
+ crafting crash-consistent applications. OSDI'14. 2014:433-48.
+
https://www.usenix.org/conference/osdi14/technical-sessions/presentation/pillai
*/
+ if (!keep && fsync (ofd) != 0 && errno != EINVAL)
+ write_error ();
+
if (close (ofd) != 0)
write_error ();
diff --git a/lib/.gitignore b/lib/.gitignore
index 81d94ff..a368a26 100644
--- a/lib/.gitignore
+++ b/lib/.gitignore
@@ -225,3 +225,4 @@
/xsize.h
/yesno.c
/yesno.h
+/fsync.c
diff --git a/m4/.gitignore b/m4/.gitignore
index 660b926..32f5566 100644
--- a/m4/.gitignore
+++ b/m4/.gitignore
@@ -150,3 +150,4 @@
/xalloc.m4
/xsize.m4
/yesno.m4
+/fsync.m4
--
2.5.0