Declaraciones públicas de zig/storage.zig (conduit-zig (SDK consumido)).
apps/docs/generated/zig/conduit.jsonPágina generada desde
conduit@conduit-0.1.0-f7J_7zg5DwCsHBHItwdOz9ZVq8cvH7ceFsk7-m3-T61t (zig/root.zig). No se edita a mano:bun run docs:genla regenera ybun run docs:checkfalla si difiere.
Staging storage of the receiving side: space reservation, direct I/O and durability (spec/wire-v2.md §8). No wire change: it applies to v1 sessions too.
reserve: real blocks for the whole file at create. Linux fallocate
mode 0, macOS F_PREALLOCATE (contiguous, then any) + ftruncate,
elsewhere nothing. Never the posix_fallocate emulation (it writes
zeros). ENOSPC/EDQUOT are error.NoSpace (→ 507); a filesystem
without the call is .unsupported and the upload goes on unreserved.openDirect: a second descriptor on the staging file that bypasses the
page cache. Linux: O_DIRECT set with F_SETFL (the kernel refuses it
with EINVAL where the filesystem has no direct I/O) and the alignment
from statx(STATX_DIOALIGN); macOS: F_NOCACHE, no alignment.Pool + DirectWriter: one chunk streamed through two aligned buffers;
a full buffer goes out while the other fills, through io_uring on
Linux. Fallbacks, chosen at runtime and counted in Stats: ring refused
(ENOSYS, EPERM under seccomp, kernel.io_uring_disabled) or switched off
→ pwrite on the direct descriptor; a direct write refused (EINVAL) →
buffered pwrite of the same bytes; short write → the rest buffered;
no buffer free or chunk not eligible → the whole chunk buffered.syncData: fdatasync (Linux), F_FULLFSYNC (macOS), fsync
elsewhere — called once, at commit.Every path that fails returns an error; nothing here panics on I/O. The writer always drains what it submitted before returning, so a buffer is never reused (or a descriptor closed) while the kernel may still read it.
storage.is_linuxconst · línea 38
pub const is_linux = builtin.os.tag == .linuxSin ///.
storage.is_darwinconst · línea 39
pub const is_darwin = builtin.os.tag.isDarwin()Sin ///.
storage.page_alignconst · línea 45
pub const page_align = 4096Alignment of the direct buffers and lower bound of the offset alignment used (a page: a direct region never shares a page with a buffered tail).
storage.Injecttype · línea 49
pub const Inject = if (builtin.is_test) struct else voidFaults a test can force on each fallback; void outside tests.
storage.Optionstype · línea 69
pub const Options = structSin ///.
storage.Options.validfn · línea 94
pub fn valid(o: Options) boolSin ///.
storage.Options.max_direct_writersconst · línea 99
pub const max_direct_writers = 256Sin ///.
storage.Statstype · línea 103
pub const Stats = structWhat the storage layer did, for operators and tests (monotonic counters).
storage.ReserveErrorconst · línea 141
pub const ReserveError = error{ /// ENOSPC / EDQUOT: there is not room for the whole file. NoSpace, /// Larger than the filesystem allows for one file. FileTooBig, Io, }Sin ///.
storage.Reservedtype · línea 149
pub const Reserved = enumSin ///.
storage.reservefn · línea 152
pub fn reserve(f: zfs.File, len: u64, o: *const Options) ReserveError!ReservedReal blocks for [0, len) of f, file size set to len.
storage.discardfn · línea 211
pub fn discard(f: zfs.File) voidGive back the blocks of an abandoned staging file: truncate it to 0.
A reservation (fallocate, F_PREALLOCATE) belongs to the inode, not
the name, so unlinking alone keeps it while any descriptor is open — and
a pinned writer keeps one until it lets go. After this, a late pwrite
of that writer only re-extends the file sparsely, by what it writes.
Only an inode no name links any more is truncated: call it after the unlink. A file some finalizer moved or linked elsewhere before failing keeps its bytes. Best effort: a failure is logged and the blocks go with the last close.
storage.SyncErrorconst · línea 260
pub const SyncError = error{ NoSpace, Io }Sin ///.
storage.syncDatafn · línea 263
pub fn syncData(f: zfs.File) SyncError!voidData (and the metadata needed to read it back) on stable storage.
storage.Directtype · línea 284
pub const Direct = structSin ///.
storage.Direct.closefn · línea 292
pub fn close(d: Direct) voidSin ///.
storage.openDirectfn · línea 300
pub fn openDirect(root: *const Root, name: []const u8, main: zfs.File, o: *const Options, stats: *Counters) ?DirectA page-cache-bypassing descriptor on the staging entry name of root,
which must be the file main is open on; null when the platform or the
filesystem has no direct I/O (the session then writes buffered).
storage.WriteErrorconst · línea 353
pub const WriteError = error{ NoSpace, Io }Sin ///.
storage.Slottype · línea 357
pub const Slot = structBuffers (and ring) of one direct writer; owned by the pool, lent to one chunk at a time.
storage.Pooltype · línea 366
pub const Pool = structUp to Options.direct_writers slots. acquire/release are called
under the caller's lock (the server mutex); the counters are atomic.
storage.Pool.initfn · línea 378
pub fn init(gpa: Allocator, o: *const Options) Allocator.Error!PoolSin ///.
storage.Pool.deinitfn · línea 388
pub fn deinit(p: *Pool, gpa: Allocator) voidSin ///.
storage.Pool.statsfn · línea 397
pub fn stats(p: *const Pool) StatsSin ///.
storage.Pool.acquirefn · línea 403
pub fn acquire(p: *Pool, gpa: Allocator) ?*SlotA slot with its buffers, or null (none free, or no memory for the buffers): the chunk is then written buffered.
storage.Pool.releasefn · línea 421
pub fn release(p: *Pool, s: *Slot) voidSin ///.
storage.DirectWritertype · línea 430
pub const DirectWriter = structWrites one chunk [offset, offset + len) of the staging file. Built by
the server only for eligible chunks (direct descriptor, len >= direct_min, offset a multiple of offset_align, a slot).
storage.DirectWriter.initfn · línea 447
pub fn init(pool: *Pool, slot: *Slot, direct: Direct, buffered: zfs.File, offset: u64) DirectWriterSin ///.
storage.DirectWriter.eligiblefn · línea 454
pub fn eligible(o: *const Options, d: ?Direct, offset: u64, len: u64) boolWhether a chunk can go direct (the server also needs a free slot).
storage.DirectWriter.writefn · línea 459
pub fn write(w: *DirectWriter, bytes: []const u8) WriteError!voidSin ///.
storage.DirectWriter.finishfn · línea 473
pub fn finish(w: *DirectWriter) WriteError!voidEnd of the body: the aligned part of what is buffered goes direct, the tail buffered; returns once every byte is written (or failed).
storage.DirectWriter.abandonfn · línea 487
pub fn abandon(w: *DirectWriter) voidGive up: waits for whatever the kernel still holds, ignores results. Idempotent; after it no buffer is in use.
storage.writeAllAtfn · línea 656
pub fn writeAllAt(f: zfs.File, bytes: []const u8, offset: u64, o: *const Options) WriteError!voidBuffered pwrite of the whole of bytes, errors folded to WriteError.
storage.countBufferedfn · línea 664
pub fn countBuffered(p: *Pool) voidSin ///.
storage.countReservefn · línea 668
pub fn countReserve(p: *Pool, r: Reserved) voidSin ///.