|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Transactional media-download storage over named RA8 VFS mounts. More...
#include "mdl_storage_vfs.h"#include <stdint.h>#include "ra8_attributes.h"#include "ra8_err.h"#include "ra8_io_vfs.h"Go to the source code of this file.
Data Structures | |
| struct | path_facts_t |
| Module-local path facts proven before any filesystem mutation. More... | |
Functions | |
| static bool | internal_is_dot_component (const char *text, uint16_t len) |
Return whether one component is exactly "." or "..". | |
| static ra8_err_t | internal_bounded_length (const char *text, uint16_t cap, uint16_t *out_len) |
| Measure one string without reading past a fixed capacity. | |
| static ra8_err_t | internal_mount_prefix (const char *path, uint16_t len, uint16_t *out_colon) |
| Validate the mount prefix and locate its colon. | |
| static ra8_err_t | internal_path_components (const char *path, uint16_t len, uint16_t colon, uint16_t *out_slash) |
| Validate canonical non-traversing components after mount:/. | |
| static ra8_err_t | internal_path_facts (const char *path, path_facts_t *out) |
| Prove a destination is a bounded canonical named-VFS file path. | |
| static ra8_err_t | internal_stage_leaf_check (const char *leaf, uint16_t *out_len) |
| Validate the caller-reserved simple staging leaf. | |
| static void | internal_copy (char *dst, const char *src, uint16_t len) |
| Copy a bounded NUL-terminated byte string. | |
| static bool | internal_leaf_equals (const char *destination_leaf, const char *stage_leaf) |
| Compare a destination leaf with the reserved staging leaf. | |
| static ra8_err_t | internal_build_stage (mdl_storage_vfs_t *ctx, const path_facts_t *facts, uint16_t stage_len) |
| Build the caller-owned sibling staging path without truncation. | |
| static ra8_err_t | internal_parent_check (mdl_storage_vfs_t *ctx, uint16_t last_slash) |
| Require the destination parent to exist and be a directory. | |
| static ra8_err_t | internal_final_absent (const char *destination) |
| Refuse an existing final, distinguishing directories as bad paths. | |
| static ra8_err_t | internal_remove_stale_stage (const char *staging_path) |
| Remove a stale owned regular stage, but never a directory. | |
| static ra8_err_t | internal_close_writer (mdl_storage_vfs_t *ctx) |
| Close the writer exactly once and retain staged cleanup state. | |
| static ra8_err_t | internal_begin_prepare_stage (mdl_storage_vfs_t *ctx, const path_facts_t *facts) |
| Stage-preparation chain: leaf check, build, parent check, and cleanup. | |
| static ra8_err_t | internal_begin (void *opaque, const char *destination) |
| Coordinator callback: create the private sibling transaction file. | |
| static ra8_err_t | internal_write (void *opaque, const uint8_t *data, uint16_t len, uint16_t *written) |
| Coordinator callback: append one all-or-error bounded chunk. | |
| static ra8_err_t | internal_staged_file_check (const mdl_storage_vfs_t *ctx, uint64_t expected) |
| Check the closed stage is still a regular file of the exact size. | |
| static ra8_err_t | internal_validate (void *opaque, uint64_t total_bytes, const uint8_t sha256[k_ra8_mdl_sha256_bytes]) |
| Coordinator callback: close, size-check, and delegate validation. | |
| static ra8_err_t | internal_commit (void *opaque) |
| Coordinator callback: one serialized no-replace same-mount publish. | |
| static ra8_err_t | internal_abort_stage (mdl_storage_vfs_t *ctx, ra8_err_t first_err) |
| Finish cleanup after the writer, if any, has been closed. | |
| static ra8_err_t | internal_abort (void *opaque) |
| Coordinator callback: best-effort, retryable, idempotent cleanup. | |
| ra8_err_t | mdl_storage_vfs_init (mdl_storage_vfs_t *storage, const mdl_storage_vfs_config_t *config, ra8_mdl_storage_iface_t *out_iface) |
| Initialise one VFS storage adapter and bind its coordinator interface. | |
Transactional media-download storage over named RA8 VFS mounts.
Implements the downloader transaction callbacks with bounded validation, a caller-reserved sibling staging file, and one final VFS no-replace rename. All state remains in the caller-owned adapter context.
Definition in file mdl_storage_vfs.c.
|
static |
Coordinator callback: best-effort, retryable, idempotent cleanup.
Closes a live writer once and removes only the reserved private stage.
| [in,out] | opaque | Bound mdl_storage_vfs_t context. |
| k_ra8_ok | Context was idle/committed or is now clean and idle. |
| k_ra8_err_null_ptr | Context pointer was null. |
| other | First close, metadata, or unlink error. |
opaque is null or points to an initialized adapter. Definition at line 821 of file mdl_storage_vfs.c.
References internal_abort_stage(), internal_close_writer(), k_mdl_storage_vfs_committed, k_mdl_storage_vfs_idle, k_ra8_err_null_ptr, k_ra8_ok, RA8_INTERNAL, and mdl_storage_vfs_t::state.
|
static |
Finish cleanup after the writer, if any, has been closed.
Preserves the earliest error while type-checking and removing the stage.
| [in,out] | ctx | Adapter context naming a possibly owned private artifact. |
| [in] | first_err | Prior close/sync status to preserve. |
| k_ra8_ok | No stage remained and no prior error occurred. |
| other | first_err when non-success, otherwise stat/unlink failure. |
ctx is non-null and its writer is closed. Definition at line 785 of file mdl_storage_vfs.c.
References ra8_io_vfs_stat_t::exists, ra8_io_vfs_stat_t::is_directory, k_mdl_storage_vfs_idle, k_ra8_err_invalid_state, k_ra8_ok, RA8_INTERNAL, ra8_io_vfs_stat(), ra8_io_vfs_unlink(), mdl_storage_vfs_t::staging_path, and mdl_storage_vfs_t::state.
Referenced by internal_abort().
|
static |
Coordinator callback: create the private sibling transaction file.
Validates paths and parent policy before removing an owned stale stage and opening a fresh bounded writer on the selected VFS mount.
| [in,out] | opaque | Bound mdl_storage_vfs_t context. |
| [in] | destination | Canonical final named-VFS path candidate. |
| k_ra8_ok | A private writer is open in the writing state. |
| k_ra8_err_null_ptr | A required pointer was null. |
| k_ra8_err_invalid_state | A transaction is already active. |
| other | First path, policy, cleanup, or VFS-open error. |
opaque points to an initialized adapter context. Definition at line 556 of file mdl_storage_vfs.c.
References mdl_storage_vfs_t::bytes_written, mdl_storage_vfs_t::destination, mdl_storage_vfs_t::file, internal_begin_prepare_stage(), internal_copy(), internal_path_facts(), k_mdl_storage_vfs_committed, k_mdl_storage_vfs_idle, k_mdl_storage_vfs_writing, k_ra8_err_invalid_state, k_ra8_err_null_ptr, k_ra8_fs_mode_write, k_ra8_ok, path_facts_t::length, RA8_INTERNAL, ra8_io_vfs_file_open(), mdl_storage_vfs_t::staging_path, and mdl_storage_vfs_t::state.
Referenced by mdl_storage_vfs_init().
|
static |
Stage-preparation chain: leaf check, build, parent check, and cleanup.
Runs the ordered stage-preparation steps, stopping at the first failure so no later step observes a half-prepared stage.
| [in,out] | ctx | Adapter context whose stage fields this chain populates. |
| [in] | facts | Parsed destination-path facts from internal_path_facts. |
| k_ra8_ok | Every preparation step succeeded. |
| other | The first failing step's status. |
ctx->destination and ctx->stage_leaf are already populated. facts describes the same destination as ctx->destination. ctx->staging_path names an absent, ready-to-open path. Definition at line 518 of file mdl_storage_vfs.c.
References mdl_storage_vfs_t::destination, internal_build_stage(), internal_final_absent(), internal_parent_check(), internal_remove_stale_stage(), internal_stage_leaf_check(), k_ra8_ok, path_facts_t::last_slash, RA8_INTERNAL, mdl_storage_vfs_t::stage_leaf, and mdl_storage_vfs_t::staging_path.
Referenced by internal_begin().
|
static |
Measure one string without reading past a fixed capacity.
Searches only the declared range and fails closed if no NUL appears.
| [in] | text | Candidate bounded string. |
| [in] | cap | Maximum bytes that may be inspected. |
| [out] | out_len | Receives bytes before the terminator. |
| k_ra8_ok | A terminator was found and length returned. |
| k_ra8_err_null_ptr | A required pointer was null. |
| k_ra8_err_invalid_size | No terminator occurred within cap. |
text is null or addresses cap readable bytes. out_len is null or writable. out_len with a value below cap. Definition at line 76 of file mdl_storage_vfs.c.
References k_ra8_err_invalid_size, k_ra8_err_null_ptr, and k_ra8_ok.
Referenced by internal_path_facts(), and internal_stage_leaf_check().
|
static |
Build the caller-owned sibling staging path without truncation.
Reuses the final path parent and appends the reserved private leaf.
| [in,out] | ctx | Adapter context holding destination and output path buffers. |
| [in] | facts | Proven destination path facts. |
| [in] | stage_len | Proven reserved-leaf byte length. |
| k_ra8_ok | A complete same-parent staging path was built. |
| k_ra8_err_invalid_arg | Final and staging leaves would be identical. |
| k_ra8_err_invalid_size | Fixed path capacity is insufficient. |
facts came from internal_path_facts. stage_len. ctx. Definition at line 350 of file mdl_storage_vfs.c.
References mdl_storage_vfs_t::destination, internal_leaf_equals(), k_mdl_storage_vfs_path_capacity, k_ra8_err_invalid_arg, k_ra8_err_invalid_size, k_ra8_ok, path_facts_t::last_slash, mdl_storage_vfs_t::stage_leaf, and mdl_storage_vfs_t::staging_path.
Referenced by internal_begin_prepare_stage().
|
static |
Close the writer exactly once and retain staged cleanup state.
Attempts a supported sync before close and clears the live handle first.
| [in,out] | ctx | Active adapter transaction context. |
| k_ra8_ok | No writer was open or sync and close succeeded. |
| other | First supported sync failure, otherwise close failure. |
ctx is non-null and owns at most one VFS file. Definition at line 486 of file mdl_storage_vfs.c.
References mdl_storage_vfs_t::file, k_mdl_storage_vfs_staged, k_ra8_err_not_supported, k_ra8_ok, RA8_INTERNAL, ra8_io_vfs_file_close(), ra8_io_vfs_file_sync(), and mdl_storage_vfs_t::state.
Referenced by internal_abort(), and internal_validate().
|
static |
Coordinator callback: one serialized no-replace same-mount publish.
Rechecks stage and final metadata immediately before one VFS rename.
| [in,out] | opaque | Bound mdl_storage_vfs_t context. |
| k_ra8_ok | Artifact was already committed or is now published. |
| k_ra8_err_null_ptr | Context pointer was null. |
| k_ra8_err_invalid_state | Artifact is not validated and ready. |
| other | Final policy, stage recheck, or rename failed. |
opaque points to an initialized adapter. Definition at line 745 of file mdl_storage_vfs.c.
References mdl_storage_vfs_t::bytes_written, mdl_storage_vfs_t::destination, internal_final_absent(), internal_staged_file_check(), k_mdl_storage_vfs_committed, k_mdl_storage_vfs_ready, k_ra8_err_invalid_state, k_ra8_err_null_ptr, k_ra8_ok, RA8_INTERNAL, ra8_io_vfs_rename(), mdl_storage_vfs_t::staging_path, and mdl_storage_vfs_t::state.
Referenced by mdl_storage_vfs_init().
|
static |
Copy a bounded NUL-terminated byte string.
Copies exactly len payload bytes and writes one terminator.
| [out] | dst | Destination spanning at least len + 1 bytes. |
| [in] | src | Source spanning at least len bytes. |
| [in] | len | Payload byte count, excluding NUL. |
len. Definition at line 296 of file mdl_storage_vfs.c.
References RA8_INTERNAL.
Referenced by internal_begin(), and mdl_storage_vfs_init().
|
static |
Refuse an existing final, distinguishing directories as bad paths.
Implements create-new publication policy with a non-mutating stat.
| [in] | destination | Canonical final path. |
| k_ra8_ok | Destination is absent. |
| k_ra8_err_exists | A regular destination already exists. |
| k_ra8_err_invalid_arg | Destination names a directory. |
| other | Underlying VFS stat failed. |
destination is non-null and canonical. Definition at line 425 of file mdl_storage_vfs.c.
References ra8_io_vfs_stat_t::exists, ra8_io_vfs_stat_t::is_directory, k_ra8_err_exists, k_ra8_err_invalid_arg, k_ra8_ok, RA8_INTERNAL, and ra8_io_vfs_stat().
Referenced by internal_begin_prepare_stage(), and internal_commit().
|
static |
Return whether one component is exactly "." or "..".
Compares the caller-bounded component without requiring a terminator.
| [in] | text | First component byte. |
| [in] | len | Number of bytes in the component. |
| true | The component is exactly "." or "..". |
| false | The component is any other byte sequence. |
text spans at least len readable bytes. len came from the bounded path parser. len is read. Definition at line 45 of file mdl_storage_vfs.c.
References RA8_INTERNAL.
Referenced by internal_path_components(), and internal_stage_leaf_check().
|
static |
Compare a destination leaf with the reserved staging leaf.
Compares through the first NUL but never beyond fixed leaf capacity.
| [in] | destination_leaf | Final path's last component. |
| [in] | stage_leaf | Validated reserved staging component. |
| true | Both leaves match through their shared terminator. |
| false | A byte differs or neither terminates within capacity. |
stage_leaf passed internal_stage_leaf_check. Definition at line 319 of file mdl_storage_vfs.c.
References k_mdl_storage_vfs_stage_leaf_capacity, and RA8_INTERNAL.
Referenced by internal_build_stage().
|
static |
Validate the mount prefix and locate its colon.
Enforces the named-VFS grammar before any device lookup or mutation.
| [in] | path | Canonical-path candidate. |
| [in] | len | Proven bytes before NUL. |
| [out] | out_colon | Receives the mount separator offset. |
| k_ra8_ok | A non-empty bounded mount prefix was found. |
| k_ra8_err_invalid_arg | Prefix grammar or length was invalid. |
path spans len plus its NUL terminator. out_colon is non-null and writable. len. Definition at line 110 of file mdl_storage_vfs.c.
References k_ra8_err_invalid_arg, k_ra8_io_vfs_name_max, and k_ra8_ok.
Referenced by internal_path_facts().
|
static |
Require the destination parent to exist and be a directory.
Temporarily terminates the owned destination at its parent boundary.
| [in,out] | ctx | Adapter holding the canonical destination buffer. |
| [in] | last_slash | Proven final separator offset. |
| k_ra8_ok | Parent exists as a directory. |
| k_ra8_err_not_found | Parent does not exist. |
| k_ra8_err_invalid_arg | Parent exists as a non-directory. |
| other | Underlying VFS stat failed. |
ctx is non-null and destination passed internal_path_facts. last_slash is the proven final separator. ctx during the temporary terminator change. Definition at line 388 of file mdl_storage_vfs.c.
References mdl_storage_vfs_t::destination, ra8_io_vfs_stat_t::exists, ra8_io_vfs_stat_t::is_directory, k_ra8_err_invalid_arg, k_ra8_err_not_found, k_ra8_ok, RA8_INTERNAL, and ra8_io_vfs_stat().
Referenced by internal_begin_prepare_stage().
|
static |
Validate canonical non-traversing components after mount:/.
Rejects empty, dot, control, alternate-separator, and colon components.
| [in] | path | Full named-VFS path. |
| [in] | len | Proven bytes before NUL. |
| [in] | colon | Proven mount-separator offset. |
| [out] | out_slash | Receives the final component separator. |
| k_ra8_ok | Every component is canonical and non-empty. |
| k_ra8_err_invalid_arg | Path grammar or a component was invalid. |
path spans len plus its NUL terminator. colon names a byte within path and out_slash is writable. out_slash before the final leaf. Definition at line 157 of file mdl_storage_vfs.c.
References internal_is_dot_component(), k_ra8_err_invalid_arg, and k_ra8_ok.
Referenced by internal_path_facts().
|
static |
Prove a destination is a bounded canonical named-VFS file path.
Composes bounded-length, mount-prefix, and component validation.
| [in] | path | Destination path candidate. |
| [out] | out | Receives proven length and final separator facts. |
| k_ra8_ok | The path is bounded and canonical. |
| k_ra8_err_null_ptr | A required pointer was null. |
| other | First bounded-path validation error. |
path is null or addresses the configured path capacity. out is non-null and writable. out. Definition at line 214 of file mdl_storage_vfs.c.
References internal_bounded_length(), internal_mount_prefix(), internal_path_components(), k_mdl_storage_vfs_path_capacity, k_ra8_ok, path_facts_t::last_slash, path_facts_t::length, and RA8_INTERNAL.
Referenced by internal_begin().
|
static |
Remove a stale owned regular stage, but never a directory.
Cleans only the adapter-reserved sibling name after type validation.
| [in] | staging_path | Canonical private sibling path. |
| k_ra8_ok | Stage was absent or was removed. |
| k_ra8_err_invalid_state | Reserved path names a directory. |
| other | Underlying VFS stat or unlink failed. |
staging_path is non-null and was built by internal_build_stage. staging_path. staging_path is never removed. Definition at line 456 of file mdl_storage_vfs.c.
References ra8_io_vfs_stat_t::exists, ra8_io_vfs_stat_t::is_directory, k_ra8_err_invalid_state, k_ra8_ok, RA8_INTERNAL, ra8_io_vfs_stat(), and ra8_io_vfs_unlink().
Referenced by internal_begin_prepare_stage().
|
static |
Validate the caller-reserved simple staging leaf.
Requires a bounded non-dot leaf with no separator, colon, or control.
| [in] | leaf | Candidate private filename. |
| [out] | out_len | Receives its bounded byte length. |
| k_ra8_ok | The leaf is safe for same-directory staging. |
| k_ra8_err_null_ptr | A required pointer was null. |
| k_ra8_err_invalid_arg | Leaf grammar was invalid. |
| k_ra8_err_invalid_size | No NUL fit within the fixed capacity. |
leaf is null or addresses the configured leaf capacity. out_len is non-null and writable. out_len to a non-zero bounded value. Definition at line 253 of file mdl_storage_vfs.c.
References internal_bounded_length(), internal_is_dot_component(), k_mdl_storage_vfs_stage_leaf_capacity, k_ra8_err_invalid_arg, k_ra8_ok, and RA8_INTERNAL.
Referenced by internal_begin_prepare_stage(), and mdl_storage_vfs_init().
|
static |
Check the closed stage is still a regular file of the exact size.
Uses VFS metadata to detect disappearance, type substitution, or size drift.
| [in] | ctx | Adapter context naming the closed private stage. |
| [in] | expected | Required byte length. |
| k_ra8_ok | A regular stage exists at the exact size. |
| k_ra8_err_not_found | Stage does not exist. |
| k_ra8_err_invalid_state | Stage is a directory. |
| k_ra8_err_invalid_size | Stage length differs from expected. |
| other | Underlying VFS stat failed. |
ctx is non-null and its staging path is canonical. Definition at line 658 of file mdl_storage_vfs.c.
References ra8_io_vfs_stat_t::exists, ra8_io_vfs_stat_t::is_directory, k_ra8_err_invalid_size, k_ra8_err_invalid_state, k_ra8_err_not_found, k_ra8_ok, RA8_INTERNAL, ra8_io_vfs_stat(), ra8_io_vfs_stat_t::size_bytes, and mdl_storage_vfs_t::staging_path.
Referenced by internal_commit(), and internal_validate().
|
static |
Coordinator callback: close, size-check, and delegate validation.
Closes exactly once, verifies independent size accounting, then invokes the optional format validator on the still-private path.
| [in,out] | opaque | Bound mdl_storage_vfs_t context. |
| [in] | total_bytes | Independently verified transfer length. |
| [in] | sha256 | Independently verified transfer digest. |
| k_ra8_ok | Closed artifact is ready for publication. |
| k_ra8_err_null_ptr | A required pointer was null. |
| k_ra8_err_invalid_state | Adapter is not actively writing. |
| k_ra8_err_invalid_size | Transfer accounting disagrees. |
| other | Close, metadata, or delegated validation failed. |
opaque and sha256 are non-null and digest spans its fixed extent. Definition at line 699 of file mdl_storage_vfs.c.
References mdl_storage_vfs_t::bytes_written, internal_close_writer(), internal_staged_file_check(), k_mdl_storage_vfs_ready, k_mdl_storage_vfs_writing, k_ra8_err_invalid_size, k_ra8_err_invalid_state, k_ra8_err_null_ptr, k_ra8_mdl_sha256_bytes, k_ra8_ok, mdl_storage_vfs_t::staging_path, mdl_storage_vfs_t::state, mdl_storage_vfs_t::validate, and mdl_storage_vfs_t::validate_ctx.
|
static |
Coordinator callback: append one all-or-error bounded chunk.
Delegates one bounded VFS write and advances accounting only on success.
| [in,out] | opaque | Bound mdl_storage_vfs_t context. |
| [in] | data | Source chunk. |
| [in] | len | Chunk byte count. |
| [out] | written | Receives either zero or the complete len. |
| k_ra8_ok | The full chunk was accepted and accounted. |
| k_ra8_err_null_ptr | A required pointer was null. |
| k_ra8_err_invalid_state | No private writer is active. |
| k_ra8_err_invalid_size | Total-byte accounting would overflow. |
| other | Underlying VFS write failed. |
opaque and written are non-null; data spans len bytes. written to len and advances bytes exactly once. written to zero and does not advance byte accounting. Definition at line 610 of file mdl_storage_vfs.c.
References mdl_storage_vfs_t::bytes_written, mdl_storage_vfs_t::file, k_mdl_storage_vfs_writing, k_ra8_err_invalid_size, k_ra8_err_invalid_state, k_ra8_err_null_ptr, k_ra8_ok, ra8_io_vfs_file_write(), and mdl_storage_vfs_t::state.
|
nodiscard |
Initialise one VFS storage adapter and bind its coordinator interface.
| [out] | storage | Caller-owned adapter context. |
| [in] | config | Staging-name policy and optional artifact validator. |
| [out] | out_iface | Bound media-download storage interface. |
| k_ra8_ok | Adapter initialised and interface bound. |
| k_ra8_err_null_ptr | A required pointer or stage_leaf is null. |
| k_ra8_err_invalid_arg | stage_leaf is not a simple path component. |
| k_ra8_err_invalid_size | stage_leaf exceeds the fixed capacity. |
Definition at line 837 of file mdl_storage_vfs.c.
References ra8_mdl_storage_iface::abort, ra8_mdl_storage_iface::begin, ra8_mdl_storage_iface::commit, ra8_mdl_storage_iface::ctx, internal_abort(), internal_begin(), internal_commit(), internal_copy(), internal_stage_leaf_check(), internal_validate(), internal_write(), k_ra8_err_null_ptr, k_ra8_ok, mdl_storage_vfs_config_t::stage_leaf, mdl_storage_vfs_t::stage_leaf, mdl_storage_vfs_config_t::validate, mdl_storage_vfs_t::validate, ra8_mdl_storage_iface::validate, mdl_storage_vfs_config_t::validate_ctx, mdl_storage_vfs_t::validate_ctx, and ra8_mdl_storage_iface::write.
Referenced by internal_bind_transfer().