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

Allocation on macOS is not working, while it does with fs2 #15

Open
nazar-pc opened this issue Mar 7, 2024 · 1 comment
Open

Allocation on macOS is not working, while it does with fs2 #15

nazar-pc opened this issue Mar 7, 2024 · 1 comment

Comments

@nazar-pc
Copy link

nazar-pc commented Mar 7, 2024

I just replaced some of fs2 usage with fs4 and got following error when calling file.allocate() on macOS from multiple users:

No space left on device (os error 28)

In one example it happened with ~750GB file and then file.allocate() was called with the same file size again, which failed with ^ error.

Here is what implementation looks in fs2, it is much more verbose than in fs4:
https://github.com/danburkert/fs2-rs/blob/9a340454a8292df025de368fc4b310bb736f382f/src/unix.rs#L108-L137

I'll be switching to fs2 for that use case for now.

@al8n
Copy link
Owner

al8n commented Mar 8, 2024

Hi, this is because in fs2, if the contiguous allocation fails, then try non-contiguous allocation. rustix does not provide the same functionality (fcntl_preallocate) as libc

I review the source code of rustix's fallocate, it already tries to allocate non-contiguous when contiguous allocation fails, so it is weird.

The fallocate source code in rustix is the same as what fs2's allocate does.

#[cfg(apple)]
pub(crate) fn fallocate(
    fd: BorrowedFd<'_>,
    mode: FallocateFlags,
    offset: u64,
    len: u64,
) -> io::Result<()> {
    let offset: i64 = offset.try_into().map_err(|_e| io::Errno::INVAL)?;
    let len = len as i64;

    assert!(mode.is_empty());

    let new_len = offset.checked_add(len).ok_or(io::Errno::FBIG)?;
    let mut store = c::fstore_t {
        fst_flags: c::F_ALLOCATECONTIG,
        fst_posmode: c::F_PEOFPOSMODE,
        fst_offset: 0,
        fst_length: new_len,
        fst_bytesalloc: 0,
    };
    unsafe {
        if c::fcntl(borrowed_fd(fd), c::F_PREALLOCATE, &store) == -1 {
            // Unable to allocate contiguous disk space; attempt to allocate
            // non-contiguously.
            store.fst_flags = c::F_ALLOCATEALL;
            let _ = ret_c_int(c::fcntl(borrowed_fd(fd), c::F_PREALLOCATE, &store))?;
        }
        ret(c::ftruncate(borrowed_fd(fd), new_len))
    }
}

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

No branches or pull requests

2 participants