ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_fs_fat_check_internal.h File Reference

Cross-TU state and helpers for the volume consistency check (fsck). More...

#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_fs.h"
#include "ra8_fs_check.h"
Include dependency graph for ra8_fs_fat_check_internal.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ra8_fs_check_ctx_t
 The state one ra8_fs_check run threads through its passes. More...

Enumerations

enum  ra8_fs_check_bound_t : uint16_t { k_ra8_fs_check_max_dirs = 128U }
 Static bounds that keep a scan of a corrupt volume terminating. More...

Functions

void priv_check_fault (ra8_fs_check_ctx_t *ctx, ra8_fs_check_fault_kind_t kind, uint32_t cluster, uint64_t lba, uint32_t entry_off)
 Record one consistency finding into the report.
bool priv_check_in_range (const ra8_fs_check_ctx_t *ctx, uint32_t cluster)
 True when cluster is a real data cluster of the volume under check.
bool priv_check_mark (ra8_fs_check_ctx_t *ctx, uint32_t cluster)
 Mark cluster visited in the scratch bitmap; report a prior visit.
bool priv_check_visit (ra8_fs_check_ctx_t *ctx, uint32_t cluster, ra8_fs_check_fault_kind_t oor_kind)
 Visit a cluster during a walk: mark it, and report a range or link fault.
void priv_check_zero_bitmap (ra8_fs_check_ctx_t *ctx)
 Zero the scratch visited-bitmap over its valid bit range.
ra8_err_t priv_check_fat (ra8_fs_check_ctx_t *ctx)
 Run the FAT12/16/32 consistency check into the context's report.
ra8_err_t ra8_fs_check_test_fat_scan_cluster_dir (ra8_fs_check_ctx_t *ctx, uint32_t first)
 Exercise the FAT cluster-directory walker from a host unit test.
void ra8_fs_check_test_fat_push_overflow (ra8_fs_check_ctx_t *ctx, uint32_t cluster, bool already_truncated)
 Exercise the FAT directory-worklist overflow guard from a host test.
void ra8_fs_check_test_exfat_mark_run (ra8_fs_check_ctx_t *ctx, uint32_t first, uint64_t nclus)
 Exercise the exFAT contiguous-run marker from a host unit test.
ra8_err_t ra8_fs_check_test_exfat_mark_fatchain (ra8_fs_check_ctx_t *ctx, uint32_t first)
 Exercise the exFAT fragmented-chain walker from a host unit test.
ra8_err_t ra8_fs_check_test_exfat_mark_dir_alloc (ra8_fs_check_ctx_t *ctx, uint32_t first)
 Exercise the exFAT FAT-chained directory allocation marker from a host test.
void ra8_fs_check_test_exfat_push_overflow (ra8_fs_check_ctx_t *ctx, uint32_t cluster, bool already_truncated)
 Exercise the exFAT directory-worklist overflow guard from a host test.
ra8_err_t priv_check_exfat (ra8_fs_check_ctx_t *ctx)
 Run the exFAT consistency check into the context's report.

Detailed Description

Cross-TU state and helpers for the volume consistency check (fsck).

ra8_fs_check is split across two translation units to stay inside the 1000-line source cap, along the same FAT / exFAT seam the rest of the adapter uses:

  • ra8_fs_fat_check.c – the shared scan context, the finding recorder, the visited-bitmap primitives, the FAT12/16/32 check, and the public ra8_fs_check entry.
  • ra8_fs_fat_exfat_check.c – the exFAT check (entry-set checksums, name hashes, and the allocation-bitmap diff).

This header carries only what those two files SHARE: the ra8_fs_check_ctx_t that threads the mount, the report and the scratch bitmap through the walk, and the recorder / bitmap primitives both use. It is included directly by those two translation units and by nothing else – it is not part of the ra8_fs_fat_internal.h umbrella, because no other unit needs the check's private vocabulary.

Since
0.1.0

Definition in file ra8_fs_fat_check_internal.h.

Enumeration Type Documentation

◆ ra8_fs_check_bound_t

enum ra8_fs_check_bound_t : uint16_t

Static bounds that keep a scan of a corrupt volume terminating.

A corrupt volume must not loop forever (NASA P10 Rule 2). Every directory-tree walk pushes subdirectories onto a fixed worklist whose depth is capped here; overflowing it is reported as k_ra8_fs_check_fault_scan_truncated rather than growing unbounded. The per-chain cluster walks are bounded separately by the volume's own count_of_clusters, and terminated early by the visited bitmap (a revisit is a cross-link, and it stops the walk).

Since
0.1.0
Enumerator
k_ra8_fs_check_max_dirs 

Directory worklist depth cap.

Definition at line 51 of file ra8_fs_fat_check_internal.h.

Function Documentation

◆ priv_check_exfat()

ra8_err_t priv_check_exfat ( ra8_fs_check_ctx_t * ctx)

Run the exFAT consistency check into the context's report.

The exFAT-side dispatch of ra8_fs_check: verifies each entry set's SetChecksum and NameHash, marks every referenced cluster (files, directories and the bitmap / up-case system runs), and diffs that against the allocation bitmap in both directions. Defined in ra8_fs_fat_exfat_check.c.

Parameters
[in,out]ctxThe scan context (ctx->m->type is exFAT).
Returns
Error code.
Return values
k_ra8_okThe scan completed; findings are in the report.
k_ra8_err_*Backend read failure mid-scan.
Precondition
ctx is non-NULL; ctx->m->type is exFAT.
The mount is in use and its geometry is populated.
Postcondition
On k_ra8_ok the report's counts and faults describe the volume.
No volume state is modified.
Note
Not thread-safe; the check holds the library lock.
Since
0.1.0

Definition at line 898 of file ra8_fs_fat_exfat_check.c.

References ra8_fs_check_ctx_t::bitmap, ra8_fs_check_report_t::entries_bad, internal_exchk_bitmap_pass(), internal_exchk_tree(), k_ra8_err_not_found, k_ra8_fs_check_fault_bad_dir_entry, k_ra8_ok, ra8_fs_check_ctx_t::m, priv_check_fault(), priv_check_zero_bitmap(), priv_cluster_to_lba(), priv_exfat_find_bitmap(), and ra8_fs_check_ctx_t::rep.

◆ priv_check_fat()

ra8_err_t priv_check_fat ( ra8_fs_check_ctx_t * ctx)

Run the FAT12/16/32 consistency check into the context's report.

The FAT-side dispatch of ra8_fs_check: classifies the FAT, walks the directory tree marking referenced clusters, diffs for lost clusters, and compares the FAT32 FSInfo free count. Defined in ra8_fs_fat_check.c.

Parameters
[in,out]ctxThe scan context (ctx->m->type is a FAT variant).
Returns
Error code.
Return values
k_ra8_okThe scan completed; findings are in the report.
k_ra8_err_*Backend read failure mid-scan.
Precondition
ctx is non-NULL; ctx->m->type is FAT12/16/32.
The mount is in use and its geometry is populated.
Postcondition
On k_ra8_ok the report's counts and faults describe the volume.
No volume state is modified.
Note
Not thread-safe; the check holds the library lock.
Since
0.1.0

Definition at line 764 of file ra8_fs_fat_check.c.

References ra8_fs_check_ctx_t::bitmap, internal_fat_classify(), internal_fat_diff(), internal_fat_fsinfo(), internal_fat_tree(), k_ra8_ok, and priv_check_zero_bitmap().

◆ priv_check_fault()

void priv_check_fault ( ra8_fs_check_ctx_t * ctx,
ra8_fs_check_fault_kind_t kind,
uint32_t cluster,
uint64_t lba,
uint32_t entry_off )

Record one consistency finding into the report.

Increments rep->faults_total and, on the FIRST finding, stamps rep->first_fault with kind and the locator. Later findings raise the total but leave the first fault untouched, so the report always names the earliest thing the scan tripped on – what fsck -n prints first. The per-category counters are the callers' responsibility; this owns only the total and the first-fault stamp.

Parameters
[in,out]ctxThe scan context.
[in]kindThe finding's category.
[in]clusterCluster the finding concerns (0 if n/a).
[in]lbaVolume-relative sector of the entry (0 if n/a).
[in]entry_offByte offset of the entry in that sector (0 if n/a).
Returns
Nothing.
Precondition
ctx and ctx->rep are non-NULL.
kind is not k_ra8_fs_check_fault_none.
Postcondition
rep->faults_total is one higher.
rep->first_fault names the earliest finding.
Note
Not thread-safe; the check holds the library lock.
Since
0.1.0

Definition at line 109 of file ra8_fs_fat_check.c.

References ra8_fs_check_fault_t::cluster, ra8_fs_check_fault_t::entry_off, ra8_fs_check_report_t::faults_total, ra8_fs_check_report_t::first_fault, ra8_fs_check_fault_t::kind, ra8_fs_check_fault_t::lba, and ra8_fs_check_ctx_t::rep.

Referenced by internal_exchk_diff_byte(), internal_exchk_mark_fatchain(), internal_exchk_mark_run(), internal_exchk_push(), internal_exchk_scan_dir_file_entry(), internal_exchk_scan_dir_terminal(), internal_exchk_set(), internal_exchk_set_clusters(), internal_exchk_verify_set(), internal_fat_classify_one(), internal_fat_diff(), internal_fat_entry(), internal_fat_fsinfo(), internal_fat_mark_chain(), internal_fat_push(), priv_check_exfat(), and priv_check_visit().

◆ priv_check_in_range()

bool priv_check_in_range ( const ra8_fs_check_ctx_t * ctx,
uint32_t cluster )

True when cluster is a real data cluster of the volume under check.

The addressable range is [2, 2 + clusters_total); anything else – the reserved 0 and 1, or a value past the last cluster – is not a cluster this volume has.

Parameters
[in]ctxThe scan context.
[in]clusterThe cluster number to test.
Returns
Whether cluster addresses a data cluster.
Return values
true2 <= cluster < 2 + clusters_total.
falseOut of range.
Precondition
ctx is non-NULL.
The report's clusters_total is populated.
Postcondition
No state modified.
Result depends only on the inputs.
Note
Pure; trivially thread-safe.
Since
0.1.0

Definition at line 125 of file ra8_fs_fat_check.c.

References ra8_fs_check_report_t::clusters_total, k_cluster_first_data, and ra8_fs_check_ctx_t::rep.

Referenced by internal_exchk_mark_fatchain(), internal_exchk_mark_run(), internal_exchk_set_clusters(), internal_fat_classify_one(), internal_fat_entry(), internal_fat_mark_chain(), and priv_check_visit().

◆ priv_check_mark()

bool priv_check_mark ( ra8_fs_check_ctx_t * ctx,
uint32_t cluster )

Mark cluster visited in the scratch bitmap; report a prior visit.

Test-and-set of the bit for cluster. A bit that was ALREADY set means a second chain reached this cluster – a cross-link, or a loop – so the caller stops the walk it is on. The bit index is cluster - 2, matching the exFAT allocation bitmap's own layout so the two can be diffed directly.

Parameters
[in,out]ctxThe scan context (its bitmap is written).
[in]clusterThe cluster to mark; must be in range.
Returns
Whether the cluster had already been visited.
Return values
trueThe bit was already set (cross-link / loop).
falseThe bit was clear and is now set (first visit).
Precondition
ctx and ctx->bitmap are non-NULL.
priv_check_in_range holds for cluster.
Postcondition
The bit for cluster reads as 1.
No other bit is changed.
Note
Not thread-safe; the check holds the library lock.
Since
0.1.0

Definition at line 134 of file ra8_fs_fat_check.c.

References ra8_fs_check_ctx_t::bitmap, k_check_bit_mask, k_check_byte_shift, and k_cluster_first_data.

Referenced by priv_check_visit().

◆ priv_check_visit()

bool priv_check_visit ( ra8_fs_check_ctx_t * ctx,
uint32_t cluster,
ra8_fs_check_fault_kind_t oor_kind )

Visit a cluster during a walk: mark it, and report a range or link fault.

The one place the walkers share – FAT chains, exFAT runs, and the directory allocations of both – so the range and cross-link handling lives once. It marks cluster and returns whether the walk must stop: a cluster out of range records oor_kind (bumping entries_bad when that kind is k_ra8_fs_check_fault_bad_dir_entry), and a cluster already visited records a cross-link.

Parameters
[in,out]ctxThe scan context (its bitmap and report are written).
[in]clusterThe cluster to visit.
[in]oor_kindThe fault kind to record when cluster is out of range.
Returns
Whether the caller must stop walking.
Return values
trueA fault was recorded (out of range, or a cross-link).
falsecluster was in range and is now freshly marked.
Precondition
ctx and its bitmap are non-NULL.
oor_kind is a range-style fault kind.
Postcondition
On false the bit for cluster reads as 1.
On true the report carries the finding.
Note
Not thread-safe; the check holds the library lock.
Since
0.1.0

Definition at line 147 of file ra8_fs_fat_check.c.

References ra8_fs_check_report_t::chains_crosslinked, ra8_fs_check_report_t::entries_bad, k_ra8_fs_check_fault_bad_dir_entry, k_ra8_fs_check_fault_crosslink, priv_check_fault(), priv_check_in_range(), priv_check_mark(), and ra8_fs_check_ctx_t::rep.

Referenced by internal_exchk_mark_dir_alloc(), internal_exchk_mark_fatchain(), internal_exchk_mark_run(), internal_fat_mark_chain(), and internal_fat_scan_cluster_dir().

◆ priv_check_zero_bitmap()

void priv_check_zero_bitmap ( ra8_fs_check_ctx_t * ctx)

Zero the scratch visited-bitmap over its valid bit range.

Clears (bitmap_bits + 7) / 8 bytes so a stale caller buffer cannot make a fresh scan see clusters as already visited. Called once, before the reference passes.

Parameters
[in,out]ctxThe scan context (its bitmap is cleared).
Returns
Nothing.
Precondition
ctx and ctx->bitmap are non-NULL.
ctx->bitmap is at least (bitmap_bits + 7) / 8 bytes.
Postcondition
Every valid bit reads as 0.
No state outside the bitmap is touched.
Note
Not thread-safe; the check holds the library lock.
Since
0.1.0

Definition at line 165 of file ra8_fs_fat_check.c.

References ra8_fs_check_ctx_t::bitmap, ra8_fs_check_ctx_t::bitmap_bits, k_check_bit_mask, and k_check_byte_shift.

Referenced by priv_check_exfat(), and priv_check_fat().

◆ ra8_fs_check_test_exfat_mark_dir_alloc()

ra8_err_t ra8_fs_check_test_exfat_mark_dir_alloc ( ra8_fs_check_ctx_t * ctx,
uint32_t first )

Exercise the exFAT FAT-chained directory allocation marker from a host test.

Builds a synthetic FAT-chained directory descriptor around first and marks its allocation without scanning directory entries. This isolates the allocation walk's exact hop ceiling from the entry scanner. Production code must call ra8_fs_check().

Parameters
[in,out]ctxSynthetic scan context whose mount supplies the FAT.
[in]firstFirst cluster of the synthetic directory chain.
Returns
Error code.
Return values
k_ra8_okThe allocation was walked; findings are in the report.
k_ra8_err_*Backend read failure.
Precondition
ctx, its report, bitmap and mount are non-NULL.
ctx->rep->clusters_total is non-zero and first is in range.
Postcondition
Every traversed cluster is marked, up to the first finding.
A non-terminal successor after the final hop records a cross-link or bad-directory fault.
Note
Test-only and not thread-safe; no filesystem lock is acquired.
MC/DC:
Host vectors independently provide EOC and an in-range cycle after the exact hop bound.
Since
0.1.0

Definition at line 279 of file ra8_fs_fat_exfat_check.c.

References internal_exchk_mark_dir_alloc().

◆ ra8_fs_check_test_exfat_mark_fatchain()

ra8_err_t ra8_fs_check_test_exfat_mark_fatchain ( ra8_fs_check_ctx_t * ctx,
uint32_t first )

Exercise the exFAT fragmented-chain walker from a host unit test.

Exposes the otherwise file-local bounded walker so the exact clusters_total boundary can be driven without constructing an impossible public volume in which one file owns every cluster also needed by the root directory and allocation bitmap. Production code must call ra8_fs_check(), never this test seam.

Parameters
[in,out]ctxSynthetic scan context whose mount supplies the FAT.
[in]firstFirst cluster of the synthetic fragmented chain.
Returns
Error code.
Return values
k_ra8_okThe chain was walked; consistency findings are in the report.
k_ra8_err_*Backend read failure.
Precondition
ctx, its report, bitmap and mount are non-NULL.
ctx->rep->clusters_total is non-zero and first is in range.
Postcondition
Every traversed cluster is marked, up to the first consistency finding.
A non-terminal successor after the final bounded hop records a specific cross-link or bad-chain finding.
Note
Test-only and not thread-safe; no filesystem lock is acquired.
MC/DC:
The host vectors independently select an end-of-chain marker, an in-range cycle, and an out-of-range tail after the exact hop bound.
Since
0.1.0

Definition at line 225 of file ra8_fs_fat_exfat_check.c.

References internal_exchk_mark_fatchain().

◆ ra8_fs_check_test_exfat_mark_run()

void ra8_fs_check_test_exfat_mark_run ( ra8_fs_check_ctx_t * ctx,
uint32_t first,
uint64_t nclus )

Exercise the exFAT contiguous-run marker from a host unit test.

Marks a synthetic NoFatChain run directly so an exact full-volume run and a one-cluster overrun from cluster two can be distinguished. That geometry is impossible through a public exFAT file because the filesystem's system files also own data clusters. Production code must call ra8_fs_check().

Parameters
[in,out]ctxSynthetic scan context and caller-owned bitmap.
[in]firstFirst cluster of the contiguous run.
[in]nclusDeclared run length in clusters.
Returns
Nothing.
Precondition
ctx, its report and bitmap are non-NULL.
ctx->rep->clusters_total and nclus are non-zero.
Postcondition
The in-range prefix is marked.
An overrun records k_ra8_fs_check_fault_bad_dir_entry.
Note
Test-only and not thread-safe; no filesystem lock is acquired.
MC/DC:
Host vectors independently select an exact in-range run and a one-cluster overrun.
Since
0.1.0

Definition at line 168 of file ra8_fs_fat_exfat_check.c.

References internal_exchk_mark_run().

◆ ra8_fs_check_test_exfat_push_overflow()

void ra8_fs_check_test_exfat_push_overflow ( ra8_fs_check_ctx_t * ctx,
uint32_t cluster,
bool already_truncated )

Exercise the exFAT directory-worklist overflow guard from a host test.

Builds an already-full private worklist and attempts one push. This drives the bounded-stack guard without constructing 129 simultaneous directories in a RAM volume. Production code must call ra8_fs_check(), never this test seam.

Parameters
[in,out]ctxSynthetic context whose report receives a fault.
[in]clusterCluster recorded for the dropped directory.
[in]already_truncatedWhether a prior overflow was already recorded.
Returns
Nothing.
Precondition
ctx is non-NULL.
ctx owns a non-NULL, writable report.
Postcondition
A first overflow records one scan-truncated fault.
A repeated overflow records no additional fault.
Note
Test-only and not thread-safe; no filesystem lock is acquired.
Since
0.1.0

Definition at line 449 of file ra8_fs_fat_exfat_check.c.

References internal_exchk_push(), and k_ra8_fs_check_max_dirs.

◆ ra8_fs_check_test_fat_push_overflow()

void ra8_fs_check_test_fat_push_overflow ( ra8_fs_check_ctx_t * ctx,
uint32_t cluster,
bool already_truncated )

Exercise the FAT directory-worklist overflow guard from a host test.

Builds an already-full private worklist and attempts one push. This drives the bounded-stack guard without constructing 129 simultaneous directories in a RAM volume. Production code must call ra8_fs_check(), never this test seam.

Parameters
[in,out]ctxSynthetic context whose report receives a fault.
[in]clusterCluster recorded for the dropped directory.
[in]already_truncatedWhether a prior overflow was already recorded.
Returns
Nothing.
Precondition
ctx is non-NULL.
ctx owns a non-NULL, writable report.
Postcondition
A first overflow records one scan-truncated fault.
A repeated overflow records no additional fault.
Note
Test-only and not thread-safe; no filesystem lock is acquired.
Since
0.1.0

Definition at line 380 of file ra8_fs_fat_check.c.

References internal_fat_push(), and k_ra8_fs_check_max_dirs.

◆ ra8_fs_check_test_fat_scan_cluster_dir()

ra8_err_t ra8_fs_check_test_fat_scan_cluster_dir ( ra8_fs_check_ctx_t * ctx,
uint32_t first )

Exercise the FAT cluster-directory walker from a host unit test.

Creates an empty private directory worklist and walks the synthetic FAT chain beginning at first. This seam lets the exact clusters_total boundary be tested without requiring the mounted volume's real root directory to consume every data cluster. Production code must call ra8_fs_check().

Parameters
[in,out]ctxSynthetic scan context whose mount supplies the FAT and directory data.
[in]firstFirst cluster of the synthetic directory chain.
Returns
Error code.
Return values
k_ra8_okThe directory chain was walked; findings are in the report.
k_ra8_err_*Backend read failure.
Precondition
ctx, its report, bitmap and mount are non-NULL.
ctx->rep->clusters_total is non-zero and first is in range.
Postcondition
Every traversed directory cluster is marked, up to the first finding.
A non-terminal successor after the final hop records a cross-link or bad-directory fault.
Note
Test-only and not thread-safe; no filesystem lock is acquired.
MC/DC:
Host vectors independently provide EOC and an in-range cycle after the exact hop bound.
Since
0.1.0

Definition at line 615 of file ra8_fs_fat_check.c.

References internal_fat_scan_cluster_dir().