Skip to content
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

Discard 0-sized writes to files #7638

Merged
merged 2 commits into from
Feb 14, 2024

Conversation

alexcrichton
Copy link
Member

This commit comes from #7633 where Windows and Unix would behave differently when writing at a particular file offset. Notably Unix semantics indicate:

Before any action described below is taken, and if nbyte is zero
and the file is a regular file, the write() function may detect
and return errors as described below. In the absence of errors,
or if error detection is not performed, the write() function
shall return zero and have no other results. If nbyte is zero and
the file is not a regular file, the results are unspecified.

These semantics are a bit easier to emulate on Windows so the host implementation now discards any attempt to perform I/O if a zero-sized write is detected.

Closes #7633

@alexcrichton alexcrichton requested a review from a team as a code owner December 5, 2023 22:42
@alexcrichton alexcrichton requested review from pchickey and removed request for a team December 5, 2023 22:42
@github-actions github-actions bot added the wasi Issues pertaining to WASI label Dec 5, 2023
Copy link
Contributor

@pchickey pchickey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like a good fix to me. Thanks

@alexcrichton alexcrichton added this pull request to the merge queue Dec 5, 2023
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Dec 5, 2023
@alexcrichton alexcrichton added this pull request to the merge queue Dec 6, 2023
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Dec 6, 2023
alexcrichton added a commit to alexcrichton/system-interface that referenced this pull request Jan 28, 2024
This commit it borne out of CI failures on bytecodealliance/wasmtime#7638.
Investigating this failure has revealed a number of aspects here which
I've attempted to address in this PR. The notable changes here are:

* The current code in this crate was handling the case where
  `FileExt::seek_write` on Windows was leaving intermediate bytes as
  undefined when a write happened beyond the end of a file. I believe
  that this is due to an error in the documentation of the Rust standard
  library which I've submitted rust-lang/rust#120452 to fix.

* Removing handling of "always write zeros" handles the primary failure
  of the PR bytecodealliance/wasmtime#7638 which is that
  `write_vectored_at` was always returning 0 on Windows for writes past
  the end of the file. This is because Windows doesn't have a vectored
  file write so the vector chosen was the first nonempty vector which
  was the one containing zeros to extend the file. That meant that the
  method always returned zero.

* Previously the methods here used file locking which appeared to handle
  the case where the file was calculated and then the write happened.
  Given that this no longer happens I've removed the locking here.

* The `write_all_at` method had a loop around `reopen_write` handling
  the `Interrupted` error but no other methods did, so I opted to remove
  the loop and leave that to the internals of `reopen_write` if
  necessary.

* Other methods related to this are all simplified to directly use
  `seek_write` and avoid handling the case where writes past the end
  need to write zeros (as zeros are guaranteed by Windows).

Overall my hope is to use this to unblock bytecodealliance/wasmtime#7638
to get more platform-agnostic behavior for writing beyond the end of a
file.
@alexcrichton
Copy link
Member Author

Took me quite some time to set aside time to debug this failure on Windows, and it turned up bytecodealliance/system-interface#43

sunfishcode pushed a commit to bytecodealliance/system-interface that referenced this pull request Feb 13, 2024
This commit it borne out of CI failures on bytecodealliance/wasmtime#7638.
Investigating this failure has revealed a number of aspects here which
I've attempted to address in this PR. The notable changes here are:

* The current code in this crate was handling the case where
  `FileExt::seek_write` on Windows was leaving intermediate bytes as
  undefined when a write happened beyond the end of a file. I believe
  that this is due to an error in the documentation of the Rust standard
  library which I've submitted rust-lang/rust#120452 to fix.

* Removing handling of "always write zeros" handles the primary failure
  of the PR bytecodealliance/wasmtime#7638 which is that
  `write_vectored_at` was always returning 0 on Windows for writes past
  the end of the file. This is because Windows doesn't have a vectored
  file write so the vector chosen was the first nonempty vector which
  was the one containing zeros to extend the file. That meant that the
  method always returned zero.

* Previously the methods here used file locking which appeared to handle
  the case where the file was calculated and then the write happened.
  Given that this no longer happens I've removed the locking here.

* The `write_all_at` method had a loop around `reopen_write` handling
  the `Interrupted` error but no other methods did, so I opted to remove
  the loop and leave that to the internals of `reopen_write` if
  necessary.

* Other methods related to this are all simplified to directly use
  `seek_write` and avoid handling the case where writes past the end
  need to write zeros (as zeros are guaranteed by Windows).

Overall my hope is to use this to unblock bytecodealliance/wasmtime#7638
to get more platform-agnostic behavior for writing beyond the end of a
file.
alexcrichton added a commit to alexcrichton/wasmtime that referenced this pull request Feb 13, 2024
This is to get bytecodealliance#7638 passing CI, but I wanted to separate this out from
that to have it go through the queue in isolation in case any issues
arise.
github-merge-queue bot pushed a commit that referenced this pull request Feb 13, 2024
This is to get #7638 passing CI, but I wanted to separate this out from
that to have it go through the queue in isolation in case any issues
arise.
This commit comes from bytecodealliance#7633 where Windows and Unix would behave
differently when writing at a particular file offset. Notably Unix
semantics [indicate]:

> Before any action described below is taken, and if nbyte is zero
> and the file is a regular file, the write() function may detect
> and return errors as described below. In the absence of errors,
> or if error detection is not performed, the write() function
> shall return zero and have no other results. If nbyte is zero and
> the file is not a regular file, the results are unspecified.

These semantics are a bit easier to emulate on Windows so the host
implementation now discards any attempt to perform I/O if a zero-sized
write is detected.

[indicate]: https://man7.org/linux/man-pages/man3/write.3p.html

Closes bytecodealliance#7633
@alexcrichton alexcrichton added this pull request to the merge queue Feb 14, 2024
Merged via the queue into bytecodealliance:main with commit df67fe8 Feb 14, 2024
19 checks passed
@alexcrichton alexcrichton deleted the fix-pwrite-behavior branch February 14, 2024 00:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wasi Issues pertaining to WASI
Projects
None yet
Development

Successfully merging this pull request may close these issues.

A difference between windows and linux?
2 participants