-
Notifications
You must be signed in to change notification settings - Fork 37.7k
Fix possible data race when committing block files #14501
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
(GitHub and DrahtBot are misdetecting a rebase needed here; it is a clean merge still... can't at least DrahtBot get fixed??) |
You have to move |
git follows the move just fine. |
@luke-jr There are different merge strategies and flags (https://git-scm.com/docs/git-merge#git-merge-mergetool) and GitHub uses a rather strict one, which they were unable to disclose to me. It appear that this pull request hasn't had any review yet, so doing a rebase comes at no cost at all. |
There hasn't been much activity lately and the patch still needs rebase, so I am closing this for now. Please let me know when you want to continue working on this, so the pull request can be re-opened. |
Rebased |
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsNo conflicts as of last run. |
Is this still being worked on? With #19614 recently merged, all that needs to be done is add the I saw the previous discussion about if calling fsync on an unchanged directory has overhead, and my understanding is that the directory's dirty bit will not be set, so no disk writes will occur. Therefore, the current method looks good to me. |
Rebased and added a fix for #19614 (which was completely broken) |
…sequence of #elif This should not change the actual code generation.
It was recently pointed out to me that calling fsync() or fdatasync() on a new file is not sufficient to ensure it's persisted to disk, a the existence of the file itself is stored in the directory inode. This means that ensuring that a new file is actually committed also requires an fsync() on the parent directory. This change ensures that we call fsync() on the blocks directory after committing new block files.
… LevelDB c4b85ba Bugfix: Define and use HAVE_FDATASYNC correctly outside LevelDB (Luke Dashjr) Pull request description: Fixes a bug introduced in #19614 The LevelDB-specific fdatasync check was only using `AC_SUBST`, which works for Makefiles, but doesn't define anything for C++. Furthermore, the #define is typically 0 or 1, never undefined. This fixes both issues by defining it and checking its value instead of whether it is merely defined. Pulled out of #14501 by fanquake's request ACKs for top commit: fanquake: ACK c4b85ba - thanks for catching and fixing my mistake. laanwj: Code review ACK c4b85ba Tree-SHA512: 91d5d426ba000b4f3ee7e2315635e24bbb23ceff16269ddf4f65a63d25fc9e9cf94a3b236eed2f8031cc36ddcf78aeb5916efcb244f415943a8a12f907ede8f9
…outside LevelDB c4b85ba Bugfix: Define and use HAVE_FDATASYNC correctly outside LevelDB (Luke Dashjr) Pull request description: Fixes a bug introduced in bitcoin#19614 The LevelDB-specific fdatasync check was only using `AC_SUBST`, which works for Makefiles, but doesn't define anything for C++. Furthermore, the #define is typically 0 or 1, never undefined. This fixes both issues by defining it and checking its value instead of whether it is merely defined. Pulled out of bitcoin#14501 by fanquake's request ACKs for top commit: fanquake: ACK c4b85ba - thanks for catching and fixing my mistake. laanwj: Code review ACK c4b85ba Tree-SHA512: 91d5d426ba000b4f3ee7e2315635e24bbb23ceff16269ddf4f65a63d25fc9e9cf94a3b236eed2f8031cc36ddcf78aeb5916efcb244f415943a8a12f907ede8f9
FILE* file = fsbridge::fopen(dirname, "r"); | ||
if (file) { | ||
fsync(fileno(file)); | ||
fclose(file); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about log the possible errors here? E.g.
Lines 1033 to 1034 in 0adb80f
if (fsync(fileno(file)) != 0 && errno != EINVAL) { | |
LogPrintf("%s: fsync failed: %d\n", __func__, errno); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you do that, please restrict it to logging once. Logging fsync errors every time can get very verbose on some network file systems otherwise, which have lots of corner cases with regard to synchronization (more so on directories, we had to patch leveldb for this once).
Code review ACK ef71229 |
ef71229 util: Check for file being NULL in DirectoryCommit (Luke Dashjr) 4574904 Fix possible data race when committing block files (Evan Klitzke) 220bb16 util: Introduce DirectoryCommit commit function to sync a directory (Evan Klitzke) ce5cbae util.h: Document FileCommit function (Evan Klitzke) 844d650 util: Prefer Mac-specific F_FULLSYNC over fdatasync in FileCommit (Evan Klitzke) f6cec0b util: Refactor FileCommit from an #if sequence nested in #else, to a sequence of #elif (Evan Klitzke) Pull request description: Reviving bitcoin#12696 ACKs for top commit: laanwj: Code review ACK ef71229 Tree-SHA512: 07d650990ef4c18d645dee3f9a199a940683ad17557d79d93979a76c4e710d8d70e6eae01d1a5991494a24a7654eb7db868be0c34a31e70b2509945d95bc9cce
Reviving #12696