Skip to content

Commit 96cb827

Browse files
committed
MB-61458: close even if fsync fails
Tweak close path so that an fsync failure before close still reaches the close Change-Id: I4a0dfe55ce25d56386b32cdde811a176c0c25cef Reviewed-on: https://review.couchbase.org/c/platform/+/239027 Reviewed-by: Trond Norbye <trond.norbye@couchbase.com> Tested-by: Build Bot <build@couchbase.com>
1 parent 7e6e0e1 commit 96cb827

2 files changed

Lines changed: 23 additions & 2 deletions

File tree

include/platform/file_sink.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ class FileSink : public Sink {
8181
}
8282

8383
protected:
84+
// @return errno if fsync fails, 0 if successful
85+
int fsync_no_throw() noexcept;
86+
8487
const std::filesystem::path filename;
8588
FILE* fp = nullptr;
8689
const std::size_t fsync_interval;

src/file_sink.cc

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,25 @@ std::size_t FileSink::fsync() {
7878

7979
std::size_t FileSink::close() {
8080
Expects(fp);
81-
fsync();
81+
// Always attempt to fsync the file before closing it.
82+
auto fsync_errno = fsync_no_throw();
8283
if (fclose(fp) != 0) {
8384
throw std::system_error(
8485
errno,
8586
std::system_category(),
86-
fmt::format("Failed to close file '{}'", filename.string()));
87+
fmt::format("Failed to close file '{}' fsync={}",
88+
filename.string(),
89+
fsync_errno));
8790
}
8891
fp = nullptr;
92+
// failed fsync but closed the file, throw for the fsync error
93+
if (fsync_errno) {
94+
throw std::system_error(
95+
fsync_errno,
96+
std::system_category(),
97+
fmt::format("Failed to fsync file before close '{}'",
98+
filename.string()));
99+
}
89100
return bytes_written;
90101
}
91102

@@ -98,4 +109,11 @@ FileSink::~FileSink() {
98109
}
99110
}
100111
}
112+
113+
int FileSink::fsync_no_throw() noexcept {
114+
if (::fsync(fileno(fp)) == -1) {
115+
return errno;
116+
}
117+
return 0;
118+
}
101119
} // namespace cb::io

0 commit comments

Comments
 (0)