62typedef enum : uint32_t {
79typedef enum : uint32_t {
139 if ((ctx->
bitmap[
byte] & mask) != 0U) {
142 ctx->
bitmap[byte] = (uint8_t)(ctx->
bitmap[
byte] | mask);
167 const uint32_t nbytes =
169 for (uint32_t i = 0U; i < nbytes; i++) {
382 bool already_truncated)
386 .truncated = already_truncated ? 1U : 0U,
530 for (uint32_t s = 0U; s < secs; s++) {
645 while (stack.
top > 0U) {
650 if ((loc.
is_root != 0U) && !fat32) {
770 if (ctx->
bitmap !=
nullptr) {
817 if (bitmap ==
nullptr) {
858 uint32_t bitmap_bytes,
861 if ((handle ==
nullptr) || (report ==
nullptr)) {
864 if (handle->in_use == 0U) {
865 return k_ra8_err_invalid_state;
868 candidate.
type = handle->type;
869 candidate.clusters_total = handle->count_of_clusters;
870 const bool have_bitmap =
872 candidate.referenced_scan = have_bitmap;
876 .bitmap = have_bitmap ? bitmap : nullptr,
877 .bitmap_bits = handle->count_of_clusters};
880 err = priv_check_exfat(&ctx);
882 err = priv_check_fat(&ctx);
894 uint32_t bitmap_bytes,
Annotation-attribute framework macros for ra8-firmware.
#define RA8_OWNS_RESOURCE(kind)
RAII-style resource ownership contract.
#define RA8_TEST_HELPER
Mark a symbol as externally-linked but only callable from tests.
#define RA8_EXPECTS_LOCK(name)
The function expects the named thread/IRQ lock to be held on entry.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
@ k_ra8_err_null_ptr
Pointer was NULL where a valid pointer was required.
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Minimal FAT12/FAT16/FAT32 filesystem adapter (read + write).
Read-only on-device volume consistency check (fsck) for ra8_fs.
@ k_ra8_fs_check_unknown
A count the check could not determine (no bitmap supplied).
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.
ra8_fs_check_fault_kind_t
The category of a single consistency finding.
@ k_ra8_fs_check_fault_bad_fat_value
FAT entry is out of range / reserved.
@ k_ra8_fs_check_fault_bad_dir_entry
A directory entry's first cluster is invalid.
@ k_ra8_fs_check_fault_bad_chain
A chain runs into free space or off-volume.
@ k_ra8_fs_check_fault_lost_cluster
A cluster is allocated but referenced by none.
@ k_ra8_fs_check_fault_scan_truncated
The directory worklist hit its static bound.
@ k_ra8_fs_check_fault_free_count_bad
FAT32 FSInfo free count disagrees.
@ k_ra8_fs_check_fault_crosslink
A cluster is reached by more than one chain.
uint32_t priv_rd32(const uint8_t *p)
Decode a little-endian uint32_t from a byte buffer.
ra8_err_t priv_fat_get(const ra8_fs_mount_t *m, uint32_t cluster, uint32_t *out_value)
Fetch the FAT entry for cluster, returning the next-cluster value.
uint16_t priv_rd16(const uint8_t *p)
Decode a little-endian uint16_t from a byte buffer.
uint64_t priv_cluster_to_lba(const ra8_fs_mount_t *m, uint32_t cluster)
Convert a cluster number into its first data-region LBA.
uint32_t priv_dir_eps(const ra8_fs_mount_t *m)
Directory entries per sector on one mounted volume.
uint8_t priv_is_eoc(const ra8_fs_mount_t *m, uint32_t value)
Test whether value is an end-of-chain marker for this FAT type.
ra8_err_t priv_read_sector(const ra8_fs_mount_t *m, uint64_t lba, uint8_t *buf)
Read a single sector into the module scratch buffer.
@ k_fs_free_unknown
MS FAT spec sec 5: count not known.
uint8_t * priv_sec_walk(void)
The WALK-role sector buffer (directory scans and entry RMW).
void priv_check_zero_bitmap(ra8_fs_check_ctx_t *ctx)
Zero the scratch visited-bitmap over its valid bit range.
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().
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_scan_fixed_root(ra8_fs_check_ctx_t *ctx, fat_dir_stack_t *stack)
Walk the FAT12/16 fixed root directory region.
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_fsinfo(ra8_fs_check_ctx_t *ctx)
Compare a FAT32 volume's FSInfo free count against the classify pass.
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 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.
ra8_fs_check_bit_t
Bit-arithmetic constants for the caller-supplied visited bitmap.
@ k_check_byte_shift
log2(8): cluster index -> bitmap byte.
@ k_check_bit_mask
Cluster index -> bit within its byte.
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.
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_classify(ra8_fs_check_ctx_t *ctx)
Pass 1: read and classify every data cluster's FAT entry.
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 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.
static ra8_err_t internal_fat_diff(ra8_fs_check_ctx_t *ctx)
Pass 3: flag allocated clusters no directory chain reached.
bool priv_check_mark(ra8_fs_check_ctx_t *ctx, uint32_t cluster)
Mark cluster visited in the scratch bitmap; report a prior visit.
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).
static uint32_t internal_fat_bad_marker(const ra8_fs_mount_t *m)
The FAT defective-cluster marker for the mounted variant.
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 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.
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.
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_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.
ra8_fs_check_marker_t
The FAT defective-cluster marker for each FAT width.
@ k_check_bad_fat16
FAT16 defective-cluster marker.
@ k_check_bad_fat12
FAT12 defective-cluster marker.
@ k_check_bad_fat32
FAT32 defective-cluster marker.
Cross-TU state and helpers for the volume consistency check (fsck).
@ k_ra8_fs_check_max_dirs
Directory worklist depth cap.
uint32_t priv_entry_first_cluster(const uint8_t *entry)
Read the first cluster from a 32-byte directory entry.
Cross-TU shared declarations for the FAT/exFAT ra8_fs adapter.
void priv_lock_release(void)
Drop the library lock taken by priv_lock_acquire.
void priv_lock_acquire(void)
Take the library lock, if the caller installed one.
@ k_fmt_fsi_off_free
FSInfo FSI_Free_Count offset.
@ k_fmt_fsi_off_struct
FSInfo FSI_StrucSig offset.
@ k_fmt_off_f32_fsinfo
FAT32 BPB_FSInfo sector number.
@ k_fmt_fsi_off_lead
FSInfo FSI_LeadSig offset.
@ k_fmt_fsi_off_trail
FSInfo FSI_TrailSig offset.
@ k_dir_off_attr
MS FAT spec sec 6 "DIR_Attr".
@ k_dir_off_name
MS FAT spec sec 6 "DIR_Name" (11 bytes).
@ k_fmt_fsi_lead_sig
FSInfo lead signature "RRaA".
@ k_fmt_fsi_trail_sig
FSInfo trailing signature.
@ k_fmt_fsi_struct_sig
FSInfo struct signature "rrAa".
@ k_dir_marker_free_used
Slot was used, deleted.
@ k_dir_marker_free_perm
End-of-directory.
@ k_cluster_free
Cluster free.
@ k_cluster_first_data
Cluster numbers start at 2.
@ k_ra8_fs_type_fat12
count_of_clusters < 4085.
@ k_ra8_fs_type_fat32
count_of_clusters >= 65525.
@ k_ra8_fs_type_exfat
exFAT (read + streaming write + format).
@ k_ra8_fs_type_fat16
4085 <= count_of_clusters < 65525.
@ k_ra8_fs_attr_lfn
Long-file-name marker (we skip).
@ k_ra8_fs_attr_volume_id
MS FAT spec sec 6 "ATTR_VOLUME_ID".
@ k_ra8_fs_attr_directory
MS FAT spec sec 6 "ATTR_DIRECTORY".
@ k_ra8_fs_dir_entry_bytes
MS FAT spec sec 6 "Directory Entry".
Identifies the directory a lookup/scan should operate in.
uint8_t is_root
1 => the volume root; 0 => the subdirectory at cluster.
uint32_t cluster
First cluster of the subdirectory (ignored when root).
Bounded worklist of directories still to walk (NASA P10 Rule 1).
uint8_t truncated
1 once an overflow was dropped.
dir_loc_t items[k_ra8_fs_check_max_dirs]
The pending directory locations.
uint32_t top
Count of pending entries.
The state one ra8_fs_check run threads through its passes.
ra8_fs_check_report_t * rep
The report being filled.
uint32_t bitmap_bits
Valid bit count (== clusters_total).
ra8_fs_mount_t * m
The mounted volume under check.
uint8_t * bitmap
Scratch visited-cluster bitmap, or NULL.
ra8_fs_check_fault_kind_t kind
Category of the first finding.
uint32_t cluster
Cluster the finding concerns (0 if n/a).
uint64_t lba
Volume-relative sector of the entry (0 if n/a).
uint32_t entry_off
Byte offset of the entry in that sector (0 n/a).
The structured result of one ra8_fs_check run.
ra8_fs_check_fault_t first_fault
Kind + location of the first finding.
uint32_t clusters_used
Clusters that read as allocated.
uint32_t chains_crosslinked
Clusters reached by more than one chain.
uint32_t entries_bad
Bad dir entry / SetChecksum / NameHash findings.
uint32_t clusters_total
Data-region cluster count.
uint32_t clusters_lost
Allocated but referenced by nothing; k_ra8_fs_check_unknown when referenced_scan is false.
uint32_t faults_total
Every finding, across all categories (0 == clean).
uint32_t clusters_bad
FAT defective-marker clusters (informational).
uint32_t clusters_free
Clusters that read as free.
uint32_t files_visited
Files walked.
ra8_fs_type_t type
The volume variant that was checked.
uint32_t dirs_visited
Directories walked.
Cached parse of one mounted FAT volume.
uint32_t reserved_sectors
BPB BPB_RsvdSecCnt.
uint32_t root_cluster
BPB BPB_RootClus (FAT32 only).
ra8_fs_type_t type
FAT12 / FAT16 / FAT32.
uint32_t root_entries
BPB BPB_RootEntCnt (FAT12/16).
uint32_t sectors_per_cluster
BPB BPB_SecPerClus.
uint64_t first_root_lba
FAT12/16 fixed root-dir start.