-
Notifications
You must be signed in to change notification settings - Fork 677
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
posix_fallocate support #1105
posix_fallocate support #1105
Conversation
It's not nix's job to fix kernel bugs; we have to live with them. You should adjust the test so that it accepts all error codes that the kernel might return in that situation. |
50417ff
to
0617c24
Compare
Sorry, forgot to cross reference here: CraneStation/wasi-common#16 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't forget to add a CHANGELOG entry, too.
test/test_fcntl.rs
Outdated
const LEN: usize = 100; | ||
let mut tmp = NamedTempFile::new().unwrap(); | ||
let fd = tmp.as_raw_fd(); | ||
let res = posix_fallocate(fd, 0, LEN as libc::off_t).unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test will fail if /tmp resides on a file system that doesn't support posix_fallocate
, like ZFS. The test must be adjusted to handle that error. Unfortunately, POSIX stipulates that the errno in that case shall be EINVAL
, which can also indicate several other problems.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I wasn't aware of this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added in some explanation in the test, in case the test fails possibly due to filesystem not supporting this operation.
test/test_fcntl.rs
Outdated
let (rd, _wr) = pipe().unwrap(); | ||
let errno = posix_fallocate(rd as RawFd, 0, 100).unwrap(); | ||
match Errno::from_i32(errno) { | ||
Errno::EBADF |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't you narrow this list down? I don't think there are very many different error codes that could be returned in this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure!
0617c24
to
bbd498d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't forget to add a CHANGELOG entry. And please don't squash until the end; it makes incremental review more difficult.
@@ -504,3 +504,16 @@ mod posix_fadvise { | |||
Errno::result(res) | |||
} | |||
} | |||
|
|||
#[cfg(any( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can add dragonfly, too. You can also add NetBSD, if you make a PR to libc first.
test/test_fcntl.rs
Outdated
match Errno::from_i32(res) { | ||
Errno::EINVAL => { | ||
eprintln!(r#" | ||
`posix_fallocate` returned EINVAL. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to print this info out; a comment is sufficient. And please keep it to 80 characters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay. It is in comment now.
test/test_fcntl.rs
Outdated
use nix::unistd::pipe; | ||
|
||
#[test] | ||
fn test_success() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Putting "test" in the function name is redundant with the "test" in the module name. You can shorten it to "success".
src/fcntl.rs
Outdated
any(target_os = "wasi", target_env = "wasi"), | ||
target_env = "freebsd" | ||
))] | ||
pub fn posix_fallocate(fd: RawFd, offset: libc::off_t, len: libc::off_t) -> Result<libc::c_int> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A better return type would be Result<()>
, because the only non-error value ever returned is 0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The spec says that posix_fallocate
returns the error number and it does not set errno
.
fallocate
returns -1
on error and set errno
. The two functions are behaving quite differently regarding to the returned value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have converted to return type to Result<()>
. However, I have concerns on whether we should follow POSIX and return Errno directly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
posix_fallocate
does what? That's bonkers. But sure enough; you're correct. However, we shouldn't expose that inconsistency to userspace. Better for Nix's posix_fallocate
to have the same interface as other Nix functions. We should turn its return value into a Result<()>
.
test/test_fcntl.rs
Outdated
#[test] | ||
fn test_errno() { | ||
let (rd, _wr) = pipe().unwrap(); | ||
let errno = posix_fallocate(rd as RawFd, 0, 100).unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be unwrap_err
?
test/test_fcntl.rs
Outdated
target_os = "emscripten", | ||
target_os = "fuchsia", | ||
any(target_os = "wasi", target_env = "wasi"), | ||
target_env = "freebsd"))] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/target_env/target_os/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
src/fcntl.rs
Outdated
target_os = "emscripten", | ||
target_os = "fuchsia", | ||
any(target_os = "wasi", target_env = "wasi"), | ||
target_env = "freebsd" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/target_env/target_os/
39818d2
to
cf1f4ae
Compare
@asomers Sorry for squashing again! I will not do this for later commits. Also, I am going to add an entry to the |
test/test_fcntl.rs
Outdated
// According to POSIX.1-2008, its implementation shall | ||
// return `EINVAL` if `len` is 0, `offset` is negative or | ||
// the filesystem does not support this operation. | ||
// According to POSIX.1-2001, its implementation shall |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment is duped.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✂️ ed
test/test_fcntl.rs
Outdated
| Sys(Errno::EBADF) => (), | ||
errno => | ||
panic!( | ||
"errno does not match posix_fallocate spec, errno={}", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would simply say "unexpected errno, {}, errno
test/test_fcntl.rs
Outdated
assert_eq!(&data as &[u8], &[0u8; LEN] as &[u8]); | ||
} | ||
Err(nix::Error::Sys(Errno::EINVAL)) => { | ||
// `posix_fallocate` returned EINVAL. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me suggest some wording that would sound more natural to a native english speaker:
POSIX requires posix_fallocate
to return EINVAL
both for invalid arguments (i.e. len
< 0) and if the operation is not supported by the file system. There's no way to tell for sure whether the file system supports posix_fallocate
, so we must pass the test if it returns EINVAL
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your suggestion! 😄
test/test_fcntl.rs
Outdated
Ok(_) => { | ||
let mut data = [1u8; LEN]; | ||
assert_eq!(tmp.read(&mut data).expect("read failure"), LEN); | ||
assert_eq!(&data as &[u8], &[0u8; LEN] as &[u8]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of casting, you should be able to do &data[..], &[0u8; LEN][..]
CHANGELOG.md
Outdated
@@ -773,3 +773,5 @@ This project adheres to [Semantic Versioning](http://semver.org/). | |||
([#335](https://github.com/nix-rust/nix/pull/335)) | |||
|
|||
## [0.5.0] 2016-03-01 | |||
- Added `posix_fallocate`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This CHANGELOG entry is seriously dislocated. It should be up in the "Unreleased" section.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, sorry
It is surprising to see tests failing under |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please rebase the PR onto master. Never merge master into PRs. As for the test failures, it looks like something on Travis's side changed.
481b162
to
877afa1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bors r+
1105: posix_fallocate support r=asomers a=dingxiangfei2009 This PR add [`posix_fallocate`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_fallocate.html), which is available on - Linux - FreeBSD - Android - Emscripten - Fuchsia - WASI Here is a question: for some reason, `posix_fallocate` returns `EBADF` instead of `EPIPE` if a FIFO file descriptor is passed in on Linux 4.19.64. In the test `EBADF` is used for now, but I would like to know if such behaviour is expected. Co-authored-by: Ding Xiang Fei <[email protected]>
Sorry, but you need to rebase again to fix the test failures. |
Build succeeded
|
This PR add
posix_fallocate
, which is available onHere is a question: for some reason,
posix_fallocate
returnsEBADF
instead ofEPIPE
if a FIFO file descriptor is passed in on Linux 4.19.64. In the testEBADF
is used for now, but I would like to know if such behaviour is expected.