aboutsummaryrefslogtreecommitdiff
path: root/src/util.cpp
diff options
context:
space:
mode:
authorWladimir J. van der Laan <[email protected]>2018-04-20 11:21:08 +0200
committerWladimir J. van der Laan <[email protected]>2018-04-23 14:25:28 +0200
commitcf0277928fa8d955d75f661021845789194dfff7 (patch)
treeda392672c936ad9f6a91c2d77c4377a22ac127d4 /src/util.cpp
parentMerge #13021: MOVEONLY: Move logging code from util.{h,cpp} to new files. (diff)
downloaddiscoin-cf0277928fa8d955d75f661021845789194dfff7.tar.xz
discoin-cf0277928fa8d955d75f661021845789194dfff7.zip
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.cpp28
1 files changed, 22 insertions, 6 deletions
diff --git a/src/util.cpp b/src/util.cpp
index 4fb027b73..9a3067259 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) {