mirror of
https://github.com/narrrl/proton-drive-linux.git
synced 2026-11-04 00:47:00 +01:00
fix(fuse): land a move right after a rename, and rename across folders quickly (B121)
The SDK caches each node, including the name hash it sends with the next rename or move, and only an event evicts it. Renames and moves didn't update that copy. So after a rename, the next change to the same node went out with the old name hash, Drive refused it as out of date (422), and the retry kept sending the stale hash until the event feed came round, up to 10 seconds later. - Every remote rename and move goes through `Core::rename_remote` or `Core::move_remote`. Both drop the SDK's copy of the node after a successful change and before each out-of-date retry, so the retry sends the current hash. - A plain move was not retried at all, so a move right after a rename failed with EIO through the mount and with "out of date" from `pdfs move`. It now retries like a rename. - The drain's combined move-and-rename also drops the SDK's copy once it lands. - A rename that also changes folders through the mount replies only once both halves have landed. When the move fails, the file keeps its new name in the source folder, the tree is told so, and the rename reports EIO. A dropped link still queues the change. B111's cause in docs/BUGS.md is corrected to the same SDK cache. The acceptance case "regression B121" renames and moves a file at once through the mount and through `pdfs`, and checks names and bytes.
This commit is contained in:
1 parent
0b27c884a7
commit
e32959e40a
7 files changed
+216
-91
No files matched your search
+36
-4
@@ -12,6 +12,38 @@ Conventions:
|
||||
|
||||
---
|
||||
|
||||
## B121 — A move right after a rename fails with `EIO`, and a rename across folders takes seconds
|
||||
|
||||
**Status:** Fixed (unverified).
|
||||
**Found:** 2026-10-03, in the journal of the account run on flaky Wi-Fi. Each change answered
|
||||
correctly, but slowly. One rename and move through the mount collected 13 `operation failed …
|
||||
method=PUT status=422` warnings over 8.2 seconds, and another collected 7 over 3.9 seconds. Each
|
||||
one was a request that Drive refused as out of date and the daemon tried again half a second
|
||||
later.
|
||||
|
||||
**Where:** every remote rename and move: `serve_rename` in `crates/pdfs-fuse/src/filesystem.rs`,
|
||||
the control `rename` and `move_to` in `crates/pdfs-fuse/src/lib.rs`, `move_between` in
|
||||
`crates/pdfs-fuse/src/relocate.rs`, and the drain's renames and `move_renaming` in
|
||||
`crates/pdfs-fuse/src/drain.rs`.
|
||||
|
||||
**Cause.** A rename or move sends the node's current name hash as `OriginalHash`. The SDK takes
|
||||
it from its entity cache before the hash in the link it has just fetched. Its own rename and move
|
||||
do not update that cache entry. Only the event feed's echo of the change drops it, and the daemon
|
||||
polls the feed every 10 seconds (`POLL_INTERVAL`). Until then, each rename or move of the same
|
||||
node sent the old hash. A rename across folders, which is a rename and then a move, was refused
|
||||
until the next poll, and the retries from B111 hid that as latency. A plain move was not retried
|
||||
at all. When it came within the poll interval, `mv a b && mv b dir/` through the mount failed with
|
||||
`EIO`, and `pdfs rename` followed by `pdfs move` failed with Drive's "out of date" error.
|
||||
|
||||
**Fix.** `Core::forget_sdk_node` passes the SDK the event its own change will echo, which drops
|
||||
the cached node. Every rename, and every move but the drain's, goes through `Core::rename_remote`
|
||||
or `Core::move_remote`. Both drop the entry once the change has landed, and before each retry of a
|
||||
request Drive called out of date. The drain's `move_renaming` drops it once its move lands.
|
||||
|
||||
**Test:** the unit tests `a_rename_or_move_drops_the_sdk_copy_of_the_node` and
|
||||
`every_remote_rename_and_move_rides_out_a_stale_hash`. On the account run, "regression B111" and
|
||||
"regression B113" should show no `status=422` warnings.
|
||||
|
||||
## B120 — A file queued in a folder that has just landed is put off by five seconds
|
||||
|
||||
**Status:** Fixed (unverified).
|
||||
@@ -285,10 +317,10 @@ InvalidRequirements (http 422): This file or folder was out of date, rename fail
|
||||
`drain_rename_in_place` in `crates/pdfs-fuse/src/drain.rs`, and the control `rename` in
|
||||
`crates/pdfs-fuse/src/lib.rs`.
|
||||
|
||||
**Cause.** The SDK's `rename_node` reads the node's details from the server and sends its current
|
||||
name hash as `OriginalHash`. Right after a rename of the same node, that read can still return the
|
||||
old hash. Drive then refuses the request as out of date. The daemon reported this at once as
|
||||
`EIO`, although the same request succeeds a moment later.
|
||||
**Cause.** The SDK's `rename_node` sends the node's current name hash as `OriginalHash`. Right
|
||||
after a rename of the same node, it still sent the old one. Drive then refuses the request as out
|
||||
of date. The daemon reported this at once as `EIO`, although the same request succeeds a moment
|
||||
later. The old hash comes from the SDK's entity cache, not from the server (see B121).
|
||||
|
||||
**Fix.** All remote renames go through `Core::rename_remote`. It retries a rename that fails with
|
||||
`InvalidRequirements` up to 20 times, half a second apart, the same window the move after a
|
||||
|
||||
+8
-2
@@ -241,6 +241,12 @@ eight times through the mount. On a mount it also does so three times with
|
||||
`pdfs rename`, after the queue is empty, so the renames race nothing but Drive.
|
||||
It runs against the reference too.
|
||||
|
||||
**B121** (a file renamed and moved at once lands) renames a file, moves it into
|
||||
a subfolder and renames it back across folders through the mount, with no pause
|
||||
between the steps. On a mount it then runs `pdfs rename` and `pdfs move` back to
|
||||
back. The file must end up where it was sent, with its bytes, and the case
|
||||
reports how long each half took. It runs against the reference too.
|
||||
|
||||
**B98** (an upload superseded by a write ends) writes 64 MiB and waits for its
|
||||
upload to show in `pdfs transfers`, then appends to the file. The queue must
|
||||
drain, the old upload must leave the transfer list, and the file must hold
|
||||
@@ -331,8 +337,8 @@ bug is open at the moment. B114 to B117 started as such cases.
|
||||
A full account run with `--journal-check` checks these `docs/BUGS.md` entries,
|
||||
many of them fixed but not yet verified:
|
||||
|
||||
- B48, B80, B94, B95, B98, B100, B101, B102, B111, B114, B115, B116, B117 and
|
||||
B119, each with its own `regression B<n>` case.
|
||||
- B48, B80, B94, B95, B98, B100, B101, B102, B111, B114, B115, B116, B117, B119
|
||||
and B121, each with its own `regression B<n>` case.
|
||||
- B118, with "application workloads" and "block boundaries", which failed on
|
||||
it. It needs Drive to be slow to list a new node, so a clean run is weak
|
||||
evidence.
|
||||
|
||||
Reference in new issue
Block a user