|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Portable downloader storage binding and validated atomic copy. More...
#include "mdl_storage.h"#include <stdint.h>#include <string.h>#include "mdl_hash.h"#include "ra8_attributes.h"Go to the source code of this file.
Data Structures | |
| struct | internal_storage_span_t |
| One overflow-checked half-open caller-storage interval. More... | |
| struct | staged_identity_t |
| Expected staged identity retained during validation. More... | |
Typedefs | |
| typedef struct internal_storage_span_t | internal_storage_span_t |
| One overflow-checked half-open caller-storage interval. | |
Enumerations | |
| enum | mdl_storage_limits_t : uint32_t { k_storage_io_calls = 2000001U , k_storage_span_count = 4U } |
| Bounded I/O progress limits for a complete copy. More... | |
Functions | |
| static ra8_err_t | internal_make_span (const void *pointer, uint32_t bytes, internal_storage_span_t *out) |
| Convert one non-empty caller region into an address interval. | |
| static bool | internal_overlap (const internal_storage_span_t *left, const internal_storage_span_t *right) |
| Return whether two validated half-open intervals share a byte. | |
| static ra8_err_t | internal_validate_spans (mdl_storage_t *storage, void *file_workspace, uint32_t file_workspace_bytes, void *transaction_workspace, uint32_t transaction_workspace_bytes, uint8_t *io_buffer, uint32_t io_buffer_bytes) |
| Validate that output and operational workspaces are pairwise disjoint. | |
| static bool | internal_aligned (const void *pointer, uint8_t alignment) |
| Return whether one pointer satisfies a backend alignment contract. | |
| ra8_err_t | mdl_storage_init (mdl_storage_t *storage, const fw_fs_t *fs, void *file_workspace, uint32_t file_workspace_bytes, void *transaction_workspace, uint32_t transaction_workspace_bytes, uint8_t *io_buffer, uint32_t io_buffer_bytes) |
| Validate and retain one filesystem plus caller-owned workspaces. | |
| static ra8_err_t | internal_abort (fw_fs_transaction_t *transaction, ra8_err_t primary) |
| Abort an active transaction and preserve cleanup failure visibility. | |
| static ra8_err_t | internal_write_all (fw_fs_transaction_t *transaction, const uint8_t *source, uint32_t length, uint32_t *calls) |
| Write all of one buffer while rejecting zero-progress success. | |
| static ra8_err_t | internal_validate_stage (void *ctx, fw_fs_file_t *staged) |
| Validate staged size and identity through its generic read handle. | |
| static ra8_err_t | internal_policy (const mdl_storage_t *storage, const char *destination, fw_fs_transaction_policy_t *out) |
| Select create-new or truthful atomic replacement policy. | |
| static ra8_err_t | internal_source_size (const mdl_storage_t *storage, const char *source, uint64_t *size) |
| Resolve and validate one regular bounded source file. | |
| static ra8_err_t | internal_begin_copy (mdl_storage_t *storage, const char *source, const char *destination, fw_fs_file_t *source_file, fw_fs_transaction_t *transaction, uint64_t *size) |
| Open the copy source and begin its publication transaction. | |
| static ra8_err_t | internal_copy_payload (mdl_storage_t *storage, fw_fs_file_t *source, fw_fs_transaction_t *transaction, uint64_t size, uint64_t *hash) |
| Copy and hash one exact source payload into a transaction. | |
| ra8_err_t | mdl_storage_copy_atomic (mdl_storage_t *storage, const char *source, const char *destination) |
| Copy a regular file through a validated atomic transaction. | |
| static ra8_err_t | internal_txn_begin (mdl_storage_txn_t *writer, mdl_storage_t *storage, const char *destination, fw_fs_transaction_policy_t policy) |
| Begin a streaming writer with one explicit publication policy. | |
| ra8_err_t | mdl_storage_txn_begin (mdl_storage_txn_t *writer, mdl_storage_t *storage, const char *destination) |
| Begin one streamed create or truthful atomic replacement. | |
| ra8_err_t | mdl_storage_txn_begin_new (mdl_storage_txn_t *writer, mdl_storage_t *storage, const char *destination) |
| Begin one streamed create-new publication without replacement. | |
| ra8_err_t | mdl_storage_txn_write (mdl_storage_txn_t *writer, const uint8_t *bytes, uint32_t length) |
| Append one complete caller chunk, tolerating bounded short writes. | |
| ra8_err_t | mdl_storage_txn_abort (mdl_storage_txn_t *writer) |
| Abort and clear one streamed transaction. | |
| ra8_err_t | mdl_storage_txn_commit (mdl_storage_txn_t *writer) |
| Independently validate and publish a completed streamed transaction. | |
Portable downloader storage binding and validated atomic copy.
Implements the downloader's reusable filesystem dependency bundle and the first transaction-backed publication operation. All filesystem effects route through fw_if_fs; workspaces and buffers are bounded and caller-owned.
Definition in file mdl_storage.c.
| typedef struct internal_storage_span_t internal_storage_span_t |
One overflow-checked half-open caller-storage interval.
| enum mdl_storage_limits_t : uint32_t |
Bounded I/O progress limits for a complete copy.
| Enumerator | |
|---|---|
| k_storage_io_calls | Short-I/O and EOF call ceiling. |
| k_storage_span_count | Output plus workspace span count. |
Definition at line 25 of file mdl_storage.c.
|
static |
Abort an active transaction and preserve cleanup failure visibility.
A successful abort returns the original operation status. If abort itself fails, that cleanup error takes precedence because a private stage may remain and the caller must not mistake the failure for a fully cleaned path.
| [in,out] | transaction | Transaction to abort when still active. |
| [in] | primary | Status from the operation that triggered cleanup. |
| k_ra8_ok | The transaction was already inactive or cleanly aborted and no earlier operation failed. |
| other | The primary operation or transaction abort failed. |
transaction is non-null and initialized or all-zero. primary is a canonical ra8_err_t status. Definition at line 249 of file mdl_storage.c.
References fw_fs_transaction_t::active, fw_fs_transaction_abort(), k_ra8_ok, and RA8_INTERNAL.
Referenced by mdl_storage_copy_atomic().
|
static |
Return whether one pointer satisfies a backend alignment contract.
Applies the standard power-of-two mask after fw_fs_get_caps has validated the advertised nonzero alignment.
| [in] | pointer | Candidate workspace address. |
| [in] | alignment | Required power-of-two byte alignment. |
| true | The pointer is non-null and correctly aligned. |
| false | The pointer is null, the alignment is zero, or the address is misaligned. |
alignment originated from a successfully bound filesystem facade. pointer is required. Definition at line 168 of file mdl_storage.c.
References RA8_INTERNAL.
Referenced by mdl_storage_init().
|
static |
Open the copy source and begin its publication transaction.
Selects the truthful destination policy before opening either side.
| [in] | storage | Initialized storage binding. |
| [in] | source | Canonical source path. |
| [in] | destination | Canonical destination path. |
| [out] | source_file | Receives the open source stream. |
| [out] | transaction | Receives the open transaction. |
| [out] | size | Receives the validated source length. |
| k_ra8_ok | Both handles are open. |
| other | Filesystem validation or open failure propagated. |
Definition at line 444 of file mdl_storage.c.
References mdl_storage_t::file_workspace, mdl_storage_t::file_workspace_bytes, mdl_storage_t::fs, fw_fs_close(), fw_fs_open(), fw_fs_transaction_begin(), internal_policy(), internal_source_size(), k_fw_fs_open_read, k_fw_fs_txn_create_new, k_ra8_ok, RA8_INTERNAL, fw_fs_t::streams, mdl_storage_t::transaction_workspace, mdl_storage_t::transaction_workspace_bytes, and fw_fs_t::transactions.
Referenced by mdl_storage_copy_atomic().
|
static |
Copy and hash one exact source payload into a transaction.
Enforces bounded I/O call counts and rejects early EOF or trailing data.
| [in] | storage | Initialized storage binding and I/O buffer. |
| [in,out] | source | Open source file. |
| [in,out] | transaction | Open destination transaction. |
| [in] | size | Exact source byte length. |
| [out] | hash | Receives the payload hash on success. |
| k_ra8_ok | Exactly size bytes were copied and EOF followed. |
| k_ra8_err_invalid_size | The bounded call budget was exhausted. |
| other | A read/write or stream-integrity failure propagated. |
hash. Definition at line 499 of file mdl_storage.c.
References fw_fs_read(), internal_write_all(), mdl_storage_t::io_buffer, mdl_storage_t::io_buffer_bytes, k_mdl_fnv_offset, k_ra8_err_invalid_size, k_ra8_fail, k_ra8_ok, k_storage_io_calls, mdl_hash_bytes_seed(), and RA8_INTERNAL.
Referenced by mdl_storage_copy_atomic().
|
static |
Convert one non-empty caller region into an address interval.
Uses integer endpoints solely to reject wrapping and overlapping workspace contracts before any caller byte is changed.
| [in] | pointer | Region start. |
| [in] | bytes | Nonzero region extent. |
| [out] | out | Receives the half-open interval. |
| k_ra8_ok | The interval is non-wrapping. |
| k_ra8_err_invalid_arg | A pointer or extent is zero. |
| k_ra8_err_invalid_size | The one-past-last address would wrap. |
out is non-null and writable. pointer is either null or denotes the claimed caller allocation. out without dereferencing pointer. Definition at line 63 of file mdl_storage.c.
References k_ra8_err_invalid_arg, k_ra8_err_invalid_size, and k_ra8_ok.
Referenced by internal_validate_spans().
|
static |
Return whether two validated half-open intervals share a byte.
Strict endpoint comparisons treat adjacent workspaces as disjoint.
| [in] | left | First interval. |
| [in] | right | Second interval. |
| true | At least one byte is shared. |
| false | The intervals are disjoint. |
Definition at line 91 of file mdl_storage.c.
References internal_storage_span_t::begin, internal_storage_span_t::end, and RA8_INTERNAL.
Referenced by internal_validate_spans().
|
static |
Select create-new or truthful atomic replacement policy.
Stats the destination without mutation. Missing paths select create-new; regular files select atomic replacement and let the transaction facade reject a backend that cannot provide that guarantee.
| [in] | storage | Initialized storage binding. |
| [in] | destination | Canonical destination path. |
| [out] | out | Receives the selected transaction policy. |
| k_ra8_ok | One policy was published. |
| k_ra8_err_invalid_arg | An existing destination is not a file. |
| other | A namespace stat failure propagated. |
storage and its filesystem are initialized. destination is canonical and out is writable. out. Definition at line 366 of file mdl_storage.c.
References fw_fs_stat_t::exists, mdl_storage_t::fs, fw_fs_stat(), k_fw_fs_node_file, k_fw_fs_txn_create_new, k_fw_fs_txn_replace_atomic, k_ra8_err_invalid_arg, k_ra8_ok, fw_fs_t::names, RA8_INTERNAL, and fw_fs_stat_t::type.
Referenced by internal_begin_copy(), and mdl_storage_txn_begin().
|
static |
Resolve and validate one regular bounded source file.
Rejects missing, non-file, and oversized namespace entries.
| [in] | storage | Initialized storage binding. |
| [in] | source | Canonical source path. |
| [out] | size | Receives the validated byte length. |
| k_ra8_ok | Source is a bounded regular file. |
| k_ra8_err_not_found | Source does not exist. |
| k_ra8_err_invalid_arg | Source is not a file. |
| k_ra8_err_invalid_size | Source exceeds the supported hash bound. |
size. Definition at line 405 of file mdl_storage.c.
References fw_fs_stat_t::exists, mdl_storage_t::fs, fw_fs_stat(), k_fw_fs_node_file, k_mdl_hash_max_file_bytes, k_ra8_err_invalid_arg, k_ra8_err_invalid_size, k_ra8_err_not_found, k_ra8_ok, fw_fs_t::names, fw_fs_stat_t::size_bytes, and fw_fs_stat_t::type.
Referenced by internal_begin_copy().
|
static |
Begin a streaming writer with one explicit publication policy.
| [out] | writer | Inactive caller-owned writer. |
| [in,out] | storage | Exclusive initialized storage binding. |
| [in] | destination | Canonical destination path. |
| [in] | policy | Validated create-new or atomic-replace policy. |
writer is inactive. Initializes a caller-owned writer with the selected publication policy. No storage mutation follows a failed validation or begin operation.
| k_ra8_ok | The operation completed successfully. |
| other | The originating validation, storage, stream, or network error. |
Definition at line 605 of file mdl_storage.c.
References fw_fs_transaction_t::active, mdl_storage_t::fs, fw_fs_transaction_begin(), k_fw_fs_txn_create_new, k_fw_fs_txn_replace_atomic, k_mdl_fnv_offset, k_ra8_err_invalid_arg, k_ra8_ok, RA8_INTERNAL, mdl_storage_txn_t::transaction, mdl_storage_t::transaction_workspace, mdl_storage_t::transaction_workspace_bytes, and fw_fs_t::transactions.
Referenced by mdl_storage_txn_begin(), and mdl_storage_txn_begin_new().
|
static |
Validate that output and operational workspaces are pairwise disjoint.
Builds four guarded spans and performs a fixed pairwise comparison; source-file and transaction state must coexist during atomic copy.
| [in] | storage | Output object storage. |
| [in] | file_workspace | File-backend workspace. |
| [in] | file_workspace_bytes | File-workspace extent. |
| [in] | transaction_workspace | Transaction-backend workspace. |
| [in] | transaction_workspace_bytes | Transaction-workspace extent. |
| [in] | io_buffer | Streaming I/O buffer. |
| [in] | io_buffer_bytes | I/O-buffer extent. |
| k_ra8_ok | All four intervals are valid and disjoint. |
| k_ra8_err_invalid_arg | A region is empty or overlaps another. |
| k_ra8_err_invalid_size | An interval endpoint would wrap. |
Definition at line 119 of file mdl_storage.c.
References internal_make_span(), internal_overlap(), k_ra8_err_invalid_arg, k_ra8_ok, k_storage_span_count, and RA8_INTERNAL.
Referenced by mdl_storage_init().
|
static |
Validate staged size and identity through its generic read handle.
Independently reads the complete stage using the caller's shared scratch, then compares exact extent and FNV identity before commit.
| [in] | ctx | Read-only staged_identity_t expectation. |
| [in,out] | staged | Validation handle positioned at byte zero. |
| k_ra8_ok | Size and hash both match. |
| k_ra8_err_invalid_arg | A required pointer is null. |
| k_ra8_err_invalid_size | The staged extent differs. |
| k_ra8_err_protocol_error | The staged hash differs. |
| other | A file query/read failure propagated. |
ctx describes live caller-owned scratch for the complete callback. staged is open for validation and exclusively owned by the facade. Definition at line 324 of file mdl_storage.c.
References staged_identity_t::buffer, staged_identity_t::buffer_bytes, fw_fs_file_size(), staged_identity_t::hash, k_ra8_err_invalid_arg, k_ra8_err_invalid_size, k_ra8_err_protocol_error, k_ra8_ok, mdl_hash_stream(), RA8_INTERNAL, and staged_identity_t::size_bytes.
|
static |
Write all of one buffer while rejecting zero-progress success.
Repeats bounded transaction writes until every byte is accepted, making short writes visible and enforcing the module-wide call ceiling.
| [in,out] | transaction | Active destination transaction. |
| [in] | source | Readable source bytes. |
| [in] | length | Exact byte count to publish. |
| [in,out] | calls | Shared write-call tally. |
| k_ra8_ok | Exactly length bytes were consumed. |
| k_ra8_err_invalid_state | A successful backend write made no progress. |
| k_ra8_err_invalid_size | The call ceiling was exhausted. |
| other | A transaction write failure propagated. |
transaction is active and exclusively owned. source covers length readable bytes and calls is writable. length bytes. calls exactly once. Definition at line 280 of file mdl_storage.c.
References fw_fs_transaction_write(), k_ra8_err_invalid_size, k_ra8_err_invalid_state, k_ra8_ok, k_storage_io_calls, and RA8_INTERNAL.
Referenced by internal_copy_payload().
|
nodiscard |
Copy a regular file through a validated atomic transaction.
The source extent is snapshotted, streamed into a private sibling, hashed while read, then independently size/hash validated through the transaction's read-only staged handle before commit. An absent destination uses create-new publication. An existing regular destination requires the backend's truthful atomic-replace capability; a VFS/FAT binding therefore returns k_ra8_err_not_supported without changing the destination.
| [in,out] | storage | Initialized filesystem binding and workspaces. |
| [in] | source | Canonical portable source path. |
| [in] | destination | Canonical portable destination path. |
| k_ra8_ok | The validated stage was published atomically. |
| k_ra8_err_invalid_arg | A binding/path/type contract is invalid. |
| k_ra8_err_not_found | The source does not exist. |
| k_ra8_err_not_supported | Existing-file replacement is not atomic on the selected backend. |
| k_ra8_err_invalid_size | The source/scratch/call bound was exceeded. |
| k_ra8_err_protocol_error | The independently read stage hash differed. |
| other | A namespace, stream, transaction, or cleanup error propagated. |
storage was initialized successfully and is exclusively owned. destination contains exactly the snapshotted source. Definition at line 543 of file mdl_storage.c.
References mdl_storage_t::fs, fw_fs_close(), fw_fs_transaction_commit(), fw_fs_transaction_validate(), internal_abort(), internal_begin_copy(), internal_copy_payload(), internal_validate_stage(), mdl_storage_t::io_buffer, mdl_storage_t::io_buffer_bytes, k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_ok, and strcmp().
Referenced by internal_mdl_fetch_copy_file().
|
nodiscard |
Validate and retain one filesystem plus caller-owned workspaces.
Requires namespace, stream, and transaction capabilities, verifies the backend-advertised workspace extents and alignments, then publishes one non-reentrant dependency bundle. No backend operation or allocation occurs.
| [out] | storage | Downloader binding to initialize. |
| [in] | fs | Complete filesystem selected by the composition root. |
| [in,out] | file_workspace | Workspace used by one open source file. |
| [in] | file_workspace_bytes | Extent of file_workspace. |
| [in,out] | transaction_workspace | Workspace used by one staged publish. |
| [in] | transaction_workspace_bytes | Extent of transaction_workspace. |
| [out] | io_buffer | Caller-owned streaming scratch. |
| [in] | io_buffer_bytes | Nonzero extent of io_buffer. |
storage ready for use. | k_ra8_ok | The complete binding was published. |
| k_ra8_err_invalid_arg | A pointer, extent, or alignment is invalid. |
| k_ra8_err_not_supported | A required filesystem facade is absent. |
| k_ra8_err_no_mem | A caller workspace is smaller than its backend cap. |
| other | A capability query failure propagated from fs. |
storage is non-null and writable for one complete object. storage or each other. storage and every caller workspace retain their entry values. Definition at line 176 of file mdl_storage.c.
References fw_fs_caps_t::file_workspace_align, fw_fs_caps_t::file_workspace_bytes, fw_fs_caps_t::flags, fw_fs_get_caps(), internal_aligned(), internal_validate_spans(), k_fw_fs_cap_namespace, k_fw_fs_cap_stream, k_fw_fs_cap_transactions, k_ra8_err_invalid_arg, k_ra8_err_no_mem, k_ra8_err_not_supported, k_ra8_ok, fw_fs_caps_t::transaction_workspace_align, and fw_fs_caps_t::transaction_workspace_bytes.
Referenced by internal_storage_init().
|
nodiscard |
Abort and clear one streamed transaction.
| [in,out] | writer | Writer to abort; an inactive writer is accepted. |
| k_ra8_ok | No private stage remains and writer is zeroed. |
| other | Backend abort failure; writer state remains for diagnosis. |
writer is non-NULL and exclusively owned. Definition at line 683 of file mdl_storage.c.
References fw_fs_transaction_t::active, fw_fs_transaction_abort(), k_ra8_err_invalid_arg, k_ra8_ok, and mdl_storage_txn_t::transaction.
Referenced by internal_body_reset(), mdl_storage_txn_commit(), priv_mdl_app_storage_publish_site(), priv_mdl_cache_publish_body(), priv_mdl_cache_save(), priv_mdl_export_output_abort(), and priv_mdl_fetch_body_abort().
|
nodiscard |
Begin one streamed create or truthful atomic replacement.
| [out] | writer | Caller-owned writer state to initialize. |
| [in,out] | storage | Initialized exclusive storage binding. |
| [in] | destination | Canonical destination path. |
| k_ra8_ok | A private empty stage is active. |
| k_ra8_err_invalid_arg | A pointer/path/type contract is invalid. |
| k_ra8_err_not_supported | Existing replacement is not atomic. |
| other | Namespace or transaction-begin failure propagated. |
writer is inactive and storage is exclusively owned. destination is NUL-terminated and confined by the bound filesystem. writer inactive. Definition at line 634 of file mdl_storage.c.
References fw_fs_transaction_t::active, mdl_storage_t::fs, internal_policy(), internal_txn_begin(), k_fw_fs_txn_create_new, k_ra8_err_invalid_arg, k_ra8_ok, and mdl_storage_txn_t::transaction.
Referenced by internal_body_begin(), priv_mdl_cache_publish_body(), priv_mdl_cache_save(), and priv_mdl_export_output_begin().
|
nodiscard |
Begin one streamed create-new publication without replacement.
Uses the same caller-owned transaction workspace and running identity as mdl_storage_txn_begin, but fixes the backend policy to k_fw_fs_txn_create_new. An existing destination is therefore refused by the transaction contract and remains byte-for-byte unchanged on every return path.
| [out] | writer | Caller-owned writer state to initialize. |
| [in,out] | storage | Initialized exclusive storage binding. |
| [in] | destination | Canonical absent destination path. |
| k_ra8_ok | A private empty create-new stage is active. |
| k_ra8_err_exists | The destination already exists. |
| k_ra8_err_invalid_arg | A pointer/path/lifecycle contract is invalid. |
| other | Transaction-begin failure propagated from the backend. |
writer is inactive and storage is exclusively owned. destination is NUL-terminated and confined by the bound filesystem. writer inactive. destination. Definition at line 645 of file mdl_storage.c.
References internal_txn_begin(), and k_fw_fs_txn_create_new.
Referenced by priv_mdl_app_storage_publish_site(), and priv_mdl_export_output_begin_new().
|
nodiscard |
Independently validate and publish a completed streamed transaction.
| [in,out] | writer | Active streamed transaction. |
| k_ra8_ok | Exact size/hash were independently verified and published. |
| k_ra8_err_protocol_error | The staged identity differed. |
| other | Validation, commit, or abort failure propagated. |
writer owns one active transaction and initialized storage binding. writer. Definition at line 698 of file mdl_storage.c.
References fw_fs_transaction_t::active, fw_fs_transaction_commit(), fw_fs_transaction_validate(), mdl_storage_txn_t::hash, internal_validate_stage(), mdl_storage_t::io_buffer, mdl_storage_t::io_buffer_bytes, k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_ok, mdl_storage_txn_abort(), mdl_storage_txn_t::size_bytes, mdl_storage_txn_t::storage, and mdl_storage_txn_t::transaction.
Referenced by priv_mdl_app_storage_publish_site(), priv_mdl_cache_publish_body(), priv_mdl_cache_save(), and priv_mdl_fetch_body_commit().
|
nodiscard |
Append one complete caller chunk, tolerating bounded short writes.
| [in,out] | writer | Active streamed transaction. |
| [in] | bytes | Readable source bytes. |
| [in] | length | Source extent. |
| k_ra8_ok | Every byte was staged and folded into the identity. |
| k_ra8_err_invalid_state | The writer is inactive or made no progress. |
| k_ra8_err_invalid_size | Size or write-call bounds were exceeded. |
| other | Backend transaction-write failure propagated. |
writer owns one active stage and bytes covers length bytes. length. Definition at line 652 of file mdl_storage.c.
References fw_fs_transaction_t::active, fw_fs_transaction_write(), mdl_storage_txn_t::hash, k_mdl_hash_max_file_bytes, k_ra8_err_invalid_arg, k_ra8_err_invalid_size, k_ra8_err_invalid_state, k_ra8_ok, k_storage_io_calls, mdl_hash_bytes_seed(), mdl_storage_txn_t::size_bytes, mdl_storage_txn_t::storage, mdl_storage_txn_t::transaction, and mdl_storage_txn_t::write_calls.
Referenced by internal_body_flush_prefix(), internal_body_write(), internal_cache_write_records(), priv_mdl_app_storage_publish_site(), priv_mdl_cache_publish_body(), and priv_mdl_cache_save().