mirror of
https://github.com/narrrl/proton-drive-linux.git
synced 2026-11-04 00:47:00 +01:00
fix(fuse): a write opened as an upload lands takes the landed base (B170)
An upload that landed let go of its blob before the tree had its node. A write open in between took the base it sampled at its start, the revision the upload replaced, found none of its bytes cached, and queued an incomplete revision; the next write open failed with EIO. The drain keeps the landing node aside until the tree has it, and a write open with no queued revision takes its base from that node, or from the tree as it is when the handle goes in. The fake Drive can hold the drain in that window (`hold_next_landing`).
This commit is contained in:
1 parent
4757b957d2
commit
2502af6e3c
10 files changed
+187
-22
No files matched your search
@@ -12,6 +12,37 @@ Conventions:
|
||||
|
||||
---
|
||||
|
||||
## B170 — A write opened as an upload lands fails the next write with `EIO`
|
||||
|
||||
**Status:** Fixed (unverified).
|
||||
**Found:** 2026-10-04, by CI on 9bbc994 and by three parallel copies of
|
||||
`one_client_on_a_good_link` (seed 4; seed 5 in the local suite). A write at an offset was
|
||||
refused with `EIO`, and the daemon logged "refusing write over incomplete queued revision".
|
||||
Just before, an open had retried with "queued revision changed while opening for write", and
|
||||
the queued write it then made was incomplete.
|
||||
|
||||
**Where:** `serve_open` in `crates/pdfs-fuse/src/filesystem.rs`, and `Core::refresh_after_upload`
|
||||
in `crates/pdfs-fuse/src/drain.rs`.
|
||||
|
||||
**Cause.** When an upload lands, the drain caches its bytes under the node as Drive has it,
|
||||
rebases the open write handles onto it, lets go of the blob, and then puts the node in the
|
||||
tree. A write open in between found no blob to copy and took the base it had sampled at its
|
||||
start: the mtime and size the tree had before the upload. The release of its partial write
|
||||
filled the gaps from the cache under that key, found nothing, and queued an incomplete
|
||||
revision, and a write open over one is refused (B123). Under load, the open retried because
|
||||
of the landing and met that window.
|
||||
|
||||
**Fix.** From before the drain lets go of the blob until the tree has the node, the landing
|
||||
node is kept aside. A write open with no queued revision takes its base from that node, or
|
||||
else from the tree as it is when the handle goes in, not from its first sample.
|
||||
|
||||
**Test:** `a_write_opened_as_an_upload_lands_takes_the_landed_revision_as_its_base` in
|
||||
`sim/daemon.rs` holds the drain in that window with the fake Drive's new `hold_next_landing`,
|
||||
writes at an offset, and writes again after it. Without the fix the second write fails with
|
||||
`EIO`.
|
||||
|
||||
---
|
||||
|
||||
## B169 — A stop lets a mirror pass go on until the runtime ends under it
|
||||
|
||||
**Status:** Fixed.
|
||||
|
||||
@@ -68,6 +68,8 @@ by its local id, in the queue, the stored tree and pins alike.
|
||||
to upload them to the top of your Drive instead (B168).
|
||||
- **Stopping the daemon during a folder sync no longer waits for the sync.** The uploads in
|
||||
progress finish, and the rest waits for the next start (B169).
|
||||
- **Writing to a file again just as its upload finishes no longer fails.** A write right after
|
||||
it failed with "Input/output error" (B170).
|
||||
- **A file renamed just as its upload finished keeps its new name.** The mount no longer showed
|
||||
the old name, and a second rename no longer failed with "No such file or directory" (B152).
|
||||
- **A change that waits for a name to be freed no longer waits seconds after it is.** A rename or
|
||||
|
||||
@@ -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 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).
|
||||
- Fixes from the simulation and account runs since then: B127 and B141 to B169.
|
||||
- Fixes from the simulation and account runs since then: B127 and B141 to B170.
|
||||
- **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`.
|
||||
|
||||
@@ -110,7 +110,9 @@ Tracks `docs/MILESTONE-3.0.0.md`. Update it with every commit that moves a phase
|
||||
Looking into it found the start spending 1.7 s rebuilding listings (B167, fixed).
|
||||
Its journal check caught a file removed with its folder while uploading being
|
||||
sent again, to the root (B168, fixed), and a stop that let a mirror pass go on
|
||||
until the runtime ended under it (B169, fixed).
|
||||
until the runtime ended under it (B169, fixed). CI on 9bbc994 failed
|
||||
`one_client_on_a_good_link`: a write opened as an upload landed took the revision
|
||||
it replaced as its base, and the next write failed with `EIO` (B170, fixed).
|
||||
5. **Release**: 2.10.0 is tagged; the 2.9.0 tag still waits for the user's go-ahead.
|
||||
|
||||
## After 3.0.0
|
||||
|
||||
Reference in new issue
Block a user