Skip to content

fs: fix mkdirp return UV_EROFS on read-only fs#48105

Open
hiimjako wants to merge 4 commits intonodejs:mainfrom
hiimjako:fix/mkdirp-EROFS
Open

fs: fix mkdirp return UV_EROFS on read-only fs#48105
hiimjako wants to merge 4 commits intonodejs:mainfrom
hiimjako:fix/mkdirp-EROFS

Conversation

@hiimjako
Copy link
Copy Markdown

Fixes: #47098

I tested the changes manually by mounting a read-only fs and trying to create a new folder inside it.
I honestly wouldn't know how to write tests on these changes without mounting a RO file systems during test sets, and I don't know if this is the best solution. If anyone has advice on how to do this, it is welcome

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. fs Issues and PRs related to the fs subsystem / file system. needs-ci PRs that need a full CI run. labels May 21, 2023
@hiimjako hiimjako force-pushed the fix/mkdirp-EROFS branch from 3d14ad9 to b4a60a3 Compare May 21, 2023 16:53
@VoltrexKeyva
Copy link
Copy Markdown
Member

VoltrexKeyva commented May 21, 2023

Hey @hiimjako, thank you for considering to contribute.

Your commit (b4a60a3) is pointing at an invalid user, make sure you've configured Git to point to you so that you would be shown as a contributor after your changes are accepted and merged.

A commit pointing to an invalid user can generally be caused by it being committed by the incorrect email address, make sure the user.email config in Git is your primary GitHub email address. You can set the config globally to your primary email address by running:

$ git config --global user.email "<primary email>"

(Replace <primary email> with your primary GitHub email address.)

You can check the Git getting started guide for more information.


After all that, force-push the commit to make it point to you.

@hiimjako hiimjako force-pushed the fix/mkdirp-EROFS branch from b4a60a3 to 237b429 Compare May 21, 2023 22:34
@hiimjako
Copy link
Copy Markdown
Author

Hi @VoltrexKeyva,

Thanks for the suggestion, I was using another email for other things and I forgot to change it :)

Now it should be right

@marco-ippolito marco-ippolito added request-ci Add this label to start a Jenkins CI on a PR. and removed needs-ci PRs that need a full CI run. labels May 22, 2023
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label May 22, 2023
@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

@marco-ippolito marco-ippolito requested a review from anonrig May 22, 2023 17:19
@anonrig
Copy link
Copy Markdown
Member

anonrig commented May 22, 2023

Can we simulate a readonly environment and add a test for this? I don't feel comfortable merging this without any tests, unless someone more knowledgable on this matter reviews and approves this PR.

@marco-ippolito marco-ippolito requested a review from RafaelGSS May 25, 2023 09:52
Copy link
Copy Markdown
Member

@RafaelGSS RafaelGSS left a comment

Choose a reason for hiding this comment

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

Thanks for the PR. Please include a test

@hiimjako
Copy link
Copy Markdown
Author

hiimjako commented Mar 1, 2025

Hi @RafaelGSS,
thanks to the work of @kwaszczuk, a test has been added.
There was a discussion in the issue about which platforms to test, and it was decided that supporting only Linux would be sufficient since uv already maps to the error on each platform.
Does this seem reasonable to you?
Thanks!

@kwaszczuk
Copy link
Copy Markdown

Hey @RafaelGSS, any chance you'll be able to take a look at this PR soon? 🤞

}

// mkdirpSync when interacting with read-only filesystem.
if (common.isLinux && process.getuid() === 0) // Mounting filesystem requires root privilege.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we have a test environment that would enter into this clause? @nodejs/build

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We do not.

kennyhyun added a commit to kennyhyun/node that referenced this pull request Apr 8, 2026
mkdirSync with { recursive: true } on a read-only filesystem throws
ENOENT instead of the expected EROFS. This test demonstrates the bug
by mounting a read-only tmpfs via sudo and verifying the error code.

Refs: nodejs#47098
Refs: nodejs#48105
Signed-off-by: Kenny Yeo <kenny@yeoyou.net>
kennyhyun added a commit to kennyhyun/node that referenced this pull request Apr 8, 2026
mkdirSync with { recursive: true } on a read-only filesystem
incorrectly throws ENOENT instead of the expected EROFS error.
This test demonstrates the bug by mounting a read-only tmpfs
via sudo and verifying the error code.

The test requires passwordless sudo to mount a read-only tmpfs.
In environments without this capability (such as ci.nodejs.org),
the test is skipped with a warning message explaining why.

Refs: nodejs#47098
Refs: nodejs#48105
Signed-off-by: Kenny Yeo <kenny@yeoyou.net>
kennyhyun added a commit to kennyhyun/node that referenced this pull request Apr 8, 2026
Add UV_EROFS to the list of errors that should be returned
immediately in MKDirpSync and MKDirpAsync, preventing it from
being incorrectly converted to ENOENT when mkdir is called with
the recursive option on a read-only filesystem.

Based on the original fix by Alberto Moretti (@hiimjako) in nodejs#48105.

Refs: nodejs#47098
Refs: nodejs#48105
Co-authored-by: Alberto Moretti <moretti919@gmail.com>
Signed-off-by: Kenny Yeo <kenny@yeoyou.net>
kennyhyun added a commit to kennyhyun/node that referenced this pull request Apr 9, 2026
Add UV_EROFS to the list of errors that should be returned
immediately in MKDirpSync and MKDirpAsync, preventing it from
being incorrectly converted to ENOENT when mkdir is called with
the recursive option on a read-only filesystem.

Based on the original fix by Alberto Moretti (@hiimjako) in nodejs#48105.

Refs: nodejs#47098
Refs: nodejs#48105
Co-authored-by: Alberto Moretti <moretti919@gmail.com>
Signed-off-by: Kenny Yeo <kenny@yeoyou.net>
kennyhyun added a commit to kennyhyun/node that referenced this pull request Apr 9, 2026
Add UV_EROFS to the list of errors that should be returned
immediately in MKDirpSync and MKDirpAsync, preventing it from
being incorrectly converted to ENOENT when mkdir is called with
the recursive option on a read-only filesystem.

Based on the original fix by Alberto Moretti (@hiimjako) in nodejs#48105.

Refs: nodejs#47098
Refs: nodejs#48105
Co-authored-by: Alberto Moretti <moretti919@gmail.com>
Signed-off-by: Kenny Yeo <kenny@yeoyou.net>
kennyhyun added a commit to kennyhyun/node that referenced this pull request Apr 9, 2026
mkdirSync with { recursive: true } on a read-only filesystem
incorrectly throws ENOENT instead of the expected EROFS error.
This test demonstrates the bug by mounting a read-only tmpfs
via sudo and verifying the error code.

The test requires passwordless sudo to mount a read-only tmpfs.
In environments without this capability (such as ci.nodejs.org),
the test is skipped with a warning message explaining why.

Refs: nodejs#47098
Refs: nodejs#48105
Signed-off-by: Kenny Yeo <kenny@yeoyou.net>
kennyhyun added a commit to kennyhyun/node that referenced this pull request Apr 9, 2026
Add UV_EROFS to the list of errors that should be returned
immediately in MKDirpSync and MKDirpAsync, preventing it from
being incorrectly converted to ENOENT when mkdir is called with
the recursive option on a read-only filesystem.

Based on the original fix by Alberto Moretti (@hiimjako) in nodejs#48105.

Refs: nodejs#47098
Refs: nodejs#48105
Co-authored-by: Alberto Moretti <moretti919@gmail.com>
Signed-off-by: Kenny Yeo <kenny@yeoyou.net>
@kennyhyun
Copy link
Copy Markdown

Hi, I have tried the same fix with a test validated on Github Actions. one commit for failure and the other is fix (from @hiimjako).

My approach for testing is to just skip testing when sudo access failed. (maybe same approach with @kwaszczuk)

@RafaelGSS @hiimjako Can I open a new PR? at least there is no conflict.

@hiimjako
Copy link
Copy Markdown
Author

Hi @kennyhyun!
On my side there is no problem!
Go for that :)

kennyhyun added a commit to kennyhyun/node that referenced this pull request Apr 12, 2026
mkdirSync with { recursive: true } on a read-only filesystem
incorrectly throws ENOENT instead of the expected EROFS error.

Two test cases are included:
- On Linux with passwordless sudo, mounts a real read-only tmpfs to
  verify the error code against the actual kernel behavior.
- Uses internalBinding to mock binding.mkdir and simulate EROFS,
  ensuring the error propagates correctly without requiring root.

Refs: nodejs#47098
Refs: nodejs#48105
Signed-off-by: Kenny Yeo <kenny@yeoyou.net>
kennyhyun added a commit to kennyhyun/node that referenced this pull request Apr 12, 2026
Add UV_EROFS to the list of errors that should be returned
immediately in MKDirpSync and MKDirpAsync, preventing it from
being incorrectly converted to ENOENT when mkdir is called with
the recursive option on a read-only filesystem.

Based on the original fix by Alberto Moretti (@hiimjako) in nodejs#48105.

Refs: nodejs#47098
Refs: nodejs#48105
Co-authored-by: Alberto Moretti <moretti919@gmail.com>
Signed-off-by: Kenny Yeo <kenny@yeoyou.net>
kennyhyun added a commit to kennyhyun/node that referenced this pull request Apr 12, 2026
mkdirSync with { recursive: true } on a read-only filesystem
incorrectly throws ENOENT instead of the expected EROFS error.

Two test cases are included:
- On Linux with passwordless sudo, mounts a real read-only tmpfs to
  verify the error code against the actual kernel behavior.
- Uses internalBinding to mock binding.mkdir and simulate EROFS,
  ensuring the error propagates correctly without requiring root.

Refs: nodejs#47098
Refs: nodejs#48105
Signed-off-by: Kenny Yeo <kenny@yeoyou.net>
kennyhyun added a commit to kennyhyun/node that referenced this pull request Apr 12, 2026
Add UV_EROFS to the list of errors that should be returned
immediately in MKDirpSync and MKDirpAsync, preventing it from
being incorrectly converted to ENOENT when mkdir is called with
the recursive option on a read-only filesystem.

Based on the original fix by Alberto Moretti (@hiimjako) in nodejs#48105.

Refs: nodejs#47098
Refs: nodejs#48105
Co-authored-by: Alberto Moretti <moretti919@gmail.com>
Signed-off-by: Kenny Yeo <kenny@yeoyou.net>
@kennyhyun
Copy link
Copy Markdown

Thanks @hiimjako, I ended up with adding a mock test case as well. Let me create a new PR. Thanks!

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++. fs Issues and PRs related to the fs subsystem / file system.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

mkdir with the recursive flag hides EROFS readonly file system errors with ENOENT

9 participants