diff options
author | Wladimir J. van der Laan <laanwj@gmail.com> | 2018-04-20 11:21:08 +0200 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@gmail.com> | 2018-04-23 14:25:28 +0200 |
commit | cf0277928fa8d955d75f661021845789194dfff7 (patch) | |
tree | da392672c936ad9f6a91c2d77c4377a22ac127d4 /src/util.cpp | |
parent | 8b262eb2d80bfa27ae8501078ce47bc1407e9c55 (diff) |
Add logging and error handling for file syncing
Add logging and error handling inside, and outside of FileCommit.
Functions such as fsync, fdatasync will return error in case of hardware
I/O errors, and ignoring this means it can silently continue through
data corruption. (c.f.
https://lwn.net/SubscriberLink/752063/12b232ab5039efbe/)
Diffstat (limited to 'src/util.cpp')
-rw-r--r-- | src/util.cpp | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/src/util.cpp b/src/util.cpp index 4fb027b731..9a3067259f 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -788,21 +788,37 @@ bool TryCreateDirectories(const fs::path& p) return false; } -void FileCommit(FILE *file) +bool FileCommit(FILE *file) { - fflush(file); // harmless if redundantly called + if (fflush(file) != 0) { // harmless if redundantly called + LogPrintf("%s: fflush failed: %d\n", __func__, errno); + return false; + } #ifdef WIN32 HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(file)); - FlushFileBuffers(hFile); + if (FlushFileBuffers(hFile) == 0) { + LogPrintf("%s: FlushFileBuffers failed: %d\n", __func__, GetLastError()); + return false; + } #else #if defined(__linux__) || defined(__NetBSD__) - fdatasync(fileno(file)); + if (fdatasync(fileno(file)) != 0 && errno != EINVAL) { // Ignore EINVAL for filesystems that don't support sync + LogPrintf("%s: fdatasync failed: %d\n", __func__, errno); + return false; + } #elif defined(__APPLE__) && defined(F_FULLFSYNC) - fcntl(fileno(file), F_FULLFSYNC, 0); + if (fcntl(fileno(file), F_FULLFSYNC, 0) == -1) { // Manpage says "value other than -1" is returned on success + LogPrintf("%s: fcntl F_FULLFSYNC failed: %d\n", __func__, errno); + return false; + } #else - fsync(fileno(file)); + if (fsync(fileno(file)) != 0 && errno != EINVAL) { + LogPrintf("%s: fsync failed: %d\n", __func__, errno); + return false; + } #endif #endif + return true; } bool TruncateFile(FILE *file, unsigned int length) { |