If we decide to replace fs2
with fs4
, I think supporting FreeBSD + ZFS could be as simple as this:
// sanakirja/src/environment/mod.rs
// ...
#[cfg(feature = "mmap")]
use fs4::FileExt;
// ...
#[cfg(feature = "mmap")]
fn fallocate(file: &std::fs::File, length: u64) -> Result<(), Error> {
let ret = file.allocate(length);
// Workaround for FreeBSD + ZFS
#[cfg(target_os = "freebsd")]
if let Err(ref err) = ret {
// libc::EINVAL on FreeBSD
const EINVAL: i32 = 22;
if err.raw_os_error().unwrap_or(0) == EINVAL {
// todo: decide if a fallback (e.g. `libc::ftruncate`) makes sense here
return Ok(());
}
}
Ok(ret?)
}
I take back what I said about fs4, it discards the error returned from rustix and then returns errno. This should be fine on Linux because rustix uses fallocate
instead of posix_fallocate
, but fs4 will still be broken on FreeBSD.
tl;dr: We can switch fs2 to fs4 to fix Linux, but it will still have the same issue on FreeBSD
I’ve started writing a crate that allows detecting the filesystem that a particular file resides on. This might help for the edge case of posix_fallocate
on FreeBSD+ZFS
RUM725HY2MWXXR7M3NHTTXD7M2HM2XCSI77PXODAXAHHLVNX6Z7QC
Here is a much simpler patch. I submitted a fix to fs4 upstream to return the correct error code for posix_fallocate
, and the maintainer bumped the version to 0.6.3.
This has the added benefit that fs4 is actively maintained, while fs2 hasn’t seen activity for more than 5 years despite a number of serious bugs and pull requests.
Thanks!
As noted on this fs2 issue,
posix_fallocate
has some issues on FreeBSD + ZFS.After a closer look, the implementation of
fs2::allocate
is not just broken on FreeBSD, it is also buggy on Linux.posix_fallocate
either returns0
or an error code, and it does not seterrno
. But on non-zero returnfs2::allocate
attempts to reconstruct the error by callingstd::io::Error::last_os_error
, which could either be0
or some unrelated error from a previous libc call.The following crates have the same problem:
These crates have correct implementations:
fs2
that delegates torustix
for unix-like)I think the quickest fix is to replace the
fs2
dependency withfs4
. Another option is to introduce alibc
dependency and handcode it ourselves. Any and all ideas are appreciated.