From 6058c83dc68ceb2bc4a3cbee15ecca2ef7c270e7 Mon Sep 17 00:00:00 2001 From: dignifiedquire Date: Tue, 12 Nov 2019 18:59:03 +0100 Subject: [PATCH] fix(sector-builder): avoid renaming between filesystems --- sector-builder/src/kv_store/fs.rs | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/sector-builder/src/kv_store/fs.rs b/sector-builder/src/kv_store/fs.rs index 169f459..cf44266 100644 --- a/sector-builder/src/kv_store/fs.rs +++ b/sector-builder/src/kv_store/fs.rs @@ -34,15 +34,28 @@ impl KeyValueStore for FileSystemKvs { } fn put(&self, key: &[u8], value: &[u8]) -> Result<()> { - let nt_file = tempfile::NamedTempFile::new()?; - let (mut file, oldpath) = nt_file.keep()?; - - file.write_all(value)?; - - let newpath = self.key_to_path(key); + let new_path = self.key_to_path(key); + let tmp_path = new_path.with_extension(".tmp"); + + { + let mut file = File::create(&tmp_path)?; + match file.write_all(value) { + Ok(_) => {} + Err(err) => { + fs::remove_file(&tmp_path)?; + return Err(err.into()); + } + } + } // if newpath already exists, it will be atomically replaced - std::fs::rename(oldpath, newpath).map_err(Into::into) + match std::fs::rename(&tmp_path, new_path) { + Ok(_) => Ok(()), + Err(err) => { + fs::remove_file(&tmp_path)?; + Err(err.into()) + } + } } fn get(&self, key: &[u8]) -> Result>> {