Skip to main content

base_scheduler/
file_allocate.rs

1// Released under the MIT License.
2// Copyright, 2026, by Samuel Williams.
3
4use super::FileOperation;
5use crate::{AllocationMode, Cancellation, OperationResult};
6use std::future::Future;
7
8/// Optional file-space reservation capability, with Linux `fallocate` semantics for ordinary allocation and `KEEP_SIZE`.
9///
10/// This optional capability has Linux-style semantics. Backends omit its implementation where these semantics are unsupported, allowing generic consumers to require support at compile time. Filesystem and per-file support still vary at runtime; their errors are preserved. Allocation is not emulated by resizing or writing zeros.
11///
12/// An allocation-only adapter does not need to forward the core file operations:
13///
14/// ```
15/// use base_scheduler::{AllocationMode, Cancellation, FileAllocate, FileOperation, OperationResult};
16/// struct AllocationOnly<S>(S);
17/// impl<S: FileAllocate> FileOperation for AllocationOnly<S> {
18///     type File = S::File;
19/// }
20/// impl<S: FileAllocate> FileAllocate for AllocationOnly<S> {
21///     async fn file_allocate(&self, file: &Self::File, offset: u64, length: u64, mode: AllocationMode, cancellation: &Cancellation) -> OperationResult<()> {
22///         self.0.file_allocate(file, offset, length, mode, cancellation).await
23///     }
24/// }
25/// ```
26pub trait FileAllocate: FileOperation {
27    /// Reserve backing space for `[offset, offset + length)` on a writable file. `Extend` grows the logical length when necessary; `KeepSize` preserves it. Both modes preserve existing contents and the shared cursor. Subsequent writes in the reserved range have the underlying filesystem's allocation guarantee against running out of space.
28    ///
29    /// Length must be positive and the range end must fit in `i64`; invalid ranges return `InvalidInput`. Filesystem limits and errors, including unsupported allocation, are reported. This does not unshare copy-on-write extents, guarantee durability, or order concurrent file operations. Await related operations sequentially and use `file_sync` for synchronization.
30    ///
31    /// The future is lazy. Cancellation before dispatch prevents submission, and blocking workers check again before execution. Started blocking operations preserve their actual result; native cancellation is best effort, with successful completion winning concurrent cancellation. The backend retains the file until access ends even if the waiting future is dropped. Errors or cancellation do not promise rollback of partial filesystem changes.
32    fn file_allocate(
33        &self,
34        file: &Self::File,
35        offset: u64,
36        length: u64,
37        mode: AllocationMode,
38        cancellation: &Cancellation,
39    ) -> impl Future<Output = OperationResult<()>> + Send;
40}