Skip to content

fs: bound the mkdir recursive ENOENT retry loop - #66410

Closed
agape1225 wants to merge 1 commit into
nodejs:mainfrom
agape1225:fs-mkdirp-bound-enoent-retry
Closed

agape1225 wants to merge 1 commit into
nodejs:mainfrom
agape1225:fs-mkdirp-bound-enoent-retry

Conversation

@agape1225

Copy link
Copy Markdown
Contributor

mkdir(path, { recursive: true }) creates missing parent directories by retrying whenever mkdir() fails with ENOENT, but nothing tracks whether a retry actually made progress. If the same path keeps failing with ENOENT even after its parent exists (e.g. under procfs, or during a racing directory removal), the retry loops forever at 100% CPU with no way to interrupt a sync call.

Track the path last requeued after ENOENT in FSContinuationData and clear it on a successful mkdir(). If the same path is retried again with no progress since, fail with the original error instead of looping. Applies to both MKDirpSync and MKDirpAsync.

Fixes: #66268

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs involving general changes in the lib/ or src/ directories. needs-ci PRs that need a full CI run. labels Sep 30, 2026
mkdir(path, { recursive: true }) creates missing parent directories by
retrying whenever mkdir() fails with ENOENT, but nothing tracks
whether a retry actually made progress. If the same path keeps
failing with ENOENT even after its parent exists (e.g. under procfs,
or during a racing directory removal), the retry loops forever at
100% CPU with no way to interrupt a sync call.

Track the path last requeued after ENOENT in FSContinuationData and
clear it on a successful mkdir(). If the same path is retried again
with no progress since, fail with the original error instead of
looping. Applies to both MKDirpSync and MKDirpAsync.

Fixes: nodejs#66268

Signed-off-by: agape1225 <49804691+agape1225@users.noreply.github.com>
@agape1225
agape1225 force-pushed the fs-mkdirp-bound-enoent-retry branch from 1fb3404 to b19049a Compare September 30, 2026 10:08
@inoway46

Copy link
Copy Markdown
Contributor

Thanks for working on this. #66340 already addresses #66268 and has approvals with CI in progress. Did you see that PR before opening this one? If this doesn’t cover anything missing there, could you close this in favor of #66340?

@agape1225 agape1225 closed this Sep 30, 2026
@codecov

codecov Bot commented Sep 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.37%. Comparing base (a18fd89) to head (b19049a).
⚠️ Report is 159 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #66410      +/-   ##
==========================================
+ Coverage   90.33%   90.37%   +0.03%     
==========================================
  Files         790      792       +2     
  Lines      273834   275598    +1764     
  Branches    52361    52843     +482     
==========================================
+ Hits       247378   249079    +1701     
- Misses      16924    16938      +14     
- Partials     9532     9581      +49     
Files with missing lines Coverage Δ
src/node_file-inl.h 85.54% <100.00%> (+0.47%) ⬆️
src/node_file.cc 75.48% <100.00%> (+0.26%) ⬆️
src/node_file.h 78.43% <ø> (ø)

... and 138 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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

Labels

c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs involving general changes in the lib/ or src/ directories. needs-ci PRs that need a full CI run.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fs.mkdir with recursive: true retries without a progress bound: spins forever on /proc, livelocks under concurrent rmdir

3 participants