|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Cross-TU helper prototypes for the FAT/exFAT adapter (part B of 2). More...
Go to the source code of this file.
Functions | |
| ra8_err_t | priv_exfat_write_dir_set (const ra8_fs_mount_t *m, uint32_t cluster, uint32_t idx, const uint8_t *set, uint32_t bytes) |
| Write a pre-built entry set into consecutive directory entries. | |
| ra8_err_t | priv_exfat_write_upcase (const ra8_fs_backend_t *backend, uint64_t abs_lba, uint32_t bps, uint32_t *out_csum) |
| Write the canonical exFAT up-case table and return its checksum. | |
| void | priv_fat_entry_apply_attr (uint8_t *entry, uint8_t set_mask, uint8_t clear_mask) |
| Clear then set attribute bits in a 32-byte FAT directory entry. | |
| 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. | |
| ra8_err_t | priv_fat_set (const ra8_fs_mount_t *m, uint32_t cluster, uint32_t value) |
| Write value into the FAT entry for cluster across every FAT copy. | |
| ra8_err_t | priv_fmt_choose_geometry (ra8_fs_fmt_geom_t *g, uint32_t spc_hint) |
| Pick the cluster size that lands the FAT cluster count in the right band. | |
| ra8_err_t | priv_fmt_clear_region (const ra8_fs_backend_t *backend, uint64_t lba, uint64_t count, uint32_t bps) |
| Clear count blocks at lba to zero – bulk-erase if the backend can. | |
| ra8_err_t | priv_fmt_emit_volume (const ra8_fs_backend_t *backend, const ra8_fs_fmt_geom_t *g, const char *label) |
| Lay down the boot sector, FAT seeds, FSInfo, and the empty root. | |
| uint32_t | priv_fmt_reserved_for (ra8_fs_type_t type) |
| Map a requested FAT type to its reserved-sector count. | |
| void | priv_fmt_label_field (uint8_t *dst, const char *label) |
| Pad an ASCII volume label into an 11-byte BS_VolLab / label field. | |
| bool | priv_fmt_spc_valid (uint8_t spc) |
| Validate a caller-pinned sectors-per-cluster value. | |
| ra8_err_t | priv_free_chain (const ra8_fs_mount_t *m, uint32_t start) |
| Free an entire cluster chain starting at start. | |
| 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. | |
| void | priv_lfn_add (lfn_state_t *s, const uint8_t *ent) |
| Fold one LFN directory entry's 13 UTF-16LE code units into the state. | |
| const uint16_t * | priv_lfn_units_for (const lfn_state_t *s, const uint8_t *name83, uint32_t *out_units) |
Code units of the chain that precedes name83, or NULL if none. | |
| void | priv_lfn_reset (lfn_state_t *s) |
| Reset the LFN reassembly state so a fresh chain can start. | |
| void | priv_lock_acquire (void) |
| Take the library lock, if the caller installed one. | |
| void | priv_lock_release (void) |
| Drop the library lock taken by priv_lock_acquire. | |
| ra8_err_t | priv_open_locked (ra8_fs_mount_t *handle, const char *path, ra8_fs_mode_t mode, ra8_fs_file_t **out_file) |
| Open a file by path – the guarded body of ra8_fs_open(). | |
| ra8_err_t | priv_parse_bpb_into_mount (ra8_fs_mount_t *m) |
| Parse the BPB layout fields out of g_fs_scratch into m. | |
| ra8_err_t | priv_parse_volume (ra8_fs_mount_t *m) |
| Parse the volume at the current base: exFAT first, then FAT BPB. | |
| uint8_t | priv_path_to_83 (const char *path, uint8_t *out11) |
| Convert a "/FILE.TXT"-style path to packed 11-byte 8.3 form. | |
| 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. | |
| ra8_err_t | priv_resolve_dir (const ra8_fs_mount_t *m, const char *path, dir_loc_t *out) |
| Resolve a whole path to the directory it names. | |
| ra8_err_t | priv_resolve_parent (const ra8_fs_mount_t *m, const char *path, dir_loc_t *out_parent, const char **out_leaf) |
| Resolve all-but-the-last path component to a parent directory. | |
| uint32_t | priv_strlen (const char *s) |
| Length of a NUL-terminated string. | |
| char | priv_to_upper (char c) |
| Upper-case ASCII conversion (returns input unchanged if not lowercase). | |
| ra8_err_t | priv_write_into_sector (const ra8_fs_mount_t *m, uint64_t lba, uint32_t off_in_sector, const uint8_t *src, uint32_t put) |
Merge put bytes into one sector at lba, at off_in_sector. | |
| ra8_err_t | priv_write_sector (const ra8_fs_mount_t *m, uint64_t lba, const uint8_t *buf) |
| Write a single sector from a caller-provided buffer. | |
Cross-TU helper prototypes for the FAT/exFAT adapter (part B of 2).
The second half of the FAT/exFAT adapter's cross-TU helper prototypes. Each helper is defined static-free in exactly one FAT/exFAT translation unit and called from at least one other. This part covers the alphabetical run from priv_exfat_write_dir_set() through priv_write_sector(); the earlier helpers live in ra8_fs_fat_protos_a_internal.h. Both are aggregated by the ra8_fs_fat_internal.h umbrella, which every ra8_fs_fat*.c file includes.
This header aggregates each cross-TU helper's full Doxygen contract.
Definition in file ra8_fs_fat_protos_b_internal.h.
| ra8_err_t priv_exfat_write_dir_set | ( | const ra8_fs_mount_t * | m, |
| uint32_t | cluster, | ||
| uint32_t | idx, | ||
| const uint8_t * | set, | ||
| uint32_t | bytes ) |
Write a pre-built entry set into consecutive directory entries.
Read-modify-writes each entry slot so neighbouring entries are preserved.
| [in] | m | Mounted exFAT volume. |
| [in] | cluster | Directory cluster holding the run. |
| [in] | idx | Entry index of the run start. |
| [in] | set | Built entry-set bytes. |
| [in] | bytes | Total size of the set. |
| k_ra8_ok | Entries written. |
| k_ra8_err_* | Backend read/write failure. |
m and set are non-NULL; the run fits in the cluster. bytes is a multiple of the entry size. Definition at line 517 of file ra8_fs_fat_exfat_write.c.
References k_exfat_entry_bytes, k_ra8_ok, priv_bps(), priv_byte_copy(), priv_cluster_to_lba(), priv_read_sector(), priv_sec_io(), and priv_write_sector().
Referenced by internal_exfat_dir_relen(), internal_exfat_place_rename(), internal_exfat_put_entry(), internal_setattr_exfat(), internal_utime_exfat(), priv_exfat_flush_set(), priv_exfat_link(), priv_exfat_mkdir(), and priv_exfat_set_label().
| ra8_err_t priv_exfat_write_upcase | ( | const ra8_fs_backend_t * | backend, |
| uint64_t | abs_lba, | ||
| uint32_t | bps, | ||
| uint32_t * | out_csum ) |
Write the canonical exFAT up-case table and return its checksum.
Streams the 5836-byte Microsoft up-case table (k_exfat_fmt_upc_std_bytes, embedded in ra8_fs_fat_exfat_upcase.c) to the device starting at absolute LBA abs_lba, one bps-byte sector at a time, zero-padding the final partial sector. The rotate-add checksum (priv_exfat_csum32) is accumulated over exactly the table bytes – not the pad – so it equals the well-known 0xE619D30D and can be stamped into the root Up-case directory entry.
| [in] | backend | Block-device backend with a non-NULL write_block. |
| [in] | abs_lba | Absolute (partition-adjusted) first LBA of the up-case table's cluster run. |
| [in] | bps | Device sector size in bytes (a power of two, 512..4096). |
| [out] | out_csum | Receives the table checksum on success. |
| k_ra8_ok | Table written; out_csum populated. |
| k_ra8_err_* | Backend write_block failure; out_csum unspecified. |
backend and backend->write_block are non-NULL. out_csum is non-NULL; abs_lba's cluster run holds the table span. out_csum holds the checksum for the root Up-case entry. Definition at line 477 of file ra8_fs_fat_exfat_upcase.c.
References ra8_fs_backend_t::ctx, g_fs_scratch, k_exfat_fmt_upc_std_bytes, k_ra8_ok, priv_byte_copy(), priv_exfat_csum32(), s_exfat_upcase, and ra8_fs_backend_t::write_block.
Referenced by priv_exfat_format().
| void priv_fat_entry_apply_attr | ( | uint8_t * | entry, |
| uint8_t | set_mask, | ||
| uint8_t | clear_mask ) |
Clear then set attribute bits in a 32-byte FAT directory entry.
Rewrites the entry's DIR_Attr byte as (attr & ~clear_mask) | set_mask: bits in clear_mask are cleared, bits in set_mask are set, every other bit is left as it was. The two masks are applied in that order, so a bit named in both ends up set. This is the one place the attribute byte is patched – the archive-on-write convention (priv_truncate_existing, priv_write_locked) and ra8_fs_set_attr() both route through it, so the read-modify-write cast lives once.
| [in,out] | entry | 32-byte directory entry to update. |
| [in] | set_mask | Attribute bits to set. |
| [in] | clear_mask | Attribute bits to clear. |
Definition at line 44 of file ra8_fs_fat_file.c.
References k_dir_off_attr.
Referenced by internal_setattr_fat(), and internal_truncate_existing().
| 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.
On FAT12 a single entry can straddle two sectors, which is why we read one sector at a time and re-read on overflow.
| [in] | m | Mount providing the FAT type and geometry. |
| [in] | cluster | Cluster whose FAT entry to read. |
| [out] | out_value | Receives the next-cluster value. |
| k_ra8_ok | Entry read successfully. |
| k_ra8_err_* | Backend error from a sector read. |
Definition at line 187 of file ra8_fs_fat.c.
References ra8_fs_mount_t::first_fat_lba, internal_fat_entry_byte_offset(), k_cluster_mask_fat32, k_fat12_value_mask, k_ra8_fs_type_exfat, k_ra8_fs_type_fat12, k_ra8_fs_type_fat16, k_ra8_ok, k_shift_byte, k_shift_nibble, priv_bps(), priv_fat_sector_read(), priv_rd16(), priv_rd32(), priv_sec_fat(), priv_sec_fat2(), and ra8_fs_mount_t::type.
Referenced by internal_exchk_mark_fatchain(), internal_exfat_cluster_at(), internal_exfat_dir_survey(), internal_exfat_shrink_chain_tail(), internal_exfat_survey_alloc(), internal_fat_classify(), internal_fat_diff(), internal_fat_mark_chain(), internal_fat_scan_cluster_dir(), internal_fat_trunc_shrink(), internal_skip_clusters(), internal_space_fat_free(), internal_trunc_walk(), internal_walk_grow(), priv_alloc_cluster(), priv_dir_walk_next_sector(), priv_exfat_free_clusters(), priv_exfat_step_cluster(), and priv_free_chain().
| ra8_err_t priv_fat_set | ( | const ra8_fs_mount_t * | m, |
| uint32_t | cluster, | ||
| uint32_t | value ) |
Write value into the FAT entry for cluster across every FAT copy.
Walks m->num_fats FAT copies and dispatches to the appropriate FAT12/16/32 set helper.
| [in] | m | Mount providing geometry, backend, and FAT type. |
| [in] | cluster | Cluster whose FAT entry to update. |
| [in] | value | Value to write. |
| k_ra8_ok | All FAT copies updated. |
| k_ra8_err_* | Backend or set-helper failure. |
Definition at line 486 of file ra8_fs_fat.c.
References ra8_fs_mount_t::fat_size_sectors, ra8_fs_mount_t::first_fat_lba, internal_exfat_fat_set_one(), internal_fat12_set_one(), internal_fat16_set_one(), internal_fat32_set_one(), internal_fat_entry_byte_offset(), k_ra8_fs_type_exfat, k_ra8_fs_type_fat12, k_ra8_fs_type_fat16, k_ra8_ok, ra8_fs_mount_t::num_fats, priv_bps(), and ra8_fs_mount_t::type.
Referenced by internal_dir_grow(), internal_exfat_dir_link(), internal_exfat_link_cluster(), internal_exfat_materialize_run(), internal_exfat_shrink_chain_tail(), internal_fat_trunc_extend(), internal_fat_trunc_shrink(), internal_walk_grow(), priv_alloc_eoc_cluster(), and priv_free_chain().
| ra8_err_t priv_fmt_choose_geometry | ( | ra8_fs_fmt_geom_t * | g, |
| uint32_t | spc_hint ) |
Pick the cluster size that lands the FAT cluster count in the right band.
Sweeps spc upward through powers of two (1, 2, 4, ... up to k_fmt_spc_max). For FAT32 the count shrinks with larger clusters, so the first spc whose count is in-band (or below k_fmt_fat32_clus_cap) wins. For FAT12/16 a too-large count fails the lower clusters and a too-small count fails the larger ones, so the sweep accepts the first in-band hit. When spc_hint is zero the starting point for FAT32 comes from priv_fmt_fat32_default_spc(); for FAT12/16 it starts at 1. On success the geometry's sectors_per_cluster, fat_size_sectors, and count_of_clusters are populated.
| [in,out] | g | Geometry with type, total_sectors, reserved_sectors, root_entries, and root_sectors pre-filled. |
| [in] | spc_hint | Caller-pinned cluster size (0 = auto-sweep). |
| k_ra8_ok | Geometry chosen; output fields stored in g. |
| k_ra8_err_invalid_size | No cluster size yields a count in g->type's band. |
g is non-NULL with the input fields (type, total_sectors, reserved_sectors, root_entries, root_sectors) already set. spc_hint is 0 or a power of two in the range [1, k_fmt_spc_max]. g->type. g is left partially written and must be discarded.Definition at line 209 of file ra8_fs_fat_fmt.c.
References ra8_fs_fmt_geom_t::bytes_per_sector, ra8_fs_fmt_geom_t::count_of_clusters, ra8_fs_fmt_geom_t::fat_size_sectors, internal_fmt_clusters_for(), internal_fmt_count_in_band(), internal_fmt_fat32_default_spc(), k_fmt_spc_max, k_ra8_err_invalid_size, k_ra8_fs_type_fat32, k_ra8_ok, ra8_fs_fmt_geom_t::sectors_per_cluster, ra8_fs_fmt_geom_t::total_sectors, and ra8_fs_fmt_geom_t::type.
Referenced by internal_format_locked().
| ra8_err_t priv_fmt_clear_region | ( | const ra8_fs_backend_t * | backend, |
| uint64_t | lba, | ||
| uint64_t | count, | ||
| uint32_t | bps ) |
Clear count blocks at lba to zero – bulk-erase if the backend can.
Tries backend->erase_blocks first: on flash media (SD) that erases a region internally in one operation, this avoids streaming tens of MB of zeros (~30 MB of FAT on a 128 GB FAT32 card). The erase path is only taken when the backend guarantees a zero read-back – it signals inability with k_ra8_err_not_supported, on which (or when no erase hook is bound) this falls back to priv_fmt_zero_run. Any other backend error aborts.
| [in] | backend | Block-device backend. |
| [in] | lba | First block to clear. |
| [in] | count | Number of blocks to clear. |
| [in] | bps | Device sector size in bytes (sizes each zero write). |
| k_ra8_ok | The range now reads back as all-zero bytes. |
| k_ra8_err_* | A backend write/erase failure (other than not_supported). |
backend is non-NULL with a non-NULL write_block. count blocks starting at lba lie within the device. bps is the device's real sector size (used to size each write). Definition at line 473 of file ra8_fs_fat_fmt.c.
References ra8_fs_backend_t::ctx, ra8_fs_backend_t::erase_blocks, internal_fmt_zero_run(), and k_ra8_ok.
Referenced by internal_exfat_write_bitmap(), internal_exfat_write_fat(), internal_exfat_write_root(), and priv_fmt_emit_volume().
| ra8_err_t priv_fmt_emit_volume | ( | const ra8_fs_backend_t * | backend, |
| const ra8_fs_fmt_geom_t * | g, | ||
| const char * | label ) |
Lay down the boot sector, FAT seeds, FSInfo, and the empty root.
The write phase of ra8_fs_format(), split out to keep the public entry under the NASA Rule 4 length budget. Clears the FAT + root region (bulk-erase or zero-write) first, then builds the type-specific BPB and persists it at LBA 0, seeds the FATs, and writes any FAT32 FSInfo + backup. The root region is left zero by the initial clear.
| [in] | backend | Block-device backend. |
| [in] | g | Resolved geometry. |
| [in] | label | Optional volume label. |
| k_ra8_ok | Volume image fully written. |
| k_ra8_err_* | Backend write failure mid-format. |
backend, g are non-NULL with geometry resolved. g->type is FAT12/FAT16/FAT32. g->type volume. Definition at line 602 of file ra8_fs_fat_fmt.c.
References ra8_fs_fmt_geom_t::bytes_per_sector, ra8_fs_backend_t::ctx, ra8_fs_fmt_geom_t::fat_size_sectors, internal_fmt_build_bpb_f16(), internal_fmt_build_bpb_f32(), internal_fmt_seed_fats(), internal_fmt_write_fsinfo(), k_fmt_num_fats, k_ra8_fs_type_fat32, k_ra8_ok, priv_byte_fill(), priv_fmt_clear_region(), priv_sec_walk(), ra8_fs_fmt_geom_t::reserved_sectors, ra8_fs_fmt_geom_t::root_sectors, ra8_fs_fmt_geom_t::sectors_per_cluster, ra8_fs_fmt_geom_t::type, and ra8_fs_backend_t::write_block.
Referenced by internal_format_locked().
| void priv_fmt_label_field | ( | uint8_t * | dst, |
| const char * | label ) |
Pad an ASCII volume label into an 11-byte BS_VolLab / label field.
Copies label up to its NUL (or 11 characters) then space-fills the remainder, matching the BS_VolLab convention. A NULL or empty label resolves to the FAT specification's unlabelled sentinel "NO NAME " – never zeros and never a bare run of spaces, both of which fsck.fat treats as a corrupt label and strips (#634). Shared by the formatter (ra8_fs_format()) and the runtime label writer (ra8_fs_set_label()), so both lay the field identically.
| [out] | dst | Destination 11-byte label field. |
| [in] | label | Source label, or NULL / "" for the unlabelled sentinel. |
dst is non-NULL and addresses at least k_fmt_label_len bytes. label is NUL-terminated when non-NULL. dst holds the padded 11-byte label (or the "NO NAME " sentinel). dst is touched.Definition at line 272 of file ra8_fs_fat_fmt.c.
References k_fmt_label_len.
Referenced by internal_fat_boot_set_label(), internal_fat_put_vol_id(), internal_fmt_build_bpb_f16(), and internal_fmt_build_bpb_f32().
| uint32_t priv_fmt_reserved_for | ( | ra8_fs_type_t | type | ) |
Map a requested FAT type to its reserved-sector count.
FAT32 reserves a 32-sector region (boot + FSInfo + backup); FAT12/16 reserve only the single boot sector.
| [in] | type | Requested FAT variant. |
type. | k_fmt_resv_f32 | type is FAT32. |
| k_fmt_resv_f16 | type is FAT12 or FAT16. |
type is one of FAT12/FAT16/FAT32. type.Definition at line 27 of file ra8_fs_fat_fmt.c.
References k_fmt_resv_f16, k_fmt_resv_f32, and k_ra8_fs_type_fat32.
Referenced by internal_format_locked().
| bool priv_fmt_spc_valid | ( | uint8_t | spc | ) |
Validate a caller-pinned sectors-per-cluster value.
A zero value defers to the auto-sweep. A non-zero value must be a power of two in the closed range 1..k_fmt_spc_max.
| [in] | spc | Requested cluster size. |
spc is acceptable. | true | spc is 0 (auto) or a power of two in 1..128. |
| false | spc is non-zero and not a valid power of two. |
spc.Definition at line 589 of file ra8_fs_fat_fmt.c.
References k_fmt_spc_max.
Referenced by internal_format_locked().
| ra8_err_t priv_free_chain | ( | const ra8_fs_mount_t * | m, |
| uint32_t | start ) |
Free an entire cluster chain starting at start.
Walks the chain via priv_fat_get, marking each cluster free. A guard counter bounds the loop against on-disk loops.
| [in] | m | Mount providing FAT access. |
| [in] | start | First cluster of the chain. |
| k_ra8_ok | All clusters freed. |
| k_ra8_err_protocol_error | Loop detected in chain. |
| k_ra8_err_* | Backend error. |
Definition at line 331 of file ra8_fs_fat_lfn.c.
References ra8_fs_mount_t::count_of_clusters, k_cluster_first_data, k_cluster_free, k_ra8_err_protocol_error, k_ra8_ok, priv_alloc_hint_lower(), priv_fat_get(), priv_fat_set(), priv_free_count_gave(), and priv_is_eoc().
Referenced by internal_dir_grow(), internal_fat_mkdir(), internal_fat_rmdir(), internal_fat_trunc_shrink(), internal_truncate_existing(), and internal_unlink_locked().
| 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.
EOC markers differ across FAT12/16/32.
| [in] | m | Mount providing the FAT type. |
| [in] | value | FAT entry value to test. |
| 1 | value indicates end-of-chain. |
| 0 | value is a normal next-cluster pointer. |
Definition at line 511 of file ra8_fs_fat.c.
References k_cluster_eoc_min_exfat, k_cluster_eoc_min_fat12, k_cluster_eoc_min_fat16, k_cluster_eoc_min_fat32, k_ra8_fs_type_exfat, k_ra8_fs_type_fat12, k_ra8_fs_type_fat16, and ra8_fs_mount_t::type.
Referenced by internal_exchk_mark_fatchain(), internal_exfat_cluster_at(), internal_exfat_dir_survey(), internal_exfat_survey_alloc(), internal_fat_classify_one(), internal_fat_mark_chain(), internal_fat_scan_cluster_dir(), internal_fat_trunc_shrink(), internal_skip_clusters(), internal_trunc_walk(), internal_walk_grow(), priv_dir_walk_next_sector(), priv_exfat_free_clusters(), priv_exfat_step_cluster(), and priv_free_chain().
| void priv_lfn_add | ( | lfn_state_t * | s, |
| const uint8_t * | ent ) |
Fold one LFN directory entry's 13 UTF-16LE code units into the state.
Reads the sequence number from ent (low 5 bits of LDIR_Ord) to locate the unit group within the assembled name, then copies each of the 13 units at their VFAT byte offsets (LDIR_Name1/2/3) VERBATIM. A zero unit or the padding value (0xFFFF) terminates the group early. The stored checksum is updated from LDIR_Chksum. Out-of-range sequence numbers are silently ignored to tolerate a corrupt chain.
Units above 0x7F used to become ?, which made the reported name one the caller could not hand back to ra8_fs_open() – the file was listed and then unopenable, and two names differing only in an accent collided (#606).
| [in,out] | s | Reassembly state being accumulated. |
| [in] | ent | 32-byte raw LFN directory entry (attribute byte == 0x0F). |
s is non-NULL and was initialised by priv_lfn_reset(). ent is non-NULL and points to exactly 32 valid bytes. s->units and s->checksum reflect the units from this entry. s is unchanged.Definition at line 141 of file ra8_fs_fat_lfn.c.
References lfn_state_t::checksum, lfn_state_t::have, k_lfn_chars_per_ent, k_lfn_max_entries, k_lfn_off_checksum, k_lfn_off_seq, k_lfn_seq_order_mask, k_lfn_unicode_pad, k_lfn_write_max, s_lfn_char_off, and lfn_state_t::units.
Referenced by internal_dir_find_long_sector(), internal_fat_dir_scan_sector(), and internal_listdir_visit_sector().
| void priv_lfn_reset | ( | lfn_state_t * | s | ) |
Reset the LFN reassembly state so a fresh chain can start.
Clears the accumulated unit array, then resets the stored checksum and the "have" flag to zero. Called at the start of a directory walk and whenever a deleted or consumed 8.3 entry breaks an in-progress chain.
| [in,out] | s | Reassembly state to reset. |
s is non-NULL. s was previously initialised (e.g. via zero-init or a prior reset). s->units is all zero. s->have and s->checksum are both zero.Definition at line 131 of file ra8_fs_fat_lfn.c.
References lfn_state_t::checksum, lfn_state_t::have, k_lfn_write_max, and lfn_state_t::units.
Referenced by internal_dir_find_long_sector(), internal_fat_dir_scan_sector(), internal_listdir_visit_sector(), and priv_dir_find_long().
| const uint16_t * priv_lfn_units_for | ( | const lfn_state_t * | s, |
| const uint8_t * | name83, | ||
| uint32_t * | out_units ) |
Code units of the chain that precedes name83, or NULL if none.
Returns the reassembled name only when a chain was accumulated and its checksum matches name83, so a stray chain never aliases an entry. The units are returned rather than text because that is the domain a lookup compares in and the domain the up-case table folds; only the listing path converts, and only at the API boundary.
The length is the run of non-zero units, exactly as the NUL used to end the string: a group that never arrived leaves zeros, and the name stops there instead of running into another chain's characters.
| [in] | s | Reassembly state carried across the directory walk. |
| [in] | name83 | The 8.3 entry the chain is claimed to belong to. |
| [out] | out_units | Receives the unit count (0 when there is no name). |
| s->units | The chain is present and binds to name83. |
| nullptr | No chain, an empty one, or a checksum mismatch. |
s and out_units are non-NULL; name83 addresses 11 bytes. s was initialised by priv_lfn_reset() before the walk. s is not modified.Definition at line 171 of file ra8_fs_fat_lfn.c.
References lfn_state_t::checksum, lfn_state_t::have, k_lfn_write_max, priv_sfn_checksum(), and lfn_state_t::units.
Referenced by internal_dir_find_long_sector(), internal_fat_dir_scan_sector(), and internal_listdir_visit_sector().
| void priv_lock_acquire | ( | void | ) |
Take the library lock, if the caller installed one.
Invokes the installed ra8_fs_lock_t::acquire with its cookie. With no binding installed – the bare-metal default – this is a load and a branch and nothing else, which is why the seam costs the default world nothing. Called only by the public entry-point wrappers: an internal helper taking it a second time would deadlock a non-recursive mutex, and the RA8_EXPECTS_LOCK("ra8_fs_lock") tag on every guarded implementation is what enforces that.
Definition at line 75 of file ra8_fs_fat_lock.c.
References s_lock, and s_lock_installed.
Referenced by ra8_fs_check(), ra8_fs_close(), ra8_fs_dir_next(), ra8_fs_dir_open(), ra8_fs_format(), ra8_fs_free_space(), ra8_fs_get_label(), ra8_fs_listdir(), ra8_fs_mkdir(), ra8_fs_mount(), ra8_fs_mount_partition(), ra8_fs_open(), ra8_fs_probe(), ra8_fs_read(), ra8_fs_rename(), ra8_fs_rmdir(), ra8_fs_seek(), ra8_fs_set_attr(), ra8_fs_set_label(), ra8_fs_size(), ra8_fs_stat(), ra8_fs_tell(), ra8_fs_truncate(), ra8_fs_unlink(), ra8_fs_unmount(), ra8_fs_utime(), ra8_fs_write(), and ra8_fs_write_file().
| void priv_lock_release | ( | void | ) |
Drop the library lock taken by priv_lock_acquire.
Invokes the installed ra8_fs_lock_t::release with its cookie, or does nothing when no binding is installed. This is the release half the annotation checker looks for when it decides whether a public wrapper discharged the ownership it took.
Definition at line 84 of file ra8_fs_fat_lock.c.
References s_lock, and s_lock_installed.
Referenced by ra8_fs_check(), ra8_fs_close(), ra8_fs_dir_next(), ra8_fs_dir_open(), ra8_fs_format(), ra8_fs_free_space(), ra8_fs_get_label(), ra8_fs_listdir(), ra8_fs_mkdir(), ra8_fs_mount(), ra8_fs_mount_partition(), ra8_fs_open(), ra8_fs_probe(), ra8_fs_read(), ra8_fs_rename(), ra8_fs_rmdir(), ra8_fs_seek(), ra8_fs_set_attr(), ra8_fs_set_label(), ra8_fs_size(), ra8_fs_stat(), ra8_fs_tell(), ra8_fs_truncate(), ra8_fs_unlink(), ra8_fs_unmount(), ra8_fs_utime(), ra8_fs_write(), and ra8_fs_write_file().
| ra8_err_t priv_open_locked | ( | ra8_fs_mount_t * | handle, |
| const char * | path, | ||
| ra8_fs_mode_t | mode, | ||
| ra8_fs_file_t ** | out_file ) |
Open a file by path – the guarded body of ra8_fs_open().
Carries the whole contract documented for ra8_fs_open() in ra8_fs.h; the public symbol is the wrapper that brackets this call with priv_lock_acquire / priv_lock_release. Exposed across translation units because ra8_fs_write_file()'s guarded body has to reach it without taking the lock a second time.
| [in] | handle | Mount handle. |
| [in] | path | NUL-terminated path. |
| [in] | mode | Open mode. |
| [out] | out_file | Receives the open file handle. |
| k_ra8_ok | File opened. |
| k_ra8_err_null_ptr | Any pointer argument was NULL. |
| k_ra8_err_* | As documented for ra8_fs_open(). |
Definition at line 455 of file ra8_fs_fat_file.c.
References ra8_fs_mount_t::in_use, internal_create_new(), internal_open_existing(), k_ra8_err_invalid_state, k_ra8_err_not_found, k_ra8_err_null_ptr, k_ra8_fs_dir_entry_bytes, k_ra8_fs_mode_read, k_ra8_fs_type_exfat, k_ra8_ok, priv_dir_lookup_any(), priv_exfat_open(), priv_resolve_parent(), and ra8_fs_mount_t::type.
Referenced by internal_write_file_locked(), and ra8_fs_open().
| ra8_err_t priv_parse_bpb_into_mount | ( | ra8_fs_mount_t * | m | ) |
Parse the BPB layout fields out of g_fs_scratch into m.
Validates the boot signature (0x55AA) and reads the BPB fields out of the boot sector scratch buffer.
| [in,out] | m | Mount to populate; backend already plugged in. |
| k_ra8_ok | Fields parsed successfully. |
| k_ra8_err_validation_failed | Bad signature or sanity-check fail. |
Definition at line 171 of file ra8_fs_fat_mount.c.
References ra8_fs_mount_t::bytes_per_sector, ra8_fs_mount_t::fat_size_sectors, g_fs_scratch, k_bpb_off_bytes_per_sec, k_bpb_off_fat_sz_16, k_bpb_off_fat_sz_32, k_bpb_off_num_fats, k_bpb_off_root_clus, k_bpb_off_root_ent_cnt, k_bpb_off_rsvd_sec_cnt, k_bpb_off_sec_per_clus, k_bpb_off_signature_hi, k_bpb_off_signature_lo, k_bpb_off_tot_sec_16, k_bpb_off_tot_sec_32, k_bpb_sig_hi, k_bpb_sig_lo, k_ra8_err_validation_failed, k_ra8_ok, ra8_fs_mount_t::num_fats, priv_rd16(), priv_rd32(), ra8_fs_mount_t::reserved_sectors, ra8_fs_mount_t::root_cluster, ra8_fs_mount_t::root_entries, ra8_fs_mount_t::sectors_per_cluster, and ra8_fs_mount_t::total_sectors.
Referenced by priv_parse_volume().
| ra8_err_t priv_parse_volume | ( | ra8_fs_mount_t * | m | ) |
Parse the volume at the current base: exFAT first, then FAT BPB.
Dispatches to the exFAT parser when the VBR carries the exFAT signature, else to the FAT BPB parser.
| [in,out] | m | Mount with sector 0 already read into g_fs_scratch. |
| k_ra8_ok | Volume parsed (FAT or exFAT). |
| k_ra8_err_* | No recognizable volume at this base. |
m is non-NULL and g_fs_scratch holds the base sector 0. Definition at line 162 of file ra8_fs_fat_exfat_read.c.
References g_fs_scratch, internal_exfat_is_volume(), internal_exfat_parse(), and priv_parse_bpb_into_mount().
Referenced by internal_read_boot_sector().
| uint8_t priv_path_to_83 | ( | const char * | path, |
| uint8_t * | out11 ) |
Convert a "/FILE.TXT"-style path to packed 11-byte 8.3 form.
Strips leading /, pre-pads out11 with spaces, calls the base/extension packers, and rewrites a leading 0xE5 byte to the kanji escape 0x05.
| [in] | path | NUL-terminated input path. Must be non-NULL. |
| [out] | out11 | 11-byte output buffer. Must be non-NULL. |
| 1 | Name packed into out11. |
| 0 | NULL input or name violates 8.3 rules. |
Definition at line 150 of file ra8_fs_fat_name.c.
References internal_pack_base(), internal_pack_ext(), and k_max_8_3_name.
Referenced by internal_setattr_fat(), internal_stat_fat(), internal_utime_fat(), priv_dir_lookup_any(), and priv_name_classify().
| 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.
Forwards to the mount's backend.read_block callback.
| [in] | m | Mount whose backend to use. |
| [in] | lba | Logical block address to read. |
| [out] | buf | Destination of m->bytes_per_sector bytes. |
| k_ra8_ok | Sector read successfully. |
| k_ra8_err_* | Whatever the backend returned. |
Definition at line 134 of file ra8_fs_fat.c.
References ra8_fs_mount_t::backend, ra8_fs_backend_t::ctx, ra8_fs_mount_t::partition_base_lba, and ra8_fs_backend_t::read_block.
Referenced by internal_close_stamp(), internal_dir_collect_chain(), internal_dir_erase_positions(), internal_dir_is_empty(), internal_exchk_bitmap_pass(), internal_exfat_bitmap_window(), internal_exfat_read_entry(), internal_fat_boot_set_label(), internal_fat_del_entry(), internal_fat_dir_next(), internal_fat_find_free_root(), internal_fat_find_vol_id(), internal_fat_fsinfo(), internal_fat_put_vol_id(), internal_fat_scan_cluster_dir(), internal_fat_scan_fixed_root(), internal_fat_trunc_commit(), internal_fsinfo_locate(), internal_get_label_fat(), internal_gpt_read_geom(), internal_gpt_scan_entries(), internal_read_boot_sector(), internal_read_one_chunk(), internal_setattr_fat(), internal_slot_advance(), internal_space_exfat_free(), internal_trunc_zero_span(), internal_truncate_existing(), internal_utime_fat(), priv_dir_commit(), priv_dir_find(), priv_dir_find_free_run(), priv_dir_find_long(), priv_exfat_bitmap_test(), priv_exfat_bmp_switch(), priv_exfat_next_entry(), priv_exfat_seal_cluster(), priv_exfat_write_dir_set(), priv_fat_sector_read(), priv_fsinfo_flush(), priv_fsinfo_seed(), priv_gpt_locate_partition(), and priv_write_into_sector().
| ra8_err_t priv_resolve_dir | ( | const ra8_fs_mount_t * | m, |
| const char * | path, | ||
| dir_loc_t * | out ) |
Resolve a whole path to the directory it names.
The empty path or "/" resolves to the volume root; otherwise the parent is resolved and the final component is entered as a subdirectory. Used by ra8_fs_listdir to walk any directory.
| [in] | m | Mount providing geometry and backend. |
| [in] | path | NUL-terminated directory path. |
| [out] | out | Receives the resolved directory location. |
| k_ra8_ok | Directory resolved. |
| k_ra8_err_invalid_arg | A component is not a directory / not 8.3. |
| k_ra8_err_not_found | A component does not exist. |
| k_ra8_err_* | Backend error. |
Definition at line 357 of file ra8_fs_fat_file.c.
References dir_loc_t::cluster, internal_enter_subdir(), dir_loc_t::is_root, k_ra8_ok, and priv_resolve_parent().
| ra8_err_t priv_resolve_parent | ( | const ra8_fs_mount_t * | m, |
| const char * | path, | ||
| dir_loc_t * | out_parent, | ||
| const char ** | out_leaf ) |
Resolve all-but-the-last path component to a parent directory.
Splits path on /, descending through each intermediate component (which must be an existing subdirectory) and returning the final component as out_leaf. A flat name (no embedded /) yields the root as the parent and the whole name as the leaf – the legacy root-only behaviour. The walk is bounded by k_path_max_depth.
| [in] | m | Mount providing geometry and backend. |
| [in] | path | NUL-terminated path (leading slashes ignored). |
| [out] | out_parent | Receives the resolved parent directory location. |
| [out] | out_leaf | Receives a pointer into path at the final component. |
| k_ra8_ok | Parent resolved; out_leaf set. |
| k_ra8_err_invalid_arg | A component is not 8.3, or the path is too deep. |
| k_ra8_err_not_found | An intermediate component does not exist. |
| k_ra8_err_* | Backend error. |
Definition at line 319 of file ra8_fs_fat_file.c.
References internal_enter_subdir(), k_path_max_depth, k_ra8_err_invalid_arg, and k_ra8_ok.
Referenced by internal_fat_mkdir(), internal_rename_prepare(), internal_rmdir_locate(), internal_setattr_fat(), internal_stat_fat(), internal_unlink_locate(), internal_utime_fat(), priv_open_locked(), and priv_resolve_dir().
| uint32_t priv_strlen | ( | const char * | s | ) |
Length of a NUL-terminated string.
Counts bytes up to the NUL terminator.
| [in] | s | NUL-terminated string. |
| 0..UINT32_MAX | String length. |
s is non-NULL. s is NUL-terminated. s is unmodified. Definition at line 27 of file ra8_fs_fat_exfat_read.c.
Referenced by internal_exfat_rename_prepare(), internal_exfat_rmdir_locate(), internal_set_label_locked(), priv_exfat_lookup(), priv_exfat_resolve_dir(), and priv_exfat_unlink().
| char priv_to_upper | ( | char | c | ) |
Upper-case ASCII conversion (returns input unchanged if not lowercase).
Locale-independent ASCII upcase.
| [in] | c | Input character. |
| 'A'..'Z' | Upper-cased input. |
| c | Otherwise unchanged. |
Upper-case ASCII conversion (returns input unchanged if not lowercase).
Result is space-padded as on-disk. Lower-case input is upper-cased. Returns 0 on bad name (>8 base, >3 ext, missing chars), 1 on success.
Definition at line 56 of file ra8_fs_fat_name.c.
Referenced by internal_alias_map_unit(), internal_pack_base(), and internal_pack_ext().
| ra8_err_t priv_write_into_sector | ( | const ra8_fs_mount_t * | m, |
| uint64_t | lba, | ||
| uint32_t | off_in_sector, | ||
| const uint8_t * | src, | ||
| uint32_t | put ) |
Merge put bytes into one sector at lba, at off_in_sector.
Read-modify-write of a single sector. Every partial-sector update in this adapter goes through it, so a write that does not start or end on a sector boundary cannot destroy the neighbouring bytes – which, inside a cluster, belong to the same file, and at a cluster edge may belong to another.
| [in] | m | Mount providing the backend. |
| [in] | lba | Volume-relative sector to update. |
| [in] | off_in_sector | Byte offset within the sector. |
| [in] | src | Source bytes. |
| [in] | put | Number of bytes to write. |
| k_ra8_ok | Sector updated. |
| k_ra8_err_* | Backend read or write failure. |
Merge put bytes into one sector at lba, at off_in_sector.
Definition at line 341 of file ra8_fs_fat_fileio.c.
References k_ra8_ok, priv_byte_copy(), priv_read_sector(), priv_sec_io(), and priv_write_sector().
Referenced by internal_exfat_close_gap(), internal_write_stream(), and priv_exfat_write_stream().
| ra8_err_t priv_write_sector | ( | const ra8_fs_mount_t * | m, |
| uint64_t | lba, | ||
| const uint8_t * | buf ) |
Write a single sector from a caller-provided buffer.
Forwards to the mount's backend.write_block callback.
| [in] | m | Mount whose backend to use. |
| [in] | lba | Logical block address to write. |
| [in] | buf | Source of m->bytes_per_sector bytes. |
| k_ra8_ok | Sector written successfully. |
| k_ra8_err_* | Whatever the backend returned. |
Definition at line 140 of file ra8_fs_fat.c.
References ra8_fs_mount_t::backend, ra8_fs_backend_t::ctx, ra8_fs_mount_t::partition_base_lba, and ra8_fs_backend_t::write_block.
Referenced by internal_close_stamp(), internal_dir_cluster_init(), internal_dir_erase_positions(), internal_dir_grow(), internal_exfat_fat_set_one(), internal_fat12_store(), internal_fat16_set_one(), internal_fat32_set_one(), internal_fat_boot_set_label(), internal_fat_del_entry(), internal_fat_put_vol_id(), internal_fat_trunc_commit(), internal_setattr_fat(), internal_slot_advance(), internal_trunc_zero_span(), internal_truncate_existing(), internal_utime_fat(), priv_dir_commit(), priv_exfat_bitmap_clear(), priv_exfat_bitmap_mark(), priv_exfat_bmp_switch(), priv_exfat_seal_cluster(), priv_exfat_write_dir_set(), priv_exfat_zero_cluster(), priv_fsinfo_flush(), and priv_write_into_sector().