mirror of
https://github.com/narrrl/proton-drive-linux.git
synced 2026-11-10 09:17:03 +01:00
fix(fuse): fill an incomplete queued revision's gaps on a write open
A partial write whose base was not in the content cache queued an incomplete revision, and every write open over it was refused with EIO until the drain uploaded it. CI's one-client-lan simulation hit this on seed 1: a create over a file whose partial edit had not drained yet. The write open now copies the blob and fills its gaps from the remote base with Core::fill_gaps, as the drain does, and fails only when that fill fails (B204). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EuyxByBpK3fSWtyPkugeHz
This commit is contained in:
4 files changed
+87
-6
No files matched your search
@@ -451,6 +451,36 @@ mod tests {
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "mounts FUSE: run with `cargo test -p pdfs-fuse sim:: -- --ignored`"]
|
||||
fn a_partial_write_over_bytes_never_read_takes_another_write_at_once() {
|
||||
// Nothing here ever read the file, so the release of a partial write
|
||||
// had no cached base to fill its gaps from and queued an incomplete
|
||||
// revision. The next write open on it failed with EIO (B204).
|
||||
let drive = FakeDrive::new();
|
||||
drive.device().write("f.txt", b"0123456789");
|
||||
let dir = scratch("partial-write-unread-base");
|
||||
let daemon = Daemon::start(&dir, drive.client(1, Faults::lan())).unwrap();
|
||||
let path = daemon.mountpoint.join("f.txt");
|
||||
let file = |bytes: &[u8]| Some(Entry::File(Arc::new(bytes.to_vec())));
|
||||
|
||||
write_at(&path, 2, b"ab").unwrap();
|
||||
write_at(&path, 6, b"cd").unwrap();
|
||||
assert!(
|
||||
wait_until(Duration::from_secs(30), || {
|
||||
daemon.pending().is_ok_and(|items| items.is_empty())
|
||||
&& drive.tree().get("f.txt").cloned() == file(b"01ab45cd89")
|
||||
}),
|
||||
"{:?} {:?}",
|
||||
daemon.pending(),
|
||||
drive.tree()
|
||||
);
|
||||
assert_eq!(drive.tree().len(), 1, "{:?}", 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_deleted_offline_while_open_still_reads_and_takes_writes() {
|
||||
|
||||
Reference in new issue
Block a user