mirror of
https://github.com/narrrl/proton-drive-linux.git
synced 2026-11-04 16:56:59 +01:00
fix(fuse): a new file closed empty reaches Drive at once (B192)
This commit is contained in:
1 parent
57a825887c
commit
31863a1da1
5 files changed
+57
-4
No files matched your search
@@ -3334,6 +3334,12 @@ impl Core {
|
|||||||
if !h.dirty {
|
if !h.dirty {
|
||||||
self.cache.clear_scratch_durable(&h.path);
|
self.cache.clear_scratch_durable(&h.path);
|
||||||
let _ = std::fs::remove_file(&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(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
preserve_on_access_denied(self.require_uid_writable(&h.uid), h.dirty, || {
|
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");
|
debug!(%uid, %parent_uid, name, is_dir, "created node offline; queued");
|
||||||
// A folder is due now; without this the workers slept through it to
|
// 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 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 {
|
if is_dir {
|
||||||
self.wake_drain();
|
self.wake_drain();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -383,6 +383,34 @@ mod tests {
|
|||||||
let _ = std::fs::remove_dir_all(&dir);
|
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]
|
#[test]
|
||||||
#[ignore = "mounts FUSE: run with `cargo test -p pdfs-fuse sim:: -- --ignored`"]
|
#[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() {
|
fn a_file_whose_upload_was_not_read_back_takes_two_writes_at_once() {
|
||||||
|
|||||||
@@ -12,6 +12,23 @@ Conventions:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## B192 — A new file closed empty reaches Drive only half a minute later
|
||||||
|
|
||||||
|
**Status:** Fixed.
|
||||||
|
**Found:** 2026-10-05, while writing the test for B193. An empty file made on an idle mount was
|
||||||
|
still queued 30 s later.
|
||||||
|
|
||||||
|
**Where:** `Core::queue_revision` in `crates/pdfs-fuse/src/lib.rs`.
|
||||||
|
|
||||||
|
**Cause.** Queueing a file's create does not wake the drain: its bytes ride on the create, and
|
||||||
|
the release that attaches them wakes it (B160). A file closed without a write (`touch`, `: > f`)
|
||||||
|
attaches nothing, so its create waited for the workers' 30 s idle poll.
|
||||||
|
|
||||||
|
**Fix.** Closing a clean handle of a file whose create is queued wakes the drain.
|
||||||
|
|
||||||
|
**Test:** simulation test `a_file_made_empty_while_the_drain_is_idle_reaches_drive_at_once`
|
||||||
|
(failed before the fix: the file was still queued after 10 s).
|
||||||
|
|
||||||
## B191 — A file deleted after its create failed and was written again can stay on Drive
|
## B191 — A file deleted after its create failed and was written again can stay on Drive
|
||||||
|
|
||||||
**Status:** Fixed (unverified).
|
**Status:** Fixed (unverified).
|
||||||
|
|||||||
+2
-1
@@ -54,7 +54,8 @@ by its local id, in the queue, the stored tree and pins alike.
|
|||||||
(B158).
|
(B158).
|
||||||
- **Opening a file right after the daemon restarts no longer fails with "Resource temporarily
|
- **Opening a file right after the daemon restarts no longer fails with "Resource temporarily
|
||||||
unavailable"** (B159).
|
unavailable"** (B159).
|
||||||
- **A new folder reaches Drive at once**, not up to half a minute later (B160).
|
- **A new folder, or a new empty file, reaches Drive at once**, not up to half a minute later
|
||||||
|
(B160, B192).
|
||||||
- **A file moved while it was still being uploaded keeps its new name in the mount** on a slow
|
- **A file moved while it was still being uploaded keeps its new name in the mount** on a slow
|
||||||
link (B161).
|
link (B161).
|
||||||
- **A folder removed and made again at once keeps what goes into it.** It used to be created
|
- **A folder removed and made again at once keeps what goes into it.** It used to be created
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ Tracks `docs/MILESTONE-3.0.0.md`. Update it with every commit that moves a phase
|
|||||||
- **Phase 2**: local ids, inode = local id, one tree for every mount (2.10.0).
|
- **Phase 2**: local ids, inode = local id, one tree for every mount (2.10.0).
|
||||||
- **Phase 3, first part**: mkdir, create, rename, unlink and rmdir on the mount are recorded
|
- **Phase 3, first part**: mkdir, create, rename, unlink and rmdir on the mount are recorded
|
||||||
locally and sent from the queue; `"local_first": false` brings back the old path (5e0f30c).
|
locally and sent from the queue; `"local_first": false` brings back the old path (5e0f30c).
|
||||||
- Fixes from the simulation and account runs since then: B125, B127, B130 and B141 to B191.
|
- Fixes from the simulation and account runs since then: B125, B127, B130 and B141 to B192.
|
||||||
- **Sync issues, first cut** (§6.2): refusals sorted into issues, shown at once in the app,
|
- **Sync issues, first cut** (§6.2): refusals sorted into issues, shown at once in the app,
|
||||||
tray and CLI; Export button and `pdfs sync export`; `pdfs sync issues`; Discard button and
|
tray and CLI; Export button and `pdfs sync export`; `pdfs sync issues`; Discard button and
|
||||||
`pdfs sync discard`; a warning badge on the node in the file browser.
|
`pdfs sync discard`; a warning badge on the node in the file browser.
|
||||||
@@ -118,7 +118,8 @@ Tracks `docs/MILESTONE-3.0.0.md`. Update it with every commit that moves a phase
|
|||||||
after an outage only the drain had met (B189, fixed; older than 3.0.0), and a file
|
after an outage only the drain had met (B189, fixed; older than 3.0.0), and a file
|
||||||
saved just before a stop whose release the stop dropped (B190, fixed; older too). The run
|
saved just before a stop whose release the stop dropped (B190, fixed; older too). The run
|
||||||
on 1436c5f found a file deleted after its failed create was written again left on Drive
|
on 1436c5f found a file deleted after its failed create was written again left on Drive
|
||||||
(B191, fixed).
|
(B191, fixed). Its test for B193 found a new empty file waiting out the idle poll (B192,
|
||||||
|
fixed).
|
||||||
- [ ] A clean account run. The one on a6f36d5 (2026-10-04, LAN: 427 passed, 12 failed)
|
- [ ] A clean account run. The one on a6f36d5 (2026-10-04, LAN: 427 passed, 12 failed)
|
||||||
failed B113 and B121 on every on-demand mount, two mirror-to-mirror move cases, and
|
failed B113 and B121 on every on-demand mount, two mirror-to-mirror move cases, and
|
||||||
the journal check. B121 was a bug (B149, fixed); B113's case still expected creates
|
the journal check. B121 was a bug (B149, fixed); B113's case still expected creates
|
||||||
|
|||||||
Reference in new issue
Block a user