fix(fuse): a new file closed empty reaches Drive at once (B192)

This commit is contained in:
nvrl committed 2026-10-05 04:50:10 +02:00
1 parent 57a825887c
commit 31863a1da1
5 files changed
+57 -4

No files matched your search

+7 -1
View File
@@ -3334,6 +3334,12 @@ impl Core {
if !h.dirty {
self.cache.clear_scratch_durable(&h.path);
let _ = std::fs::remove_file(&h.path);
// A new file's create waits for this release to wake the drain
// (`Core::queue_local_node`). Closed empty, it attached nothing
// that would, and sat until the idle poll (`docs/BUGS.md` B192).
if is_local_uid(&h.uid) {
self.wake_drain();
}
return Ok(());
}
preserve_on_access_denied(self.require_uid_writable(&h.uid), h.dirty, || {
@@ -3828,7 +3834,7 @@ impl Core {
debug!(%uid, %parent_uid, name, is_dir, "created node offline; queued");
// A folder is due now; without this the workers slept through it to
// the idle poll (B160). A file is not: its bytes ride on the create, and
// the release that attaches them wakes the drain.
// its release wakes the drain, with bytes or without (B192).
if is_dir {
self.wake_drain();
}
+28
View File
@@ -383,6 +383,34 @@ mod tests {
let _ = std::fs::remove_dir_all(&dir);
}
#[test]
#[ignore = "mounts FUSE: run with `cargo test -p pdfs-fuse sim:: -- --ignored`"]
fn a_file_made_empty_while_the_drain_is_idle_reaches_drive_at_once() {
// A new file's create waits for the release that attaches its bytes
// to wake the drain. A file closed without any attached none, so it
// sat until the workers' 30 s idle poll (B192).
let drive = FakeDrive::new();
let dir = scratch("idle-empty-create");
let daemon = Daemon::start(&dir, drive.client(1, Faults::lan())).unwrap();
assert!(wait_until(Duration::from_secs(30), || {
daemon.pending().is_ok_and(|items| items.is_empty())
}));
std::fs::write(daemon.mountpoint.join("e.md"), b"").unwrap();
assert!(
wait_until(Duration::from_secs(10), || {
daemon.pending().is_ok_and(|items| items.is_empty())
&& drive.lookup("e.md").is_some()
}),
"{:?} {:?}",
daemon.pending(),
drive.tree()
);
assert!(matches!(daemon.stop(), Ok(MountOutcome::Shutdown)));
let _ = std::fs::remove_dir_all(&dir);
}
#[test]
#[ignore = "mounts FUSE: run with `cargo test -p pdfs-fuse sim:: -- --ignored`"]
fn a_file_whose_upload_was_not_read_back_takes_two_writes_at_once() {