Thin Elixir wrapper over Ferricstore.Bitcask.NIF.fs_* that:
- Preserves bang-style raise semantics (
touch!,mkdir_p!,rm!,rm_rf!) matchingFile.*call sites we're replacing. Keeps the non-bang variants returning
:ok | {:error, {kind, msg}}so callers usingwith/casecan pattern-match on the stable atom kinds.
Metadata ops and bounded file reads run on DirtyIo, while recursive removal runs on Tokio's blocking pool. This keeps filesystem work off Normal schedulers.
For potentially long operations (rm_rf of a large tree), the caller
owns the waiting: fs_rm_rf_async returns immediately and delivers a
:tokio_complete message. The rm_rf!/1 helper here blocks the
calling process until the message arrives — keeping the call-site
shape compatible with File.rm_rf!/1.
Summary
Functions
Recursive remove, blocking the caller until the async NIF completes.
Types
Functions
@spec append_sync_nofollow_bounded(binary(), binary(), non_neg_integer()) :: :ok | fs_error()
@spec atomic_replace_nofollow(binary(), binary(), non_neg_integer()) :: :ok | fs_error()
@spec mkdir_p!(binary()) :: :ok
@spec read_nofollow(binary(), non_neg_integer()) :: {:ok, binary()} | fs_error()
@spec read_private_nofollow(binary(), non_neg_integer()) :: {:ok, binary()} | fs_error()
@spec rm!(binary()) :: :ok
Recursive remove, blocking the caller until the async NIF completes.
Idempotent: removing a non-existent path is :ok. Never raises for
missing paths — matches File.rm_rf/1 (returns {:ok, []} there).
@spec rm_rf!(binary()) :: :ok
@spec touch!(binary()) :: :ok