Expand description
C ABI for the block-device framework.
Every sister crate (qcow2 reader, partition probe, fs-* drivers) speaks
through the FsCoreDevice handle defined here, so consumers (Swift
FSKit modules, Go callers, C programs) only learn one device-handle
type and one error convention.
§Conventions
- Handles are opaque
*mut FsCoreDevice. Allocate via a constructor in one of the sister crates (e.g.qcow2_openfrom rust-img-qcow2), free viafs_core_device_closeregardless of which crate created it. - Error reporting is errno-style: every fallible function returns an
FsCoreErrorCode(0 = OK, non-zero = failure) and stashes a human message in a thread-local. Read it viafs_core_last_error_message. - Every entry point catches Rust panics with
catch_unwindand maps them toFsCoreErrorCode::Panic. Crossing an FFI boundary while unwinding is UB; the catch-net is non-negotiable. - Thread safety: handles wrap
Arc<dyn BlockDevice>, which isSend + Syncby trait bound. Multiple threads can call read/write concurrently as long as the underlying device’s locking permits it.
Structs§
- FsCore
Callback Cfg - Configuration passed to
fs_core_device_from_callbacks. - FsCore
Device - Opaque handle wrapping an
Arc<dyn BlockDevice>. Allocated by sister crates’ constructors and freed viafs_core_device_close.
Enums§
- FsCore
Error Code - Numeric error codes mirrored across every sister crate’s C ABI.
Functions§
- ffi_
guard - Helper for sister crates: run
body, catch panics, map errors to codes, stash the message in the thread-local. Returns the error code. - ffi_
guard_ cleanup - Run a cleanup body — a
close, afree— catching a panic so it cannot unwind into C, and leaving the error slot untouched. - ffi_
guard_ or - Run
body, catching a panic and returningfailinstead — and recording the panic’s message where a caller can read it. - fs_
core_ ⚠device_ close - Free a device handle. Safe to call with NULL (no-op).
- fs_
core_ ⚠device_ flush - Flush pending writes to stable storage.
- fs_
core_ ⚠device_ from_ callbacks - Build an
FsCoreDevicebacked by host-provided callbacks. Returns NULL on failure (config null, read callback null, etc.) and stashes detail in the thread-local last-error. - fs_
core_ ⚠device_ is_ writable - True if
write_atis likely to succeed. Returns false on NULL. - fs_
core_ ⚠device_ read_ at - Read exactly
lenbytes fromoffsetintobuf.bufmust be at leastlenbytes. Returns anFsCoreErrorCode. - fs_
core_ ⚠device_ size_ bytes - Total device size in bytes. Returns 0 if
handleis NULL. - fs_
core_ ⚠device_ slice_ ro - Read-only slice. Writes via the returned handle return
FS_CORE_READ_ONLYregardless of the parent’s writability. - fs_
core_ ⚠device_ slice_ rw - Read-write slice. Writes are forwarded to the parent at
start + offset; writes outside[0, length)returnFS_CORE_OUT_OF_BOUNDS. If the parent reportsis_writable() == false, write attempts returnFS_CORE_READ_ONLY. - fs_
core_ ⚠device_ write_ at - Write exactly
lenbytes frombuftooffset. ReturnsReadOnlyfor read-only devices. - fs_
core_ ⚠file_ open - Open
path(NUL-terminated UTF-8) as aFileDeviceand return a handle. Passwritable=truefor RW. On failure returns NULL and the thread-local last-error has detail. - fs_
core_ last_ error_ message - Return a pointer to the calling thread’s most recent error message, or NULL if there is none. The pointer is owned by the framework and remains valid until the next FFI call on this thread.
- panic_
message - What a caught panic actually said.
- set_
last_ error - Stash a message in the thread-local, replacing any previous one. Public to sister crates so they can populate it for their own error paths.
Type Aliases§
- FsCore
Flush Cb - Flush/fsync callback. NULL → flush is a no-op.
- FsCore
Read Cb - Read callback. Returns 0 on success, non-zero (errno-like) on failure.
Must fully fill
lenbytes — short reads are treated as I/O errors. - FsCore
Write Cb - Write callback. NULL → device is read-only.