From b5a97ad86e81e3bd8ff325ea991459c5f262b245 Mon Sep 17 00:00:00 2001 From: edef Date: Thu, 28 Apr 2022 21:40:08 +0000 Subject: ripple/fossil: ensure durability of add_path sled doesn't actually promise not to eat your data until you invoke flush. This is observable under normal circumstances as add_path occasionally just not committing anything to the store. While we're at it, ensure we're syncing the chunks file data to disk, so the database *might* actually be consistent. We're not going for full crash-correctness yet, mostly for performance and complexity reasons. Change-Id: I6cc69a013dc18cd50df26e73801b185de596565c --- ripple/fossil/src/lib.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'ripple/fossil') diff --git a/ripple/fossil/src/lib.rs b/ripple/fossil/src/lib.rs index 4cea16a..c79105c 100644 --- a/ripple/fossil/src/lib.rs +++ b/ripple/fossil/src/lib.rs @@ -66,6 +66,20 @@ impl Store { pub fn add_path(&self, path: impl AsRef) -> Node { let path = path.as_ref(); + let node = self.add_path_inner(path); + + // NOTE: sled *can* flush without us explicitly asking for it, so it's + // possible for the store to end up containing pointers to chunks that + // aren't fsynced yet. The easiest fix is to always `chunks_file.sync_data()` + // before we write anything to the database, but that's kind of a performance hazard. + // TODO(edef): keep pending and known-durable blobs/chunks separate in the database + self.chunks_file.borrow_mut().sync_data().unwrap(); + self.meta.flush().unwrap(); + + node + } + + fn add_path_inner(&self, path: &Path) -> Node { let meta = fs::symlink_metadata(path).unwrap(); match meta.file_type() { @@ -151,7 +165,6 @@ impl Store { buf }; - // TODO(edef): figure out fsync for durability (&self.blobs, &self.chunks, &self.meta) .transaction(|(blobs, chunks, meta)| { chunks.apply_batch(&batch)?; -- cgit 1.4.1