From: Paul Eggert Date: Tue, 23 Feb 2016 07:21:49 +0000 (-0800) Subject: fsync output file before closing X-Git-Tag: v1.7~24 X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=22aac8f8a616a72dbbe0e4119db8ddda0f076c04;p=debian%2Fgzip fsync output file before closing 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. --- 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