From 6e7137f2821cfb6fcb8279117a289793e9e96b3a Mon Sep 17 00:00:00 2001 From: Zygo Blaxell Date: Tue, 27 Dec 2016 14:10:25 -0500 Subject: [PATCH] bees: work around btrfs fsync bug btrfs provides a flush on rename when the rename target exists, so the fsync is not necessary. In the initialization case (when the rename target does not exist and the implicit flush does not occur), the file may be empty or a hole after a crash. Bees treats this case the same as if the file did not exist. Since this condition occurs for only the first 15 minutes of the lifetime of a bees installation, it's not worth bothering to fix. If we attempt to fsync the file ourselves, on a crash with log replay, btrfs will end up with a directory entry pointing to a non-existent inode. This directory entry cannot be deleted or renamed except by deleting the entire subvol. On large filesystems this bug is triggered by nearly every crash (verified on kernels up to 4.5.7). Remove the fsync to avoid the btrfs bug, and accept the failure mode that occurs in the first 15 minutes after a bees install. Signed-off-by: Zygo Blaxell --- src/bees.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/bees.cc b/src/bees.cc index dafdddc..e86ec4d 100644 --- a/src/bees.cc +++ b/src/bees.cc @@ -394,8 +394,13 @@ BeesStringFile::write(string contents) Fd ofd = openat_or_die(m_dir_fd, tmpname, FLAGS_CREATE_FILE, S_IRUSR | S_IWUSR); BEESNOTE("writing " << tmpname << " in " << name_fd(m_dir_fd)); write_or_die(ofd, contents); +#if 0 + // This triggers too many btrfs bugs. I wish I was kidding. + // Forget snapshots, balance, compression, and dedup: + // the system call you have to fear on btrfs is fsync(). BEESNOTE("fsyncing " << tmpname << " in " << name_fd(m_dir_fd)); DIE_IF_NON_ZERO(fsync(ofd)); +#endif } BEESNOTE("renaming " << tmpname << " to " << m_name << " in FD " << name_fd(m_dir_fd)); BEESTRACE("renaming " << tmpname << " to " << m_name << " in FD " << name_fd(m_dir_fd));