Repository navigation
fix(libkernel): append positioned writes on an O_APPEND descriptor on Windows - #8359
Merged
Merged
Conversation
… Windows On Windows, sceKernelPwrite, pwrite, sceKernelPwritev, pwritev and the AIO write commands wrote at the given offset on a descriptor opened with O_APPEND. FreeBSD's vn_write sets IO_APPEND for an O_APPEND regular file whether or not an offset is given, the filesystem then writes at the end of the file, and the file offset is left unchanged. Write at Windows' end-of-file offset in that case, and gather a multi-buffer pwritev into one write as writev already does.
|
Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.
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
12 tasks done
12 tasks done
Contributor
|
Independent Windows run of this PR (head ad7e1ac). Environment: Windows 11 10.0.26300, Ryzen 7 9800X3D, WinLibs GCC 15.2.0 r7 (MinGW), Release, BUILD_TESTING=ON. Results:
Not run: the offset-only variant from the description, Linux/macOS, the full repository CTest, and any title. AI-assisted: yes |
12 tasks done
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
On Windows,
sceKernelPwrite,pwrite,sceKernelPwritev,pwritevand the AIO write commands on a descriptor opened withO_APPENDwrite at the given offset, over the start of the file. #5831 madewriteandwritevappend on such a descriptor and leftpwriteunchanged. On Linux these calls go to the host'spwriteandpwritev, which append.FreeBSD 11.4 appends too:
kern_pwritevcallsdofilewritewithFOF_OFFSET, andvn_writesetsIO_APPENDfor anO_APPENDregular file whether or not an offset is given.ffs_write(and tmpfs) then writes at the end of the file. WithFOF_OFFSETthe file offset is not updated.The change, Windows only:
NativePositionedTransferwrites on anO_APPENDdescriptor (File::Appends) at offset0xFFFFFFFFFFFFFFFF, Windows' write to the end of the file, whichFile::WriteAtEndalready uses forwrite. It still restores the file pointer afterwards, so the descriptor's offset does not move. Handles that are not disk files still fail withESPIPE, directories withEBADF.sceKernelPwrite,pwrite,pwritevand the AIO write commands all go through this function.TransferIovecsgathers a multi-bufferpwritevon anO_APPENDdescriptor into one write, as it already does forwritev: FreeBSD appends the whole vector in oneVOP_WRITE, under the whole-file range lockvn_io_faulttakes forO_APPEND.sceKernelPread,sceKernelPwrite,sceKernelPreadvandsceKernelPwritevno longer says these transfer "at the given offset".Tested
Windows 11, WinLibs GCC 15.2.0:
guest_append_writesgets a fifth concurrent writer, which appends with a two-bufferpwritev(fd, ..., 0)on its own descriptor, and then single-threadedsceKernelPwrite(fd, ..., 0)andpwritev(fd, ..., 32)that must append and leavelseek(fd, 0, SEEK_CUR)at 0.guest_aiogets an AIO write at offset 0 on anO_APPENDdescriptor that must append.main'sStdio.cpp:append check failed at line 94(file size after the concurrent writers: thepwritevwriter overwrites other lines) andAio check failed at line 413. With only the offset change:append check failed at line 102in 5 of 5 runs (other writers land between the twopwritevbuffers). With the change, both pass with--repeat until-fail:10.ctest:99% tests passed, 4 tests failed out of 1735.agc_driver_image_array_window_past_layer_limitdoes not build with MinGW onmain(test(agc): align the array window test's texels at run time #8310);agc_driver_image_plane_address_on_lineandagc_driver_pass_input_hazardfail onmainon this machine too;agc_driver_sgpr_pattern_fill_keysfailed once in the parallel run and passes 3 of 3 alone.Linux (Ubuntu 24.04 container, GCC 13.3.0): both tests pass. The change compiles into the Linux build only through these two tests; full
ctest:99% tests passed, 17 tests failed out of 1700, all outside this change (16agc_*tests on the container's lavapipe and kernel, which lacksUFFD_FEATURE_WP_ASYNC, andguest_system_load_exec_standard_error).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)