Repository navigation
Preserve attachment lifetime and native file semantics - #1
Merged
Merged
Conversation
techartdev
marked this pull request as ready for review
September 10, 2026 16:31
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Explicit detach now reports busy instead of retiring a drive while local applications hold files. Protocol v2 reports readiness, status and cleanup warnings; the parent retains a busy attachment for another explicit attempt.
Windows gates detach against open contexts. Volume flush attempts every writable descriptor and preserves the first failure; confirmed renames update related open paths and context drop closes remote handles. Linux/macOS use ordinary unmount without force or lazy flags. Linux negotiates shared mmap only when the kernel advertises support, while retaining ordinary direct I/O.
Validation:
Remaining release gates include desktop-created Windows SFTP mappings and Explorer/editor UI acceptance, real remote failure cases, modern macOS native runtime and concurrent remote-edit semantics. These checks do not establish database or VM-image compatibility. CI installs the pinned official WinFsp MSI only on its disposable runner after SHA-256 and signer checks; normal tests skip the opt-in native fixture.
Native failure acceptance also passes at 36464c5 (CI run 34512537189): write-through I/O/offline/timeout/read-only errors map to the expected Windows codes, source bytes stay unchanged, failed flush reports failure, unrelated I/O remains usable, and close/cleanup deletion warnings reach the parent. Failed deletion preserves the source. These injected provider errors do not substitute for real network-loss or remote disk-full acceptance.
At 1459801, CI run 34513391440 also passes actual Windows IPC-loss acceptance: cutting both parent pipes while a file is open makes the next write fail within ten seconds, preserves confirmed source bytes, exits the helper unsuccessfully and removes the drive letter. Unexpected lifecycle replies or connection loss now return failure exits on both Windows and FUSE. Actual SSH outages and abnormal native FUSE teardown remain separate verification gates; fuser's teardown fallback can use lazy/forced unmount, unlike normal explicit Detach.
The 1459801 Linux CI artifact also passes actual pipe-loss acceptance on Linux 6.8 as root, through the core SFTP provider: write and close return ENOTCONN with an open descriptor, confirmed source bytes remain unchanged, the helper exits with failure and mountinfo confirms removal. The disposable fixture and staged binary were verified removed. Modern macOS and actual SSH network outages remain separate checks; later non-root Linux results follow.
Setup diagnostics at 49c481a were checked by launching the helper without WinFsp: it completes the capability handshake, requests no filesystem operations and exits promptly with official runtime installation guidance.
Native directory rename coverage at e58d386 passes in CI run 34518237898, alongside all earlier Windows cases (32.21 seconds). Windows correctly rejects rename while a child file is open without damaging the source; closing the child permits rename while two directory aliases remain open, and both still return metadata. A rejected replacement preserves both trees. The expectation was checked against a separate NTFS baseline and Microsoft's MS-FSA rules; Windows does not use POSIX open-child rename semantics.
FUSE cursor recovery at 87a28c9 clears retired handles and buffered entries before reopening. Linux/macOS regressions cover failed close/reopen and invalid replies followed by a later seek; all platform jobs pass in CI run 34519068114. Its Linux artifact passes native rewind of the same directory descriptor before and after rename through the core SFTP provider, plus the prior I/O, mmap and busy-detach checks. Fixture/mount and staged binary cleanup were independently verified. Native injected reopen failure remains a separate check.
Unprivileged Linux acceptance now also passes at 87a28c9 on Linux 6.8 (UID 65534, installed fusermount3): file operations, directory rewind/rename, mmap, busy detach and ordinary unmount. A separate open-file pipe-loss run returns ENOTCONN, preserves confirmed backing bytes, exits with failure and removes the mount before any privileged recovery. Source bytes and removal of both disposable trees/mounts and the staged binary were independently verified. No accounts or FUSE configuration changed.
Native volume-wide flush passes at 9c4fbe1 in CI run 34521265017 (full native suite: 28.88 seconds). FlushFileBuffers on the actual disposable volume visits all three writable files despite a provider flush failure and returns ERROR_IO_DEVICE. Clearing the injected fault permits a successful subsequent flush with independently verified backing bytes. All platform jobs and prior native checks pass.
Inode lifetime regressions pass at 558d1f2 in CI run 34521983619, covering both kernel-forget/open-release orders and recreated-path isolation. Its Linux artifact passes native Linux 6.8 acceptance as UID 65534 through the core SFTP provider: unlink/recreate yields a distinct inode, the old descriptor reads/writes its original object, and closing it leaves the replacement intact. Source-owner inspection verifies replacement bytes. Prior directory rewind, mmap, busy detach and ordinary unmount checks pass; fixture, mount and staged binary cleanup were independently verified. All platform jobs and native Windows acceptance pass (29.24 seconds).
Windows read-only projection at 447b1c3 passes native CI 34523633220 (37.15 seconds), all platform regressions and clippy. Existing regular-file read-only set/clear reaches provider permissions, blocks new writes/deletion, and unsupported combined DOS-attribute requests fail without partial mutation. Attribute-only opens use a remote read handle; the matching core separately passes live SFTP metadata set/clear with read-only-root and truncation enforcement. No protocol fields or required provider methods were added. This projects ordinary Unix permission bits; DOS flag persistence, creation/overwrite attributes and creation/change timestamps are not claimed complete.
Timestamp handling at 3f66501 passes native CI 34524595837 (29.14 seconds), all platform builds/tests and Windows clippy. Unavailable creation/change times are no longer synthesized from modification time. Supported access/modification times round-trip; unsupported mixed requests fail before modifying timestamps or permissions. A separate live SFTP probe verifies single-field timestamp preservation and out-of-range rejection without partial changes. Creation/change-time storage is unavailable in the present contract; explicit changes report unsupported. Creation/overwrite attributes remain a separate review item.