-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
os: O_SYNC not utilized in os.OpenFile() on Windows #35358
Comments
cc @alexbrainman @zx2c4 @mattn |
Thank you for creating this issue. I am not an expert here. But, I am not against mapping syscall.O_SYNC onto FILE_FLAG_WRITE_THROUGH. Alex |
Are there data loss concerns related to this issue. For example, expecting O_SYNC force writes to disk before returning but instead the OS is caching the writes? |
@tsellers-r7 my understanding is the answer is "sort of". Lines 68 to 81 in 03aca99
The comment here states that not all flags are passed/utilized on every platform. However, if you assumed that O_SYNC worked on your platform (which wouldn't be unreasonable on Windows given the existence of FILE_FLAG_WRITE_THROUGH) and turned out to be incorrect you could experience unexpected data loss (as in dgraph-io/badger#1084). |
I don't see any promise of data loss prevention in O_SYNC documentation. It says
whatever that means. Alex |
Fair enough, I guess I was referring to the Linux O_SYNC documentation http://man7.org/linux/man-pages/man2/open.2.html. @alexbrainman you're absolutely correct that there aren't any Go contracts/documentation currently being violated. However, if a user isn't really sure what O_SYNC's synchronous I/O means they'll probably reach for something similar, like the link above. |
The point of O_SYNC or write-through is to leave the file cache untouched, usually because the file to be written should not be added to the cache, for example in a backup scenario. |
@networkimprov That sounds like like |
Oh, yes, O_SYNC makes write() become write() + fsync(). |
We have: nix:
win:
Documentation on FILE_FLAG_NO_BUFFERING: https://docs.microsoft.com/en-us/windows/win32/fileio/file-buffering Quick perusal makes me think that the closet approximation is actually O_SYNC=FILE_FLAG_WRITE_THROUGH, O_DIRECT=FILE_FLAG_NO_BUFFERING. Does this correspond with other folks' reading too? Note that we'll probably never match the exact semantics, but we can find something that's reasonably close, I wouldn't mind making such a mapping in Go. |
@ianlancetaylor is there a reason O_DIRECT wasn't included in pkg os? |
The os package is intended to be portable across operating systems, and not even all Unix-like systems support |
@gopherbot add "help wanted" |
It should be easy to add the correct flags in the |
You can send a pull request. It should only change the syscall package to handle (Note that we just entered a release freeze so any change will be for the 1.16 release.) |
The current implementation of `os.Open` function does not use the O_SYNC flag. This means that even if user has set the O_SYNC flag, the `os.Open` call will ignore the `SYNC` flag. This commit fixes the issue by adding the `FILE_FLAG_WRITE_THROUGH` which is the equivalent of `O_SYNC` flag on linux. Fixes golang#35358
Thank you everyone, moving to Go1.16 as per Ian's last comment #35358 (comment) and given that the CL was sent 5 days ago and almost a month in the freeze. I've reviewed and posted feedback on the change though, so in August 2020 we'll hopefully merge it in. |
The CL doesn't appear on this issue because the |
The current implementation of `os.Open` function does not use the O_SYNC flag. This means that even if user has set the O_SYNC flag, the `os.Open` call will ignore the `SYNC` flag. This commit fixes the issue by adding the `FILE_FLAG_WRITE_THROUGH` which is the equivalent of `O_SYNC` flag on linux. Fixes golang#35358
@networkimprov Thank you. I've fixed it. |
Change https://golang.org/cl/235198 mentions this issue: |
Thank you @jarifibrahim, much appreciated CL. Unfortunately we didn’t land it for Go1.16, but we are definitely close to finishing it. Please take a look at @alexbrainman’s comments for the benchmark and tests, so that we can land it for Go1.17. |
Is this change going to land anytime soon in a later release? |
There are pending comments on the change (https://golang.org/cl/235198). Ideally the original author will address them, or someone else can create a new pull request. |
Change https://go.dev/cl/541015 mentions this issue: |
os.OpenFile on windows did not use the O_SYNC flag. This meant that even if the user set O_SYNC, os.OpenFile would ignore it. This change adds a new flag FILE_FLAG_WRITE_THROUGH, which is the equivalent of O_SYNC flag on Linux and is documented in https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea Fixes golang#35358 Change-Id: Ib338caed5bb2f215723bfe30a2551a83998d92c9 GitHub-Last-Rev: 82c6275 GitHub-Pull-Request: golang#64027
While Linux systems are able to pass their low level flags directly into
os.OpenFile
on Windowsos.OpenFile
takes "invented values"go/src/syscall/types_windows.go
Lines 34 to 48 in 5d1a951
These invented values are then checked against a subset of the features that Windows actually supports in syscall.Open
go/src/syscall/syscall_windows.go
Line 273 in 03aca99
Despite Windows supporting FILE_FLAG_WRITE_THROUGH (very close to O_SYNC on Linux) the Open function does not check for O_SYNC. This is unexpected behavior as developers would expect the O_SYNC flag on Windows to work since it can perform synchronous writes.
Some ways to resolve this unexpected behavior include:
The text was updated successfully, but these errors were encountered: