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.
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
win, fs: add fallback for
fs__stat_handle
#3268base: master
Are you sure you want to change the base?
win, fs: add fallback for
fs__stat_handle
#3268Changes from all commits
ff2046c
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This introduces a race condition and we try very hard to avoid those in libuv. It's a TOCTOU variant: the file can change between the CreateFile and FindFirstFile calls.
It's probably benign (I can't think of a plausible scenario where it'd matter) but still, if CreateFile can be substituted with FindFirstFile with no loss of functionality, then why not use FindFirstFile always?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually,
FindFirstFile
queries less information.Currently, libuv calls
CreateFile
to open a handle to the file, and then call another two other functions to gather information:NtQueryInformationFile
NtQueryVolumeInformationFile
and in some cases
DeviceIoControl
.See: https://github.com/libuv/libuv/blob/v1.x/src/win/fs.c#L1696
As we can't open handles to files that we don't have the necessary permission for, the
FindFirstFile
is a fallback that won't require a handle and only get the most critical information: creation date, last write, last access, size, and file attributes.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bnoordhuis bump, I guess?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bnoordhuis I don't think this is a TOCTOU, since we don't try to merge the information. It is a bit unfortunate that there is a narrow window where a few items of information won't be available, which makes the filesystem appear less atomic than it would otherwise have been.
Alternatively, we could repeat the
CreateFileW
above but withoutFILE_READ_ATTRIBUTES
, which I assume is whatFindFirstFile
is doing.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CreateFileW
will fail no matter what if the user doesn't have the necessary permissions to a file.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already have the code to handle the result of
NtOpenFile
though, whereas this requires a new code path to handle the results.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
POC with
NtOpenFile
(kinda messy, just a poc 🔨): oluan@fd6b562I guess this just adds even more new paths VS
FindFirstFileW
, even if we deal only withNtOpenFile
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Turns out FindFirstFile is (un)documented here to calling NtQueryDirectoryFile
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the POC work? I expected you need to open a handle to the containing directory, rather than the file itself. I guess I need to do a bit of testing myself, but I think I understand this issue better now, to the point of being able to review and merge something. I was wrong about needing NtOpenFile for in case, since it just needs CreateFile for the parent directory. It appears that thhe advantage of NtQueryDirectoryFile is a substantial performance boost over FindFirstFile (according to git and chromium, who tested this and switched) and the ability to still query the drive information.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also realized this PR seems like it may implement lstat, so to implement stat, it needs to check if dwFileAttributes member includes FILE_ATTRIBUTE_REPARSE_POINT, then figure out how to handle that if so