Skip to content

Improve SSHFS connection stability and fix handle leaks - #478

Open
TongLi-Galaxy wants to merge 3 commits into
winfsp:masterfrom
TongLi-Galaxy:master
Open

Improve SSHFS connection stability and fix handle leaks#478
TongLi-Galaxy wants to merge 3 commits into
winfsp:masterfrom
TongLi-Galaxy:master

Conversation

@TongLi-Galaxy

Copy link
Copy Markdown

sshfs-win 3.7.26236

This release improves SSHFS connection resilience on Windows and fixes several handle leaks and remote file-handle exhaustion issues affecting long-running mounts.

Highlights

  • Update SSHFS to the latest version.

  • Improved connection stability with the following default options for new installations:

    • ServerAliveInterval=15
    • ServerAliveCountMax=3
    • reconnect
    • ConnectTimeout=10
    • request_timeout=30
  • Added an SFTP request watchdog that terminates a mount when a request remains blocked for more than 30 seconds, preventing applications from hanging indefinitely.

  • Added automatic recovery support through WinFsp Launcher after an abnormal mount termination.

  • Fixed multiple handle leaks involving:

    • Condition variables
    • Windows-native request synchronization objects
    • Long-running read and write operations
  • Changed Windows read operations to use transient SFTP read handles, preventing read handles from accumulating and exceeding the per-session server limit.

  • Added a rapid-failure circuit breaker that terminates a mount after repeated failures of critical SFTP operations within a short period, allowing the launcher to recover it cleanly.

  • Improved compatibility of the build and patching process with different line-ending formats.

Important notes

Existing network drive mappings must be disconnected and reconnected before the updated connection options take effect.

When a connection fails, in-progress operations may return an error and need to be retried. Writes that were still in progress when the connection failed may be lost.

@TongLi-Galaxy

TongLi-Galaxy commented Aug 27, 2026

Copy link
Copy Markdown
Author

This pull request address different failure modes in the SSHFS-Win resource and connection lifecycle. Together, they improve long-running mount stability on Windows.

Common Trigger Scenario

A common way to trigger the issue is to place a large Git repository on a remote SSH directory and access it through a locally mapped SSHFS drive.

When Git runs locally—such as during git status, repository discovery, file enumeration, IDE refreshes, or source-control indexing—it may inspect a very large number of files and directories in a short period of time. This generates a high volume of SFTP OPEN, READ, STAT, LSTAT, OPENDIR, and READDIR requests.

With the previous implementation, these operations could cause local synchronization handles and remote read handles to accumulate instead of being released promptly. Once the process or the remote SFTP session approached its handle limit, file operations became increasingly slow or started failing.

Typical symptoms included:

  • Git commands becoming noticeably slower or hanging;
  • IDE source-control integration becoming unresponsive;
  • Directory enumeration taking an unusually long time;
  • New files or directories failing to open;
  • Intermittent I/O errors or resource-related access failures;
  • The sshfs-win process handle count continuing to grow during normal use.
image For example, those 15052 handles are still there even after the git repo closed.

This workload is particularly effective at exposing the problem because Git repeatedly scans large directory trees and accesses many small metadata and object files. The recent changes address the issue at both ends: local synchronization resources are released correctly, while Windows read operations use transient remote SFTP handles to avoid exhausting the server-side per-session handle limit.
image

1. Connection resilience and request timeouts

A broken SSH transport does not always immediately produce an error visible to the SFTP request layer. In some cases, an SFTP request can remain pending indefinitely after the underlying connection has become unusable. SSH keep-alive settings alone cannot detect every such condition.

The first release therefore introduced:

  • More aggressive SSH keep-alive settings;
  • ServerAliveCountMax=3;
  • ConnectTimeout=10;
  • Automatic reconnect;
  • A configurable request_timeout watchdog.

The watchdog tracks outstanding SFTP requests and terminates the mount if a request, or the request-processing lock, makes no progress for the configured timeout. This allows WinFsp Launcher to start a clean replacement instance instead of leaving applications blocked forever.

2. Local synchronization-resource leaks

The second release fixed a long-running handle leak caused by pthread condition variables that were initialized but not destroyed on all cleanup paths.

The affected objects included:

  • Read-chunk completion conditions;
  • Per-file write completion conditions;
  • Temporary conditions used by synchronous writes.

On Cygwin, these synchronization primitives may hold underlying Windows resources. Freeing the surrounding C structure without calling pthread_cond_destroy() releases memory but not necessarily the associated operating-system resource. Repeated file operations could therefore cause the process handle count to grow continuously.

The cleanup paths now explicitly destroy every condition variable before its owning object is freed.

3. Request-event leaks, rapid failures, and remote handle exhaustion

The third release addresses three additional issues.

On Cygwin, request completion now uses native Windows Event objects instead of POSIX semaphores. Each request has a clear CreateEventW / SetEvent / WaitForSingleObject / CloseHandle lifecycle, including error and connection-cleanup paths. This makes Windows handle ownership explicit and prevents request synchronization objects from accumulating.

The release also adds a rapid-failure circuit breaker. If critical SFTP operations fail repeatedly—32 failures within a 10-second window—the mount is terminated and allowed to recover through WinFsp Launcher. A successful health-related request resets the failure counter. This prevents an unusable connection from generating an unbounded stream of failed requests and consuming additional resources.

Finally, Windows read-only opens now use transient SFTP handles. Previously, a remote file handle could remain open for the entire lifetime of a Windows file object. Under file scanning, readahead, or applications that open many files concurrently, this could exceed the SFTP server's per-session handle limit and cause subsequent OPEN operations to fail.

The new behavior opens a remote read handle only for the duration of an individual read and closes it immediately afterward. This reduces the number of long-lived remote handles and prevents read-handle exhaustion. The implementation also avoids applying write-specific synchronization and close operations to transient read handles.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant