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_fallocatehas some issues on FreeBSD + ZFS.After a closer look, the implementation of
fs2::allocateis not just broken on FreeBSD, it is also buggy on Linux.posix_fallocateeither returns0or an error code, and it does not seterrno. But on non-zero returnfs2::allocateattempts to reconstruct the error by callingstd::io::Error::last_os_error, which could either be0or some unrelated error from a previous libc call.The following crates have the same problem:
These crates have correct implementations:
fs2that delegates torustixfor unix-like)I think the quickest fix is to replace the
fs2dependency withfs4. Another option is to introduce alibcdependency and handcode it ourselves. Any and all ideas are appreciated.