Repository navigation
fix(libkernel): read a watched file's path before its state on Windows - #9227
Merged
oneandonlydean merged 1 commit intoOct 23, 2026
Conversation
TakeSnapshot read the file information and then the path. A delete between the two left a snapshot whose path was already under \$Extend\$Deleted\ but whose link count and delete flag were not, so IsDeleted was false and the watch thread asked for a parent watch of \$Extend\$Deleted\. FindFirstChangeNotification refuses it with ERROR_ACCESS_DENIED, and the exception on the detached watch thread ended the process. guest_kqueue hit this when FileWatch removed its file while a watch thread was still polling. The path is now read first. A path under \$Extend\$Deleted\ is only returned after the delete, so the information read after it reports the delete and the parent watch is skipped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.
|
12 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
What
guest_kqueuecan abort on Windows with:TakeSnapshotread the file information (FileBasicInfo,FileStandardInfo) and then the path (GetFinalPathNameByHandleW). A delete between the two left a snapshot with the old link count and delete flag but a path already under\$Extend\$Deleted\.IsDeletedwas false for it, so the watch thread askedWatchParentfor\$Extend\$Deleted\, whichFindFirstChangeNotificationrefuses withERROR_ACCESS_DENIED. The exception on the detached watch thread ends the process.FileWatchhits this when it removes its file while a watch thread it has just stopped is still in a poll; the watch threads are detached, andStoponly sets their event.The snapshot now reads the path first. A path under
\$Extend\$Deleted\is only returned after the delete, so the information read after it reports the delete,IsDeletedholds and the parent watch is skipped, as #8623 does at registration. A delete between the two reads now leaves the old path with the deleted state, and the next poll replaces the path.What Windows reports for a deleted file that is still open, measured on this machine with
DeleteFileWon NTFS:NumberOfLinks0,DeletePending1, path\\?\C:\$Extend\$Deleted\...;NumberOfLinks1,DeletePending1, path under\$Extend\$Deleted\.So
IsDeletedis true whenever the path is under\$Extend\$Deleted\and the information is read after it. #7049 also changesIsDeleted, to treat a path under\$Extend\$Deleted\as deleted for a rename into it; this change is independent of it and touches neitherIsDeletednorSnapshotHints.Tested
BUILD_TESTING=ON, onmaincecb540.ctest --parallel 4onmainfailedguest_kqueueonce with the message above; alone it passed 5 of 5.guest_kqueue_tests.exeat once, each in its own working directory, 1024 runs each way:mainaborted 2 times, both with the message above; this change 0 times. With all 16 copies in one working directory, the directory changes wake the watch threads more often:mainaborted 121 times in 1536 runs with that message, this change 0 times in 1792. (In the shared directory both builds also had a few failures of other checks, 4 and 10, where copies picked the same steady-clock file name; they did not occur with separate directories.)python tools/select_tests.py ctest build --output-on-failure --timeout 120 --parallel 4: 1517 of the 1520 selected tests pass. The 3 failures areagc_driver_sample_order,agc_driver_sample_order_grid_referenceandagc_driver_sample_order_recipe_depth_locations, which fail the same way onmainon this RTX 4090 and which test(agc): read the sample order tests' depth through a sampled copy #9056 fixes.agc_driver_image_array_window_past_layer_limitis not built: it does not compile with MinGW onmain(test(agc): align the array window test's texels at run time #8310).guest_kqueuepasses 20 of 20 underctest --repeat until-fail:20.python tools/check_conventions.py --base origin/mainpasses.python tools/pr_overlap.py --branch fix/kqueue-snapshot-path-before-statereports no open PR changing the same lines. It could not compare feat(aot): consolidate native ARM64 compiler, runtime and consumers #5021, feat(wasm): run relinked titles in the browser with WebGPU #6879, fix(libkernel): retire an EV_ONESHOT note through its delete callback and follow Windows $Deleted paths #7049, feat(libkernel): support kevent read and write events on regular files #7088 and feat(libkernel): report open, read and close notes on watched files #7121, which conflict withmain; none of them changesTakeSnapshot(fix(libkernel): retire an EV_ONESHOT note through its delete callback and follow Windows $Deleted paths #7049 changesIsDeletedandSnapshotHintsbelow it)._WIN32path only).Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)🤖 Generated with Claude Code