Skip to content

Convert EnsureCaseSensitiveDirectoryRecursive to iterative traversal#40347

Draft
benhillis wants to merge 2 commits into
masterfrom
fix/iterative-case-sensitive-directory
Draft

Convert EnsureCaseSensitiveDirectoryRecursive to iterative traversal#40347
benhillis wants to merge 2 commits into
masterfrom
fix/iterative-case-sensitive-directory

Conversation

@benhillis
Copy link
Copy Markdown
Member

@benhillis benhillis commented Apr 28, 2026

Summary

Converts EnsureCaseSensitiveDirectoryRecursive in filesystem.cpp from unbounded recursive depth-first traversal to an iterative approach using an explicit work stack.

Problem

The recursive implementation of EnsureCaseSensitiveDirectoryRecursive has no depth limit — a deeply nested directory tree (e.g. node_modules) can exhaust the service thread stack.

Fix

  • Replace recursive DFS with iterative two-stack post-order traversal
  • Children are still marked case-sensitive before their parents (preserving the early-exit optimization in EnsureCaseSensitiveDirectory)
  • Handle ownership managed via wil::unique_hfile vector; raw handles used as non-owning references in work stacks
  • No behavioral change — same directories visited, same attributes set, same error handling

Copilot AI review requested due to automatic review settings April 28, 2026 22:01
@benhillis benhillis requested a review from SvenGroot April 28, 2026 22:03
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Converts EnsureCaseSensitiveDirectoryRecursive in filesystem.cpp from recursive DFS to an iterative traversal to prevent stack overflows in the WSL service during deep directory upgrades (e.g., during distro import).

Changes:

  • Replace recursive depth-first traversal with an explicit stack-based traversal.
  • Preserve bottom-up (children-before-parent) case-sensitivity marking and existing retry semantics.

Comment thread src/windows/common/filesystem.cpp Outdated
Comment thread src/windows/common/filesystem.cpp Outdated
Comment thread src/windows/common/filesystem.cpp Outdated
Replace unbounded recursive depth-first traversal with an iterative
approach using an explicit stack. A deeply nested directory tree could
overflow the thread stack during the recursive calls.

The iterative version collects directories in reverse post-order during
traversal, then marks them bottom-up (children before parents),
preserving the ordering invariant that EnsureCaseSensitiveDirectory
relies on for its early-exit optimization.

Bug: 61964147, 61974992, 61911308, 61463090

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@benhillis benhillis force-pushed the fix/iterative-case-sensitive-directory branch from 4d39623 to b1eeaa2 Compare April 29, 2026 17:35
The original recursive EnsureCaseSensitiveDirectoryRecursive could blow
the Windows 1 MB thread stack at a few hundred levels of nesting because
each frame carried a FILE_ID_BOTH_DIR_INFORMATION enumeration buffer.
The iterative implementation in this PR moves that state to the heap, so
a very deep tree must complete without crashing.

The test creates a 1024-level chain via the \\\\?\\ long-path prefix
(cumulative path length exceeds MAX_PATH) and then calls
EnsureCaseSensitiveDirectory on the root. Cleanup goes through the same
long-path prefix so remove_all can see every component.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 12, 2026 05:11
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants