mirror of
https://github.com/narrrl/proton-drive-linux.git
synced 2026-11-04 00:47:00 +01:00
fix(fuse): cache an upload whose read-back failed, and know it as ours (B157)
When the read-back after an upload went unanswered, the drain let go of the staged blob without caching it. A partial write opened next had nothing to fill its gaps from and queued an incomplete revision, so the write open after it was refused with EIO. The bytes are now cached under the size and mtime the tree still has, which is the base the next write takes. Their SHA-1 stands in for the revision id the read-back did not bring, so that write chains onto the upload and does not fork a conflict copy of itself.
This commit is contained in:
1 parent
16fca10e6c
commit
4676a4e32b
8 files changed
+165
-17
No files matched your search
@@ -12,6 +12,36 @@ Conventions:
|
||||
|
||||
---
|
||||
|
||||
## B157 — A second write to a file whose upload was not read back fails with `EIO`
|
||||
|
||||
**Status:** Fixed (unverified).
|
||||
**Found:** 2026-10-04, by the simulation's Wi-Fi profile (`one_client_on_a_slow_link`, seed 4,
|
||||
every replay on 16fca10, none on dbc4d9a: sixteen drain workers changed the timing). After an
|
||||
upload of `c.bin` landed, the read-back of the node went unanswered. A write at an offset
|
||||
followed, and the next write to the file failed with `EIO`. The daemon logged "refusing write
|
||||
over incomplete queued revision".
|
||||
|
||||
**Where:** `Core::refresh_after_upload` and `Core::revision_conflict` in
|
||||
`crates/pdfs-fuse/src/drain.rs`.
|
||||
|
||||
**Cause.** The uploaded bytes are cached under the revision the read-back returns (B123). With no
|
||||
read-back, the drain let go of the staged blob and cached nothing. A partial write opened next had
|
||||
nothing to fill its gaps from, so it queued an incomplete revision, and a write open over one is
|
||||
refused. Had it been filled, the write would have landed as a conflict copy of itself: the
|
||||
revision id of the upload was never recorded as ours (`own_sealed_rev`).
|
||||
|
||||
**Fix.** When the read-back fails, the uploaded bytes are cached under the size and mtime the
|
||||
tree still has for the file, which is the base a write opened next takes, unless a newer write
|
||||
has taken over. The SHA-1 of those bytes is kept in memory, and a queued write that finds the
|
||||
remote holding them chains onto it instead of forking. After a restart the write still forks a
|
||||
conflict copy, which loses nothing.
|
||||
|
||||
**Test:** sim test `a_file_whose_upload_was_not_read_back_takes_two_writes_at_once`, with the
|
||||
fake Drive's new `lose_read_back_of_next_revision`. Without the fix the second write fails with
|
||||
`EIO`; with only the cache fix, it lands as a conflict copy.
|
||||
|
||||
---
|
||||
|
||||
## B156 — A file written again after its create lost its answer lands as a conflict copy
|
||||
|
||||
**Status:** Fixed (unverified).
|
||||
|
||||
@@ -42,6 +42,8 @@ by its local id, in the queue, the stored tree and pins alike.
|
||||
answer to its upload** (B155).
|
||||
- **A file written again while its upload was being retried no longer lands as a conflict copy
|
||||
of itself when the link lost Drive's answer to the first try** (B156).
|
||||
- **Writing to a file twice in a row no longer fails with "Input/output error" when the link
|
||||
lost Drive's answer to reading back the file's last upload** (B157).
|
||||
- **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 B156.
|
||||
- Fixes from the simulation and account runs since then: B127 and B141 to B157.
|
||||
- **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`.
|
||||
|
||||
@@ -79,7 +79,9 @@ Tracks `docs/MILESTONE-3.0.0.md`. Update it with every commit that moves a phase
|
||||
a write whose answer was lost (B155). Both fixed. One slow-link run of seed 2 failed
|
||||
once with a rename answering `ENOENT` as a folder move landed. Not reproduced since;
|
||||
it may be B152. Replays of slow-link seed 4 failed two of six times on a file written
|
||||
again after its create lost its answer (B156, fixed).
|
||||
again after its create lost its answer (B156, fixed). With sixteen drain workers
|
||||
(16fca10), seed 4 failed every replay on a write after an upload that was not read
|
||||
back (B157, fixed).
|
||||
- [ ] Known-bug list in `sim/run.rs` is empty: B125 and B130 open; B127, B129 and B132 fixed
|
||||
but unconfirmed.
|
||||
- [ ] A clean account run. The one on a6f36d5 (2026-10-04, LAN: 427 passed, 12 failed)
|
||||
|
||||
Reference in new issue
Block a user