mirror of
https://github.com/narrrl/proton-drive-linux.git
synced 2026-11-03 16:41:26 +01:00
fix(fuse): wait for a create on the wire that holds the name (B154); a write whose answer was lost is not a conflict (B155)
B154 is a regression from the B153 fix: after a failure on a held name the op woke the ops waiting for it, but the database cannot see a create on the wire, so the op was due again at once and spent its waits in milliseconds. No wake while another create on the wire holds the name. B155: a revision upload that reached Drive but lost its answer left the file at a revision this daemon never heard of, and the retry kept the write as a conflict copy of itself. A complete write whose bytes the remote holds, by size and SHA-1, is sent again instead. The fake Drive gains hold_reply_to_next_create and lose_reply_to_next_revision for the two new sim tests.
This commit is contained in:
1 parent
7269cb5118
commit
3f74b95b34
6 files changed
+204
-12
No files matched your search
@@ -12,6 +12,46 @@ Conventions:
|
||||
|
||||
---
|
||||
|
||||
## B155 — A write whose upload lost its answer lands as a conflict copy of itself
|
||||
|
||||
**Status:** Fixed (unverified).
|
||||
**Found:** 2026-10-04, by the simulation's Wi-Fi profile (`one_client_on_a_slow_link`, seed 2,
|
||||
second replay on 7269cb5). `x/z/y/a.txt` was written after its create landed. The revision upload
|
||||
reached Drive, but the answer was lost and the call timed out. On the retry, Drive held
|
||||
`a (sync-conflict …).txt` beside the file, with the same bytes.
|
||||
|
||||
**Where:** `Core::revision_conflict` in `crates/pdfs-fuse/src/drain.rs`.
|
||||
|
||||
**Cause.** A queued write remembers the revision it was made against. The retry found the file one
|
||||
revision further, sealed by the lost upload, which this daemon never heard of, so it was not
|
||||
recorded as our own (`own_sealed_rev`). The write was taken for a change from elsewhere and kept as
|
||||
a conflict copy.
|
||||
|
||||
**Fix.** A complete write whose bytes the remote already holds, by size and SHA-1, is not a
|
||||
conflict: it is sent again as a revision of the same bytes. Sim test
|
||||
`a_write_whose_answer_was_lost_lands_once`, with the fake Drive's new
|
||||
`lose_reply_to_next_revision`.
|
||||
|
||||
## B154 — A file made under the name of a create on the wire lands as a conflict copy
|
||||
|
||||
**Status:** Fixed (unverified).
|
||||
**Found:** 2026-10-04, by CI on 7269cb5 (`one_client_on_a_good_link`, seed 9, every run). `c.bin`
|
||||
was renamed to `d` while its create was on the wire, and a new `c.bin` was made. The new file landed
|
||||
as `c (sync-conflict …).bin`, the mount showed that name, and `unlink c.bin` answered `ENOENT`.
|
||||
|
||||
**Where:** the failure path of `Core::run_pending_drain` in `crates/pdfs-fuse/src/drain.rs`.
|
||||
|
||||
**Cause.** A regression from the B153 fix. The new file's create found `c.bin` held by the first
|
||||
create, which was still on the wire, and failed as a wait. The B153 fix then woke the ops waiting
|
||||
for the name. The database cannot see a create on the wire, only queued trashes and renames, so
|
||||
it found the name free and the op was due again at once. Four waits went in 70 ms, and the create
|
||||
took a conflict name.
|
||||
|
||||
**Fix.** No wake while another create on the wire holds the name. It frees the name when it
|
||||
lands, or hands it to the rename queued behind it, which wakes the waiters when it lands. Sim
|
||||
test `a_file_made_under_the_name_of_a_create_on_the_wire_waits_for_it`, with the fake Drive's
|
||||
new `hold_reply_to_next_create`.
|
||||
|
||||
## B153 — An op waiting for a name sat out its backoff after the name was free
|
||||
|
||||
**Status:** Fixed (unverified).
|
||||
|
||||
Reference in new issue
Block a user