-
Notifications
You must be signed in to change notification settings - Fork 13.3k
std::io::copy returns Bad File Descriptor with writer files in append mode in 1.50 #82410
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
Comments
syscall_326 is copy_file_range. And indeed, it has this error code overloading the more common meaning of EBADF.
@rustbot assign. |
Error: Parsing assign command in comment failed: ...'ot assign.' | error: specify user to assign to at >| ''... Please let |
@rustbot claim |
If you need a workaround for the moment you can do |
Nice, this is awesome. We will try this tomorrow which should allow to migrate our codebase to 1.50! Thanks a lot for the quick help on this.. |
Test out the workaround and it works, while we wait for the actual fix to come out, thanks a lot! |
@rustbot label +T-libs-impl +I-prioritize +regression-from-stable-to-stable +C-bug +O-linux workaround is available. fix needs review. |
Assigning @rustbot label -I-prioritize +P-critical |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
… r=m-ou-se Fix io::copy specialization using copy_file_range when writer was opened with O_APPEND fixes rust-lang#82410 While `sendfile()` returns `EINVAL` when the output was opened with O_APPEND, `copy_file_range()` does not and returns `EBADF` instead, which – unlike other `EBADF` causes – is not fatal for this operation since a regular `write()` will likely succeed. We now treat `EBADF` as a non-fatal error for `copy_file_range` and fall back to a read-write copy as we already did for several other errors.
While updating my code base from 1.49 to 1.50 we noticed a failures in a program that rebuilds files from small chunks.
We are opening a file in append mode, one in read mode, and we stream one into the other (as for the snippet below).
Testing this out confirmed that the error happens on the reader file when the writer is in append mode, whenever we use a
BufWriter
/BufReader
or not. If we load the whole file into a string and then usestd::io::copy
on the same data it works as intended, as does setting the file in write mode (while it becomes necessary to seek to the end).Checking what got shipped into 1.50 we suspect the probable culprit to be 028754a#diff-4280ab12d5278289ca8b2e83cad374850eaeac0c18f49a474f5a9b5bf55d3991
What we are guessing is that this change is using the
sendfile
syscall that doesn't support files in append mode even when the file is in append mode, triggering the Bad File Descriptor errorhttps://github.com/torvalds/linux/blob/b52bb135aad99deea9bfe5f050c3295b049adc87/fs/read_write.c#L1676
Code
I tried this code (playground):
I expected to see this happen: the files to be concatenated
Instead, this happened:
std::io::copy
returnsError: Os { code: 9, kind: Other, message: "Bad file descriptor" }
Strace for the code snipped:
Example that works with loading the file into a string before copy (playground):
Version it worked on
It most recently worked on: 1.49
Version with regression
1.50
rustc --version --verbose
:Backtrace
no backtrace
The text was updated successfully, but these errors were encountered: