|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Read-only consistency check (fsck): shared scaffolding + FAT12/16/32. More...
#include <stddef.h>#include <stdint.h>#include "ra8_attributes.h"#include "ra8_fs.h"#include "ra8_fs_check.h"#include "ra8_fs_fat_check_internal.h"#include "ra8_fs_fat_internal.h"Go to the source code of this file.
Data Structures | |
| struct | fat_dir_stack_t |
| Bounded worklist of directories still to walk (NASA P10 Rule 1). More... | |
Enumerations | |
| enum | ra8_fs_check_marker_t : uint32_t { k_check_bad_fat12 = 0x0FF7U , k_check_bad_fat16 = 0xFFF7U , k_check_bad_fat32 = 0x0FFFFFF7U } |
| The FAT defective-cluster marker for each FAT width. More... | |
| enum | ra8_fs_check_bit_t : uint32_t { k_check_bit_mask = 7U , k_check_byte_shift = 3U } |
| Bit-arithmetic constants for the caller-supplied visited bitmap. 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. | |
| static uint32_t | internal_fat_bad_marker (const ra8_fs_mount_t *m) |
| The FAT defective-cluster marker for the mounted variant. | |
| static void | internal_fat_classify_one (ra8_fs_check_ctx_t *ctx, uint32_t cluster, uint32_t value) |
| Classify one FAT entry value into the report's cluster tallies. | |
| static ra8_err_t | internal_fat_classify (ra8_fs_check_ctx_t *ctx) |
| Pass 1: read and classify every data cluster's FAT entry. | |
| static ra8_err_t | internal_fat_mark_chain (ra8_fs_check_ctx_t *ctx, uint32_t first) |
| Mark a file's whole cluster chain, detecting cross-links and breaks. | |
| static void | internal_fat_push (ra8_fs_check_ctx_t *ctx, fat_dir_stack_t *stack, uint32_t clus) |
| Push a subdirectory onto the walk stack, capping the depth. | |
| 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. | |
| static ra8_err_t | internal_fat_entry (ra8_fs_check_ctx_t *ctx, fat_dir_stack_t *stack, const uint8_t *ent, uint64_t lba, uint32_t entry_off, uint8_t *out_eod) |
| Process one 32-byte FAT directory entry. | |
| static ra8_err_t | internal_fat_visit_sector (ra8_fs_check_ctx_t *ctx, fat_dir_stack_t *stack, const uint8_t *buf, uint64_t lba, uint8_t *out_eod) |
| Process the 16 directory entries of one loaded sector. | |
| static ra8_err_t | internal_fat_scan_fixed_root (ra8_fs_check_ctx_t *ctx, fat_dir_stack_t *stack) |
| Walk the FAT12/16 fixed root directory region. | |
| static ra8_err_t | internal_fat_scan_cluster_dir (ra8_fs_check_ctx_t *ctx, fat_dir_stack_t *stack, uint32_t first) |
| Walk a cluster-chained directory (a FAT32 root or any subdirectory). | |
| 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. | |
| static ra8_err_t | internal_fat_tree (ra8_fs_check_ctx_t *ctx) |
| Walk the whole directory tree from the root with an explicit worklist. | |
| static ra8_err_t | internal_fat_diff (ra8_fs_check_ctx_t *ctx) |
| Pass 3: flag allocated clusters no directory chain reached. | |
| static ra8_err_t | internal_fat_fsinfo (ra8_fs_check_ctx_t *ctx) |
| Compare a FAT32 volume's FSInfo free count against the classify pass. | |
| ra8_err_t | priv_check_fat (ra8_fs_check_ctx_t *ctx) |
| Run the FAT12/16/32 consistency check into the context's report. | |
| static bool | internal_check_bitmap_ok (uint32_t total, const uint8_t *bitmap, uint32_t bitmap_bytes) |
| Decide whether the caller's bitmap enables the reference passes. | |
| static ra8_err_t | internal_check_locked (ra8_fs_mount_t *handle, uint8_t *bitmap, uint32_t bitmap_bytes, ra8_fs_check_report_t *report) |
| Consistency check – the guarded body of ra8_fs_check(). | |
| ra8_err_t | ra8_fs_check (ra8_fs_mount_t *handle, uint8_t *bitmap, uint32_t bitmap_bytes, ra8_fs_check_report_t *report) |
| Scan a mounted volume for consistency, read-only, and report findings. | |
Read-only consistency check (fsck): shared scaffolding + FAT12/16/32.
The FAT half of ra8_fs_check, plus the scaffolding its exFAT half (ra8_fs_fat_exfat_check.c) shares: the finding recorder, the visited-cluster bitmap primitives, and the public entry point that brackets the library lock and dispatches on the volume type.
The FAT check is three passes over a mounted volume, none of which writes to it:
References (every shorthand citation in this file):
NASA Power-of-Ten compliance:
Definition in file ra8_fs_fat_check.c.
| enum ra8_fs_check_bit_t : uint32_t |
Bit-arithmetic constants for the caller-supplied visited bitmap.
The visited bitmap packs one cluster per bit, LSB first, so a cluster index shifts right by k_check_byte_shift to its byte and masks with k_check_bit_mask to its bit – the same layout the exFAT allocation bitmap uses, so the two diff directly.
| Enumerator | |
|---|---|
| k_check_bit_mask | Cluster index -> bit within its byte. |
| k_check_byte_shift | log2(8): cluster index -> bitmap byte. |
Definition at line 79 of file ra8_fs_fat_check.c.
| enum ra8_fs_check_marker_t : uint32_t |
The FAT defective-cluster marker for each FAT width.
One below the end-of-chain threshold in every FAT variant (MS FAT spec sec 4): a value the formatter or a surface scan writes to fence off a bad cluster. It is counted – informationally – rather than treated as corruption.
| Enumerator | |
|---|---|
| k_check_bad_fat12 | FAT12 defective-cluster marker. |
| k_check_bad_fat16 | FAT16 defective-cluster marker. |
| k_check_bad_fat32 | FAT32 defective-cluster marker. |
Definition at line 62 of file ra8_fs_fat_check.c.
|
static |
Decide whether the caller's bitmap enables the reference passes.
The bitmap must hold one bit per data cluster – (clusters_total + 7) / 8 bytes – for the walk / lost analysis to run. A NULL or short bitmap leaves the classification pass to run alone, with clusters_lost reported as k_ra8_fs_check_unknown.
| [in] | total | The volume's data-cluster count. |
| [in] | bitmap | The caller's bitmap, or NULL. |
| [in] | bitmap_bytes | The caller's bitmap size in bytes. |
| true | bitmap is non-NULL and large enough. |
| false | Otherwise. |
total is the mounted volume's cluster count. Definition at line 815 of file ra8_fs_fat_check.c.
References k_check_bit_mask, and k_check_byte_shift.
Referenced by internal_check_locked().
|
static |
Consistency check – the guarded body of ra8_fs_check().
Validates the arguments, seeds the report, decides whether the caller's bitmap enables the reference passes, and dispatches on the volume type into a local candidate report. The candidate is published only after the entire scan succeeds, so backend failures cannot expose a plausible-looking partial result. The public ra8_fs_check brackets this with the library lock; the full contract is documented there.
| [in] | handle | Mount handle. |
| [in] | bitmap | Scratch visited-cluster bitmap, or NULL. |
| [in] | bitmap_bytes | Size of bitmap in bytes. |
| [out] | report | Receives the findings. |
| k_ra8_ok | Scan completed. |
| k_ra8_err_null_ptr | handle or report is NULL. |
| k_ra8_err_invalid_state | Mount is not in use. |
| k_ra8_err_* | Backend read failure. |
handle and report are non-NULL. report retains its entry value. Definition at line 856 of file ra8_fs_fat_check.c.
References internal_check_bitmap_ok(), internal_check_locked(), k_ra8_err_null_ptr, k_ra8_fs_check_unknown, k_ra8_fs_type_exfat, k_ra8_ok, and ra8_fs_check_report_t::type.
Referenced by internal_check_locked(), and ra8_fs_check().
|
static |
The FAT defective-cluster marker for the mounted variant.
One below the end-of-chain threshold for the mounted FAT variant (MS FAT spec sec 4).
| [in] | m | Mounted FAT volume. |
| k_check_bad_fat12 | FAT12. |
| k_check_bad_fat16 | FAT16. |
| k_check_bad_fat32 | FAT32. |
m is non-NULL and m->type is a FAT variant. Definition at line 197 of file ra8_fs_fat_check.c.
References k_check_bad_fat12, k_check_bad_fat16, k_check_bad_fat32, k_ra8_fs_type_fat12, k_ra8_fs_type_fat16, and ra8_fs_mount_t::type.
Referenced by internal_fat_classify_one(), and internal_fat_diff().
|
static |
Pass 1: read and classify every data cluster's FAT entry.
A single pass over the FAT, tallying free, used and defective clusters.
| [in,out] | ctx | The scan context. |
| k_ra8_ok | Every entry classified. |
| k_ra8_err_* | Backend read failure. |
ctx is non-NULL; ctx->m->type is a FAT variant. Definition at line 270 of file ra8_fs_fat_check.c.
References ra8_fs_check_report_t::clusters_total, internal_fat_classify_one(), k_cluster_first_data, k_ra8_ok, ra8_fs_check_ctx_t::m, priv_fat_get(), and ra8_fs_check_ctx_t::rep.
Referenced by priv_check_fat().
|
static |
Classify one FAT entry value into the report's cluster tallies.
Free, defective and end-of-chain are each their own tally; a value in [2, 2 + clusters_total) is a valid next-cluster pointer and counts used; anything else – the reserved 1, or a pointer past the last cluster – is a bad FAT value, still counted used but recorded as a fault.
| [in,out] | ctx | The scan context. |
| [in] | cluster | The cluster whose entry value belongs to. |
| [in] | value | The FAT entry value read for cluster. |
ctx is non-NULL; the report's clusters_total is populated. value came from priv_fat_get for cluster. Definition at line 234 of file ra8_fs_fat_check.c.
References ra8_fs_check_report_t::clusters_bad, ra8_fs_check_report_t::clusters_free, ra8_fs_check_report_t::clusters_used, internal_fat_bad_marker(), k_cluster_free, k_ra8_fs_check_fault_bad_fat_value, ra8_fs_check_ctx_t::m, priv_check_fault(), priv_check_in_range(), priv_is_eoc(), and ra8_fs_check_ctx_t::rep.
Referenced by internal_fat_classify().
|
static |
Pass 3: flag allocated clusters no directory chain reached.
A single pass over the FAT flagging allocated clusters that no chain reached.
| [in,out] | ctx | The scan context. |
| k_ra8_ok | The diff completed. |
| k_ra8_err_* | Backend read failure. |
ctx and its bitmap are non-NULL; the tree walk has run. Definition at line 685 of file ra8_fs_fat_check.c.
References ra8_fs_check_ctx_t::bitmap, ra8_fs_check_report_t::clusters_lost, ra8_fs_check_report_t::clusters_total, internal_fat_bad_marker(), k_check_bit_mask, k_check_byte_shift, k_cluster_first_data, k_cluster_free, k_ra8_fs_check_fault_lost_cluster, k_ra8_ok, ra8_fs_check_ctx_t::m, priv_check_fault(), priv_fat_get(), and ra8_fs_check_ctx_t::rep.
Referenced by priv_check_fat().
|
static |
Process one 32-byte FAT directory entry.
Skips the entries that name nothing walkable – end-of-directory, deleted, long-name, "." / "..", and the volume-label – then validates the first cluster of a real file or directory. A file's chain is marked now; a directory is pushed to be walked (and marked) when it is popped.
| [in,out] | ctx | The scan context. |
| [in,out] | stack | The directory worklist. |
| [in] | ent | The 32-byte directory entry. |
| [in] | lba | Volume-relative sector the entry was read from. |
| [in] | entry_off | Byte offset of the entry in that sector. |
| [out] | out_eod | Set to 1 when ent is the end-of-directory marker. |
| k_ra8_ok | The entry was processed (a fault may have been recorded). |
| k_ra8_err_* | Backend read failure while marking a file chain. |
ent points at 32 valid bytes. Definition at line 420 of file ra8_fs_fat_check.c.
References ra8_fs_check_report_t::entries_bad, ra8_fs_check_report_t::files_visited, internal_fat_mark_chain(), internal_fat_push(), k_dir_marker_dot, k_dir_marker_free_perm, k_dir_marker_free_used, k_dir_off_attr, k_dir_off_name, k_ra8_fs_attr_directory, k_ra8_fs_attr_lfn, k_ra8_fs_attr_volume_id, k_ra8_fs_check_fault_bad_dir_entry, k_ra8_ok, priv_check_fault(), priv_check_in_range(), priv_entry_first_cluster(), and ra8_fs_check_ctx_t::rep.
Referenced by internal_fat_visit_sector().
|
static |
Compare a FAT32 volume's FSInfo free count against the classify pass.
Reads BPB_FSInfo from the boot sector, validates the three FSInfo signatures (MS FAT spec sec 5), and only then compares the stored free count to clusters_free. A volume with no or an untrusted FSInfo sector is not a fault – there is simply nothing to compare.
| [in,out] | ctx | The scan context. |
| k_ra8_ok | Compared, or nothing to compare. |
| k_ra8_err_* | Backend read failure. |
ctx is non-NULL; the classify pass has run. Definition at line 728 of file ra8_fs_fat_check.c.
References ra8_fs_check_report_t::clusters_free, k_fmt_fsi_lead_sig, k_fmt_fsi_off_free, k_fmt_fsi_off_lead, k_fmt_fsi_off_struct, k_fmt_fsi_off_trail, k_fmt_fsi_struct_sig, k_fmt_fsi_trail_sig, k_fmt_off_f32_fsinfo, k_fs_free_unknown, k_ra8_fs_check_fault_free_count_bad, k_ra8_fs_type_fat32, k_ra8_ok, ra8_fs_check_ctx_t::m, priv_check_fault(), priv_rd16(), priv_rd32(), priv_read_sector(), priv_sec_walk(), ra8_fs_check_ctx_t::rep, ra8_fs_mount_t::reserved_sectors, and ra8_fs_mount_t::type.
Referenced by priv_check_fat().
|
static |
Mark a file's whole cluster chain, detecting cross-links and breaks.
Follows the FAT from first, marking each cluster. A cluster already marked is a cross-link (or a loop) and stops the walk; a next-cluster that is free or out of range is a broken chain and stops it too. The hop count is bounded by clusters_total. After the last permitted hop, a non-terminal successor is checked once more without reading another FAT entry: it must revisit one of the volume's clusters or name a cluster outside the volume, so the bound cannot look clean.
| [in,out] | ctx | The scan context. |
| [in] | first | The file's first cluster (>= 2). |
| k_ra8_ok | The chain was walked (a fault may have been recorded). |
| k_ra8_err_* | Backend read failure. |
ctx and its bitmap are non-NULL; first is in range. Definition at line 317 of file ra8_fs_fat_check.c.
References ra8_fs_check_report_t::clusters_total, k_ra8_fs_check_fault_bad_chain, k_ra8_ok, ra8_fs_check_ctx_t::m, priv_check_fault(), priv_check_in_range(), priv_check_visit(), priv_fat_get(), priv_is_eoc(), and ra8_fs_check_ctx_t::rep.
Referenced by internal_fat_entry().
|
static |
Push a subdirectory onto the walk stack, capping the depth.
Records k_ra8_fs_check_fault_scan_truncated the first time the stack is full and drops the entry, so the tree walk stays bounded.
| [in,out] | ctx | The scan context (for the truncation fault). |
| [in,out] | stack | The directory worklist. |
| [in] | clus | The subdirectory's first cluster. |
ctx and stack are non-NULL; clus is in range. Definition at line 364 of file ra8_fs_fat_check.c.
References dir_loc_t::cluster, dir_loc_t::is_root, fat_dir_stack_t::items, k_ra8_fs_check_fault_scan_truncated, k_ra8_fs_check_max_dirs, priv_check_fault(), fat_dir_stack_t::top, and fat_dir_stack_t::truncated.
Referenced by internal_fat_entry(), and ra8_fs_check_test_fat_push_overflow().
|
static |
Walk a cluster-chained directory (a FAT32 root or any subdirectory).
Follows the directory's own cluster chain, marking each cluster (a revisit is a cross-link), and processes every sector of each cluster. The end-of-directory marker or a terminal FAT entry ends the walk. Reaching the hop bound validates the pending successor once more so a full-volume cycle or off-volume tail is reported, never accepted.
| [in,out] | ctx | The scan context. |
| [in,out] | stack | The directory worklist. |
| [in] | first | The directory's first cluster. |
| k_ra8_ok | The directory was walked. |
| k_ra8_err_* | Backend read failure. |
ctx and stack are non-NULL; first is a directory's first cluster. Definition at line 577 of file ra8_fs_fat_check.c.
References ra8_fs_check_report_t::clusters_total, internal_fat_visit_sector(), k_ra8_fs_check_fault_bad_dir_entry, k_ra8_ok, ra8_fs_check_ctx_t::m, priv_check_visit(), priv_cluster_to_lba(), priv_fat_get(), priv_is_eoc(), priv_read_sector(), priv_sec_walk(), ra8_fs_check_ctx_t::rep, and ra8_fs_mount_t::sectors_per_cluster.
Referenced by internal_fat_tree(), and ra8_fs_check_test_fat_scan_cluster_dir().
|
static |
Walk the FAT12/16 fixed root directory region.
Reads the FAT12/16 fixed root-directory region sector by sector.
| [in,out] | ctx | The scan context. |
| [in,out] | stack | The directory worklist. |
| k_ra8_ok | The fixed root was walked. |
| k_ra8_err_* | Backend read failure. |
ctx and stack are non-NULL; the mount is FAT12/16. Definition at line 527 of file ra8_fs_fat_check.c.
References ra8_fs_mount_t::first_root_lba, internal_fat_visit_sector(), k_ra8_ok, ra8_fs_check_ctx_t::m, priv_dir_eps(), priv_read_sector(), priv_sec_walk(), and ra8_fs_mount_t::root_entries.
Referenced by internal_fat_tree().
|
static |
Walk the whole directory tree from the root with an explicit worklist.
Pops directories off the worklist and walks each, the volume root first.
| [in,out] | ctx | The scan context. |
| k_ra8_ok | The tree was walked (faults may have been recorded). |
| k_ra8_err_* | Backend read failure. |
ctx and its bitmap are non-NULL; ctx->m->type is a FAT variant. Definition at line 638 of file ra8_fs_fat_check.c.
References dir_loc_t::cluster, ra8_fs_check_report_t::dirs_visited, internal_fat_scan_cluster_dir(), internal_fat_scan_fixed_root(), dir_loc_t::is_root, fat_dir_stack_t::items, k_ra8_fs_type_fat32, k_ra8_ok, ra8_fs_check_ctx_t::m, ra8_fs_check_ctx_t::rep, ra8_fs_mount_t::root_cluster, fat_dir_stack_t::top, and ra8_fs_mount_t::type.
Referenced by priv_check_fat().
|
static |
Process the 16 directory entries of one loaded sector.
Processes the sixteen directory entries packed into one 512-byte sector.
| [in,out] | ctx | The scan context. |
| [in,out] | stack | The directory worklist. |
| [in] | buf | The 512-byte directory sector. |
| [in] | lba | Volume-relative sector number of buf. |
| [out] | out_eod | Set to 1 when the end-of-directory marker was hit. |
| k_ra8_ok | The sector was processed. |
| k_ra8_err_* | Backend read failure while marking a chain. |
buf holds a directory sector. Definition at line 487 of file ra8_fs_fat_check.c.
References internal_fat_entry(), k_ra8_fs_dir_entry_bytes, k_ra8_ok, ra8_fs_check_ctx_t::m, and priv_dir_eps().
Referenced by internal_fat_scan_cluster_dir(), and internal_fat_scan_fixed_root().
| 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.
| [in,out] | ctx | The scan context (ctx->m->type is a FAT variant). |
| k_ra8_ok | The scan completed; findings are in the report. |
| k_ra8_err_* | Backend read failure mid-scan. |
ctx is non-NULL; ctx->m->type is FAT12/16/32. 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().
| 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.
| [in,out] | ctx | The scan context. |
| [in] | kind | The finding's category. |
| [in] | cluster | Cluster the finding concerns (0 if n/a). |
| [in] | lba | Volume-relative sector of the entry (0 if n/a). |
| [in] | entry_off | Byte offset of the entry in that sector (0 if n/a). |
ctx and ctx->rep are non-NULL. kind is not k_ra8_fs_check_fault_none. 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().
| 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.
| [in] | ctx | The scan context. |
| [in] | cluster | The cluster number to test. |
cluster addresses a data cluster. | true | 2 <= cluster < 2 + clusters_total. |
| false | Out of range. |
ctx is non-NULL. 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().
| 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.
| [in,out] | ctx | The scan context (its bitmap is written). |
| [in] | cluster | The cluster to mark; must be in range. |
| true | The bit was already set (cross-link / loop). |
| false | The bit was clear and is now set (first visit). |
ctx and ctx->bitmap are non-NULL. cluster. cluster reads as 1. 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().
| 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.
| [in,out] | ctx | The scan context (its bitmap and report are written). |
| [in] | cluster | The cluster to visit. |
| [in] | oor_kind | The fault kind to record when cluster is out of range. |
| true | A fault was recorded (out of range, or a cross-link). |
| false | cluster was in range and is now freshly marked. |
ctx and its bitmap are non-NULL. oor_kind is a range-style fault kind. cluster reads as 1. 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().
| 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.
| [in,out] | ctx | The scan context (its bitmap is cleared). |
ctx and ctx->bitmap are non-NULL. 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().
|
nodiscard |
Scan a mounted volume for consistency, read-only, and report findings.
Runs the passes described in this header's file comment for handle's filesystem and fills report. Nothing on the volume is written, so it is safe on a volume already suspected to be damaged – that is the whole point.
A return of k_ra8_ok means the scan COMPLETED, not that the volume is clean: a clean volume and a volume with a thousand lost clusters both return k_ra8_ok, and only report->faults_total tells them apart. A non-k_ra8_ok return means the scan could not run to completion – a null argument, an unmounted handle, or a backend read failure – and report retains its entry value. Findings are assembled in a private candidate and published only after the full scan succeeds, so callers cannot mistake partial counts for a completed check.
Pass bitmap of at least (report->clusters_total + 7) / 8 bytes to enable the reference / lost-cluster / cross-link analysis; pass bitmap == NULL (or fewer bytes) to run the classification pass alone (see the file comment). The bitmap is scratch: its contents on entry are ignored and on return undefined.
| [in] | handle | Mount handle from ra8_fs_mount(). |
| [in] | bitmap | Scratch visited-cluster bitmap, or NULL for the classification-only pass. Not read on entry. |
| [in] | bitmap_bytes | Size of bitmap in bytes (0 when bitmap is NULL). |
| [out] | report | Receives the structured findings. |
| k_ra8_ok | Scan completed; inspect report->faults_total. |
| k_ra8_err_null_ptr | handle or report is NULL. |
| k_ra8_err_invalid_state | Mount is not in use. |
| k_ra8_err_* | Backend read failure while scanning. |
report retains its entry value. Definition at line 892 of file ra8_fs_fat_check.c.
References internal_check_locked(), priv_lock_acquire(), priv_lock_release(), and ra8_fs_check().
Referenced by ra8_fs_check().
| 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.
| [in,out] | ctx | Synthetic context whose report receives a fault. |
| [in] | cluster | Cluster recorded for the dropped directory. |
| [in] | already_truncated | Whether a prior overflow was already recorded. |
ctx is non-NULL. ctx owns a non-NULL, writable report. Definition at line 380 of file ra8_fs_fat_check.c.
References internal_fat_push(), and k_ra8_fs_check_max_dirs.
| 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().
| [in,out] | ctx | Synthetic scan context whose mount supplies the FAT and directory data. |
| [in] | first | First cluster of the synthetic directory chain. |
| k_ra8_ok | The directory chain was walked; findings are in the report. |
| k_ra8_err_* | Backend read failure. |
ctx, its report, bitmap and mount are non-NULL. first is in range. Definition at line 615 of file ra8_fs_fat_check.c.
References internal_fat_scan_cluster_dir().