diff --git a/lib/util/dirutil.c b/lib/util/dirutil.c index fcccc4cc..56a8a3dc 100644 --- a/lib/util/dirutil.c +++ b/lib/util/dirutil.c @@ -60,6 +60,38 @@ dirutil_fsyncdir(const char * path) return (0); } +/** + * dirutil_fsync(fp, name): + * Attempt to write the contents of ${fp} to disk. Do not close ${fp}. + * + * Caveat: "Disks lie" - Kirk McKusick. + */ +int +dirutil_fsync(FILE * fp, const char * name) +{ + int fd; + + if (fflush(fp)) { + warnp("fflush(%s)", name); + goto err0; + } + if ((fd = fileno(fp)) == -1) { + warnp("fileno(%s)", name); + goto err0; + } + if (fsync(fd)) { + warnp("fsync(%s)", name); + goto err0; + } + + /* Success! */ + return (0); + +err0: + /* Failure! */ + return (-1); +} + /** * build_dir(dir, diropt): * Make sure that ${dir} exists, creating it (and any parents) as necessary. diff --git a/lib/util/dirutil.h b/lib/util/dirutil.h index b602ceb7..98cf43f0 100644 --- a/lib/util/dirutil.h +++ b/lib/util/dirutil.h @@ -7,6 +7,14 @@ */ int dirutil_fsyncdir(const char *); +/** + * dirutil_fsync(fp, name): + * Attempt to write the contents of ${fp} to disk. Do not close ${fp}. + * + * Caveat: "Disks lie" - Kirk McKusick. + */ +int dirutil_fsync(FILE *, const char *); + /** * build_dir(dir, diropt): * Make sure that ${dir} exists, creating it (and any parents) as necessary. diff --git a/tar/ccache/ccache_write.c b/tar/ccache/ccache_write.c index a010ed75..cfb9dd01 100644 --- a/tar/ccache/ccache_write.c +++ b/tar/ccache/ccache_write.c @@ -12,6 +12,7 @@ #include "asprintf.h" #include "ccache_internal.h" +#include "dirutil.h" #include "multitape_internal.h" #include "patricia.h" #include "sysendian.h" @@ -266,6 +267,10 @@ ccache_write(CCACHE * cache, const char * path) goto err2; } + /* Finish writing the file. */ + if (dirutil_fsync(W.f, W.s)) + goto err2; + /* Close the file. */ if (fclose(W.f)) warnp("fclose"); diff --git a/tar/chunks/chunks_directory.c b/tar/chunks/chunks_directory.c index f2170573..b20b8038 100644 --- a/tar/chunks/chunks_directory.c +++ b/tar/chunks/chunks_directory.c @@ -319,7 +319,6 @@ chunks_directory_write(const char * cachepath, RWHASHTAB * HT, struct chunkstats_external cse; FILE * f; char * s; - int fd; /* The caller must pass the cachepath, and a suffix to use. */ assert(cachepath != NULL); @@ -351,18 +350,8 @@ chunks_directory_write(const char * cachepath, RWHASHTAB * HT, goto err2; /* Call fsync on the new chunk directory and close it. */ - if (fflush(f)) { - warnp("fflush(%s)", s); + if (dirutil_fsync(f, s)) goto err2; - } - if ((fd = fileno(f)) == -1) { - warnp("fileno(%s)", s); - goto err2; - } - if (fsync(fd)) { - warnp("fsync(%s)", s); - goto err2; - } if (fclose(f)) { warnp("fclose(%s)", s); goto err1;