Skip to content

Commit ffa804a

Browse files
authored
Merge pull request #4702 from TheBlueMatt/2026-05-revert-4678
Revert "Prevent stale fs-store writes after lock cleanup"
2 parents c7fcdf6 + ce13095 commit ffa804a

1 file changed

Lines changed: 1 addition & 87 deletions

File tree

lightning-persister/src/fs_store/common.rs

Lines changed: 1 addition & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,7 @@ use std::collections::HashMap;
1111
use std::fs;
1212
use std::io::{ErrorKind, Read, Write};
1313
use std::path::{Path, PathBuf};
14-
#[cfg(test)]
15-
use std::sync::atomic::AtomicBool;
1614
use std::sync::atomic::{AtomicU64, AtomicUsize, Ordering};
17-
#[cfg(test)]
18-
use std::sync::mpsc;
1915
use std::sync::{Arc, Mutex, RwLock};
2016

2117
#[cfg(target_os = "windows")]
@@ -95,20 +91,14 @@ impl FilesystemStoreState {
9591
}
9692

9793
fn get_new_version_and_lock_ref(&self, dest_file_path: PathBuf) -> (Arc<RwLock<u64>>, u64) {
98-
let mut outer_lock = self.inner.locks.lock().unwrap();
99-
100-
// Allocate the version while holding the lock map mutex so that clean_locks cannot remove the entry after a
101-
// version has been reserved but before its lock reference is cloned.
10294
let version = self.next_version.fetch_add(1, Ordering::Relaxed);
10395
if version == u64::MAX {
10496
panic!("FilesystemStore version counter overflowed");
10597
}
106-
#[cfg(test)]
107-
maybe_pause_after_version_allocation(&self.inner, &dest_file_path);
10898

10999
// Get a reference to the inner lock. We do this early so that the arc can double as an in-flight counter for
110100
// cleaning up unused locks.
111-
let inner_lock_ref = Arc::clone(&outer_lock.entry(dest_file_path).or_default());
101+
let inner_lock_ref = self.inner.get_inner_lock_ref(dest_file_path);
112102

113103
(inner_lock_ref, version)
114104
}
@@ -861,79 +851,3 @@ pub(crate) fn get_key_from_dir_entry_path(
861851
},
862852
}
863853
}
864-
865-
#[cfg(test)]
866-
struct VersionAllocatedHook {
867-
dest_file_path: PathBuf,
868-
version_allocated: mpsc::Sender<()>,
869-
continue_write: Mutex<mpsc::Receiver<()>>,
870-
fired: AtomicBool,
871-
}
872-
873-
#[cfg(test)]
874-
static VERSION_ALLOCATED_HOOK: Mutex<Option<Arc<VersionAllocatedHook>>> = Mutex::new(None);
875-
876-
#[cfg(test)]
877-
fn maybe_pause_after_version_allocation(inner: &FilesystemStoreInner, dest_file_path: &Path) {
878-
let hook = VERSION_ALLOCATED_HOOK.lock().unwrap().clone();
879-
if let Some(hook) = hook {
880-
if hook.dest_file_path.as_path() != dest_file_path
881-
|| hook.fired.swap(true, Ordering::AcqRel)
882-
{
883-
return;
884-
}
885-
886-
let version_allocation_holds_lock = inner.locks.try_lock().is_err();
887-
hook.version_allocated.send(()).unwrap();
888-
if !version_allocation_holds_lock {
889-
hook.continue_write.lock().unwrap().recv().unwrap();
890-
}
891-
}
892-
}
893-
894-
#[cfg(test)]
895-
mod tests {
896-
use super::*;
897-
898-
use std::sync::Arc;
899-
use std::thread;
900-
901-
#[test]
902-
fn stale_write_after_lock_cleanup_does_not_overwrite_newer_write() {
903-
let mut temp_path = std::env::temp_dir();
904-
temp_path.push("test_stale_write_after_lock_cleanup");
905-
let _ = std::fs::remove_dir_all(&temp_path);
906-
907-
let state = Arc::new(FilesystemStoreState::new(temp_path.clone()));
908-
let path =
909-
state.get_checked_dest_file_path("ns", "sub", Some("key"), "write", false).unwrap();
910-
let (version_allocated, wait_for_version) = mpsc::channel();
911-
let (continue_write, wait_to_continue) = mpsc::channel();
912-
*VERSION_ALLOCATED_HOOK.lock().unwrap() = Some(Arc::new(VersionAllocatedHook {
913-
dest_file_path: path.clone(),
914-
version_allocated,
915-
continue_write: Mutex::new(wait_to_continue),
916-
fired: AtomicBool::new(false),
917-
}));
918-
919-
let state_for_thread = Arc::clone(&state);
920-
let path_for_thread = path.clone();
921-
let stale_write = thread::spawn(move || {
922-
let (inner_lock_ref, version) =
923-
state_for_thread.get_new_version_and_lock_ref(path_for_thread.clone());
924-
state_for_thread
925-
.inner
926-
.write_version(inner_lock_ref, path_for_thread, b"stale".to_vec(), version, false)
927-
.unwrap();
928-
});
929-
930-
wait_for_version.recv().unwrap();
931-
state.write_impl("ns", "sub", "key", b"newer".to_vec(), false).unwrap();
932-
continue_write.send(()).unwrap();
933-
stale_write.join().unwrap();
934-
*VERSION_ALLOCATED_HOOK.lock().unwrap() = None;
935-
936-
assert_eq!(state.read_impl("ns", "sub", "key", false).unwrap(), b"newer");
937-
let _ = std::fs::remove_dir_all(temp_path);
938-
}
939-
}

0 commit comments

Comments
 (0)