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

Add file sync shims #1418

Merged
merged 7 commits into from Jun 9, 2020
Merged

Add file sync shims #1418

merged 7 commits into from Jun 9, 2020

Conversation

divergentdave
Copy link
Contributor

@divergentdave divergentdave commented May 18, 2020

This PR adds shim implementations for these related file syncing functions.

  • fsync, for POSIX targets, backed by File::sync_all()
  • fdatasync, for POSIX targets, backed by File::sync_data()
  • fcntl with command F_FULLFSYNC, for macOS targets, backed by File::sync_all()
  • sync_file_range, for Linux targets, backed by File::sync_data()

Adds implementations for fsync, fdatasync, and sync_file_range
@RalfJung
Copy link
Member

I am not familiar with the detailed semantics of all these variants of sync. Are these all adequate implementations, or are some of them using sync_all because a more precise syncing is not possible with Rust's cross-platform APIs?

src/shims/fs.rs Outdated Show resolved Hide resolved
tests/run-pass/fs.rs Outdated Show resolved Hide resolved
src/shims/fs.rs Outdated Show resolved Hide resolved
@divergentdave
Copy link
Contributor Author

Whoops, I misspoke above, sync_file_range uses File::sync_data(). I've edited the comment.

On non-ancient versions of Linux, fsync lines up well with File::sync_all(), as it writes out all data for a file and its file metadata, and then waits for the disk to finish writing. (on "older kernels", it did not flush disk caches) Likewise, fdatasync lines up well with File::sync_data(), as it skips writing out some file metadata. sync_file_range doesn't have an analogue in the Rust standard library, but it is closest to File::sync_data(), because it doesn't write out file metadata, and while sync_file_range allows selecting what range of the file should be written out, File::sync_data() writes out the whole file, so it's a stronger operation, and just loses out on performance.

On macOS, fsync writes out file contents and metadata, but it does not block until the disk has finished writing. fcntl with F_FULLFSYNC writes out both and then waits for the disk to write. While File::sync_all() looks like it could describe either operation, as its docs don't mention flushing the drive's buffers, (only the filesystem's) fcntl with F_FULLFSYNC is the stronger of the two operations on macOS, and that's what the stdlib uses to implement File. And yes, I put the fsync shim in the posix.rs file since it's a POSIX function, even though it may not be used on macOS.

@RalfJung
Copy link
Member

sync_file_range doesn't have an analogue in the Rust standard library, but it is closest to File::sync_data(), because it doesn't write out file metadata, and while sync_file_range allows selecting what range of the file should be written out, File::sync_data() writes out the whole file, so it's a stronger operation, and just loses out on performance.

Thanks for the explanation! I see the code already has a comment for this, so this seems fine.

On macOS, fsync writes out file contents and metadata, but it does not block until the disk has finished writing. fcntl with F_FULLFSYNC writes out both and then waits for the disk to write. While File::sync_all() looks like it could describe either operation, as its docs don't mention flushing the drive's buffers, (only the filesystem's) fcntl with F_FULLFSYNC is the stronger of the two operations on macOS, and that's what the stdlib uses to implement File. And yes, I put the fsync shim in the posix.rs file since it's a POSIX function, even though it may not be used on macOS.

I see. So on macOS, the Miri implementation is stronger than what the actual system does. That's fine, but please leave a comment along those lines.

src/shims/fs.rs Outdated Show resolved Hide resolved
tests/run-pass/libc.rs Outdated Show resolved Hide resolved
tests/run-pass/libc.rs Outdated Show resolved Hide resolved
src/shims/fs.rs Outdated Show resolved Hide resolved
src/shims/fs.rs Outdated Show resolved Hide resolved
src/shims/fs.rs Outdated Show resolved Hide resolved
@RalfJung
Copy link
Member

Thanks a lot! @bors r+

@bors
Copy link
Collaborator

bors commented May 25, 2020

📌 Commit 3092b9e has been approved by RalfJung

bors added a commit that referenced this pull request May 25, 2020
Add file sync shims

This PR adds shim implementations for these related file syncing functions.
* `fsync`, for POSIX targets, backed by `File::sync_all()`
* `fdatasync`, for POSIX targets, backed by `File::sync_data()`
* `fcntl` with command `F_FULLFSYNC`, for macOS targets, backed by `File::sync_all()`
* `sync_file_range`, for Linux targets, backed by `File::sync_data()`
@bors
Copy link
Collaborator

bors commented May 25, 2020

⌛ Testing commit 3092b9e with merge 5f55f0e...

@bors
Copy link
Collaborator

bors commented May 25, 2020

💔 Test failed - status-appveyor

@RalfJung
Copy link
Member

Looks like file.sync_data() is failing on a Windows host / Linux target (and then, as usual, we run into strerror_r when printing the error messages of the failure).

@RalfJung
Copy link
Member

Hm, the code should work... maybe this is an AppVeyor thing?

src/shims/fs.rs Outdated Show resolved Hide resolved
@RalfJung
Copy link
Member

Let's see if this reproduces.
@bors try

@bors
Copy link
Collaborator

bors commented May 25, 2020

⌛ Trying commit 3092b9e with merge ba32813...

bors added a commit that referenced this pull request May 25, 2020
Add file sync shims

This PR adds shim implementations for these related file syncing functions.
* `fsync`, for POSIX targets, backed by `File::sync_all()`
* `fdatasync`, for POSIX targets, backed by `File::sync_data()`
* `fcntl` with command `F_FULLFSYNC`, for macOS targets, backed by `File::sync_all()`
* `sync_file_range`, for Linux targets, backed by `File::sync_data()`
@bors
Copy link
Collaborator

bors commented May 26, 2020

⌛ Trying commit 889640b with merge d0cb89d...

bors added a commit that referenced this pull request May 26, 2020
Add file sync shims

This PR adds shim implementations for these related file syncing functions.
* `fsync`, for POSIX targets, backed by `File::sync_all()`
* `fdatasync`, for POSIX targets, backed by `File::sync_data()`
* `fcntl` with command `F_FULLFSYNC`, for macOS targets, backed by `File::sync_all()`
* `sync_file_range`, for Linux targets, backed by `File::sync_data()`
@bors
Copy link
Collaborator

bors commented May 26, 2020

☀️ Try build successful - checks-travis, status-appveyor
Build commit: d0cb89d (d0cb89df165c9dbd5633b42c38a16569ade9c490)

@divergentdave
Copy link
Contributor Author

@bors try

@bors
Copy link
Collaborator

bors commented May 26, 2020

⌛ Trying commit c01bc14 with merge 57b5acb...

bors added a commit that referenced this pull request May 26, 2020
Add file sync shims

This PR adds shim implementations for these related file syncing functions.
* `fsync`, for POSIX targets, backed by `File::sync_all()`
* `fdatasync`, for POSIX targets, backed by `File::sync_data()`
* `fcntl` with command `F_FULLFSYNC`, for macOS targets, backed by `File::sync_all()`
* `sync_file_range`, for Linux targets, backed by `File::sync_data()`
@bors
Copy link
Collaborator

bors commented May 26, 2020

☀️ Try build successful - checks-travis, status-appveyor
Build commit: 57b5acb (57b5acb948954e846aa6d3d05a5736130242bd76)

@RalfJung
Copy link
Member

Argh, GH doesn't let me view the force-pushd diff. :/
In the future, please avoid force pushes until review is done.

src/shims/fs.rs Outdated Show resolved Hide resolved
src/shims/fs.rs Outdated Show resolved Hide resolved
@divergentdave
Copy link
Contributor Author

I added similar logic to fcntl(F_FULLFSYNC) and sync_file_range, and added read-only files to both tests.

@bors try

@bors
Copy link
Collaborator

bors commented Jun 6, 2020

⌛ Trying commit e352d4f with merge e8ff19e...

bors added a commit that referenced this pull request Jun 6, 2020
Add file sync shims

This PR adds shim implementations for these related file syncing functions.
* `fsync`, for POSIX targets, backed by `File::sync_all()`
* `fdatasync`, for POSIX targets, backed by `File::sync_data()`
* `fcntl` with command `F_FULLFSYNC`, for macOS targets, backed by `File::sync_all()`
* `sync_file_range`, for Linux targets, backed by `File::sync_data()`
@bors
Copy link
Collaborator

bors commented Jun 6, 2020

☀️ Try build successful - checks-travis, status-appveyor
Build commit: e8ff19e (e8ff19eed88eb639641ae8929aec1a57f052c198)

src/shims/fs.rs Outdated
}

if let Some(FileHandle { file, writable }) = this.machine.file_handler.handles.get_mut(&fd) {
if !*writable && cfg!(windows) {
Copy link
Member

Choose a reason for hiding this comment

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

We have this same conditional 4 times now... can you factor this into a helper function?

@RalfJung
Copy link
Member

RalfJung commented Jun 8, 2020

I guess we can always clean up later. Thanks for the PR @divergentdave!
@bors r+

@bors
Copy link
Collaborator

bors commented Jun 8, 2020

📌 Commit e352d4f has been approved by RalfJung

@divergentdave
Copy link
Contributor Author

Hang on, I just got the refactor done

@RalfJung
Copy link
Member

RalfJung commented Jun 8, 2020

Oh okay, that's quick. :)
@bors r-
I'm going to sleep now, will check this out the next morning.

@RalfJung
Copy link
Member

RalfJung commented Jun 9, 2020

Thanks. :)
@bors r+

@bors
Copy link
Collaborator

bors commented Jun 9, 2020

📌 Commit a60c130 has been approved by RalfJung

@bors
Copy link
Collaborator

bors commented Jun 9, 2020

⌛ Testing commit a60c130 with merge ffd03b3...

@bors
Copy link
Collaborator

bors commented Jun 9, 2020

☀️ Test successful - checks-travis, status-appveyor
Approved by: RalfJung
Pushing ffd03b3 to master...

@bors bors merged commit ffd03b3 into rust-lang:master Jun 9, 2020
@divergentdave divergentdave deleted the file-sync branch June 9, 2020 13:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants