[PATCH v3 0/1] MR9809: server: Support creating files with direct and synchronous I/O
This allows various disk benchmarking software like CrystalDiskMark and ATTO disk benchmark to actually benchmark the disk rather than the file cache Implementation based on public Microsoft NtCreateFile() documentation: https://learn.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntc... According to the documentation, Windows forbids FILE_APPEND_DATA and FILE_NO_INTERMEDIATE_BUFFERING being set together, but Linux has no such limitation with the equivalent O_APPEND and O_DIRECT... -- v3: server: Support creating files with direct and synchronous I/O https://gitlab.winehq.org/wine/wine/-/merge_requests/9809
From: 小太 <nospam@kota.moe> This allows various disk benchmarking software like CrystalDiskMark and ATTO disk benchmark to actually benchmark the disk rather than the file cache Implementation based on public Microsoft NtCreateFile() documentation: https://learn.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntc... --- server/fd.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/server/fd.c b/server/fd.c index f70bec354a3..eb84015ae88 100644 --- a/server/fd.c +++ b/server/fd.c @@ -1974,6 +1974,17 @@ struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_nam } else rw_mode = O_RDONLY; + if (options & FILE_NO_INTERMEDIATE_BUFFERING) + { +#if defined(O_DIRECT) /* O_DIRECT is not available on OSX */ + flags |= O_DIRECT; +#endif + /* FILE_NO_INTERMEDIATE_BUFFERING implies FILE_WRITE_THROUGH according + to NtCreateFile() documentation */ + options |= FILE_WRITE_THROUGH; + } + if (options & FILE_WRITE_THROUGH) flags |= O_SYNC; + if ((fd->unix_fd = open( name, rw_mode | (flags & ~O_TRUNC), *mode )) == -1) { /* if we tried to open a directory for write access, retry read-only */ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9809
Surely correctness is more important here? If an app explicitly requests no buffering, it must already understand that this can significantly impact performance if I/O is done incorrectly
Yes, correctness is most important, but broadly across the apps these flags this is optimization feature, functional result doesn't depend on those. And while using that may have moderate positive impact on Windows if the app implements own sophisticated data caching that is not necessarily the case on Linux (and can instead throttle the performance greatly due to various aspects not working the same). So in this sense it will only be correct if the effect of caching and disabling that is the same. For one, the absence of async file IO in Wine may be standing on the way in this case. The case of benchmarking software is special of course, it will clearly misbehave with cache disable not working, but the question is how well we support such a low level software in Wine anyway now and how much is it needed through Wine (vs the more basic use cases).
Direct I/O on Windows broadly has the same limitations as O_DIRECT according to the documentation (access must be aligned and an integer multiple of block size): https://learn.microsoft.com/en-us/windows/win32/fileio/file-buffering#alignm...
That would need detailed tests, documentation is unfortunately not an argument for correctness and can only be viewed as a hint. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9809#note_126004
On Mon Dec 22 16:27:10 2025 +0000, Paul Gofman wrote:
Surely correctness is more important here? If an app explicitly requests no buffering, it must already understand that this can significantly impact performance if I/O is done incorrectly Yes, correctness is most important, but broadly across the apps these flags this is optimization feature, functional result doesn't depend on those. And while using that may have moderate positive impact on Windows if the app implements own sophisticated data caching that is not necessarily the case on Linux (and can instead throttle the performance greatly due to various aspects not working the same). So in this sense it will only be correct if the effect of caching and disabling that is the same. For one, the absence of async file IO in Wine may be standing on the way in this case. The case of benchmarking software is special of course, it will clearly misbehave with cache disable not working, but the question is how well we support such a low level software in Wine anyway now and how much is it needed through Wine (vs the more basic use cases). Direct I/O on Windows broadly has the same limitations as O_DIRECT according to the documentation (access must be aligned and an integer multiple of block size): https://learn.microsoft.com/en-us/windows/win32/fileio/file-buffering#alignm... That would need detailed tests, documentation is unfortunately not an argument for correctness and can only be viewed as a hint. My general concern is of course arguable, it may as well be decided that if the app explicitly requests no cache it is correct to do that regardless and face potential consequences and try to solve them going forward if any. But I am suggesting to consider pro and cons, how much do we gain by helping the specific benchmarking software (e. g., does it really fully work after that?) vs the risks.
Also WRT O_DIRECT, sure, Windows also imposes limitation, in particular, alignment, but are you sure, e. g., the exact alignment is the same? That should be tested with specific alignments to confirm that failure and success cases are the same, I think diverging from Windows behaviour once we add some limitations is not tolerable in such a central place of the system. Also, if that is bound to fsblock size (IIRC for O_DIRECT there were stricter alignment requirements related to system page size and not just filesystem block size, but not fully sure offhand), I am afraid we do not track / know filesystem blocks size accurately now, that would probably need to be explored first. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9809#note_126005
participants (3)
-
Paul Gofman (@gofman) -
小太 -
小太 (@kotarou3)