You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
`acquire_client` had its sole hot-path caller removed in `efb15479` —
the streaming write path now drives on an owned `Connection` clone via
smb2 0.9's owned `FileWriter`. Nothing else called it. `LoggedClientGuard`
existed only to instrument that one method's release point, so it goes
with it.
`clone_session` keeps its ticketed `client-mutex:` debug logs: that's
the one remaining lock acquire on the SMB session and a useful future
diagnostic. The mutex is held for microseconds per call now (just to
clone the underlying `Arc<Connection>`), so the logs sit at `debug`
where they fire only when explicitly enabled.
Also updates the colocated CLAUDE.md and the historical comment in
`write_from_stream` to point at the regression test that pins the
no-deadlock shape, not the deleted Phase C QNAP test.
Copy file name to clipboardExpand all lines: apps/desktop/src-tauri/src/file_system/volume/CLAUDE.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -411,7 +411,7 @@ spawned detached task. This is safe because the stream always lives in an async
411
411
**Why**: SMB servers return NFC-normalized filenames. macOS filesystem paths use NFD. The watcher NFD-normalizes filenames before constructing display paths used for cache lookups.
412
412
413
413
**Gotcha (no longer applicable as of smb2 0.9)**: SMB write streaming fallback used to hold the client mutex for the whole upload
414
-
**Why**: Historically `FileWriter<'a>` borrowed `&'a mut Connection` from the `SmbClient`, so `write_from_stream` had to hold the client mutex for the duration of the streaming write. Under sustained concurrent pressure on QNAP this two-phase pattern (brief `clone_session` fast-path probe → drop → long `acquire_client` for the streaming fallback) deadlocked: Phase C `smb_integration_phase_c_deadlock_repro_qnap` reproduced it reliably. smb2 0.9 rebuilt `FileWriter` to own its `Connection` and `Arc<Tree>`, removing the borrow. See the new Decision below (`write_from_stream` uses a cloned Connection + Arc<Tree>) for the current design.
414
+
**Why**: Historically `FileWriter<'a>` borrowed `&'a mut Connection` from the `SmbClient`, so `write_from_stream` had to hold the client mutex for the duration of the streaming write. Under sustained concurrent pressure this two-phase pattern (brief `clone_session` fast-path probe → drop → long mutex-guarded streaming fallback) deadlocked. smb2 0.9 rebuilt `FileWriter` to own its `Connection` and `Arc<Tree>`, removing the borrow. The regression is pinned by `smb_integration_concurrent_streaming_writes_no_deadlock`. See the new Decision below (`write_from_stream` uses a cloned Connection + Arc<Tree>) for the current design.
415
415
416
416
**Decision**: `write_from_stream` uses a cloned `Connection` + `Arc<Tree>` via smb2 0.9's owned `FileWriter`
417
417
**Why**: smb2 0.9 made `FileWriter` own its `Connection` (cheap `Arc::clone`) and `Arc<Tree>` instead of borrowing `&'a mut Connection`. `write_from_stream` now calls `clone_session` once up front and drives both the compound fast-path AND the streaming fallback on the same owned `Connection` clone. The client mutex is held only for the few microseconds of `clone_session()`, never across I/O. The previous shape — fast-path on a clone, then drop and re-acquire the client for the streaming fallback — was the deadlock reproducer in Phase C against QNAP. The architectural property we get for free: N concurrent streaming writes on one `SmbVolume` pipeline N WRITE chains over a single SMB session, multiplexed by `MessageId` in smb2's receiver task. No external locking, no mutex contention on the hot copy path.
0 commit comments