62 for (uint32_t i = 0; i < dots; i++) {
151 const char* leaf =
nullptr;
170 uint32_t new_cluster = 0;
175 const uint32_t parent_cluster = (parent.
is_root != 0U) ? 0U : parent.
cluster;
225 if (handle ==
nullptr) {
228 if (path ==
nullptr) {
231 if (handle->in_use == 0U) {
232 return k_ra8_err_invalid_state;
235 return priv_exfat_mkdir(handle, path);
252typedef enum : uint8_t {
340 const dir_loc_t loc = {.is_root = 0U, .cluster = cluster};
402 uint32_t* out_cluster)
404 const char* leaf =
nullptr;
409 if (leaf[0] ==
'\0') {
462 uint32_t cluster = 0;
515 if (handle ==
nullptr) {
518 if (path ==
nullptr) {
521 if (handle->in_use == 0U) {
522 return k_ra8_err_invalid_state;
525 return priv_exfat_rmdir(handle, path);
Annotation-attribute framework macros for ra8-firmware.
#define RA8_OWNS_RESOURCE(kind)
RAII-style resource ownership contract.
#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_err_not_empty
Container still holds members – the operation requires it empty.
@ k_ra8_err_invalid_arg
Invalid function argument.
@ k_ra8_err_exists
Item already exists – cannot create again.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
@ k_ra8_err_null_ptr
Pointer was NULL where a valid pointer was required.
@ k_ra8_err_protocol_error
Protocol-level error (e.g.
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).
ra8_err_t ra8_fs_mkdir(const ra8_fs_mount_t *handle, const char *path)
Create a directory at path.
ra8_err_t ra8_fs_rmdir(const ra8_fs_mount_t *handle, const char *path)
Remove an empty directory at path.
void priv_byte_fill(uint8_t *dst, uint8_t value, uint32_t n)
Fill n bytes of dst with value.
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.
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.
uint32_t priv_bps(const ra8_fs_mount_t *m)
One mounted volume's sector size in bytes.
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.
uint8_t * priv_sec_walk(void)
The WALK-role sector buffer (directory scans and entry RMW).
const uint8_t k_zero_sector[k_ra8_fs_sector_max]
One whole sector of zero bytes, in read-only storage.
static ra8_err_t internal_dir_cluster_init(const ra8_fs_mount_t *m, uint32_t new_cluster, uint32_t parent_cluster)
Initialise a freshly allocated directory cluster ("." + ".." + zeros).
static ra8_err_t internal_rmdir_locate(const ra8_fs_mount_t *handle, const char *path, dir_target_t *out, uint32_t *out_cluster)
Resolve a path to a removable subdirectory's entry and first cluster.
static ra8_err_t internal_fat_rmdir(const ra8_fs_mount_t *handle, const char *path)
Implementation of internal_fat_rmdir() – remove one empty FAT directory.
static ra8_err_t internal_dir_is_empty(const ra8_fs_mount_t *m, uint32_t cluster, uint8_t *out_empty)
Decide whether a subdirectory holds any entry other than "." / "..".
static ra8_err_t internal_fat_mkdir(const ra8_fs_mount_t *handle, const char *path)
Implementation of internal_fat_mkdir() – create one FAT directory.
static dir_scan_t internal_rmdir_scan_sector(const ra8_fs_mount_t *m, const uint8_t *buf)
Classify one already-loaded directory sector as empty / occupied / more.
static ra8_err_t internal_mkdir_locked(const ra8_fs_mount_t *handle, const char *path)
Create a directory – the guarded body of ra8_fs_mkdir().
dir_scan_t
Verdict of scanning one directory sector for occupancy.
@ k_dir_scan_used
A real entry was found; not empty.
@ k_dir_scan_more
Only skippable slots here; keep walking.
@ k_dir_scan_empty
End-of-directory marker reached.
static void internal_pack_dot_entry(uint8_t *ent, uint32_t dots, uint32_t cluster)
Pack a "." or ".." dot entry into a 32-byte directory slot.
static ra8_err_t internal_rmdir_locked(const ra8_fs_mount_t *handle, const char *path)
Remove an empty directory – the guarded body of ra8_fs_rmdir().
uint32_t priv_entry_first_cluster(const uint8_t *entry)
Read the first cluster from a 32-byte directory entry.
void priv_entry_set_cluster_size(uint8_t *entry, uint32_t cluster, uint32_t size)
Patch first-cluster + size back into a 32-byte directory entry.
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.
ra8_err_t priv_alloc_eoc_cluster(const ra8_fs_mount_t *m, uint32_t *out_c)
Allocate a fresh cluster, mark it EOC, and return its number.
Cross-TU shared declarations for the FAT/exFAT ra8_fs adapter.
ra8_err_t priv_free_chain(const ra8_fs_mount_t *m, uint32_t start)
Free an entire cluster chain starting at start.
ra8_err_t priv_dir_reserve(const ra8_fs_mount_t *m, const dir_loc_t *loc, const char *leaf, dir_insert_t *out)
Decide how a name will be stored and set aside the slots for it.
ra8_err_t priv_dir_erase_chain(const ra8_fs_mount_t *m, const dir_loc_t *loc, uint64_t lba, uint32_t off, const uint8_t *name83)
Delete a directory entry together with its long-name chain.
ra8_err_t priv_dir_lookup_any(const ra8_fs_mount_t *m, const dir_loc_t *loc, const char *leaf, uint64_t *out_lba, uint32_t *out_off, uint8_t out_entry[k_ra8_fs_dir_entry_bytes])
Resolve one leaf name by 8.3 first and by long name second.
ra8_err_t priv_dir_commit(const ra8_fs_mount_t *m, const dir_insert_t *plan, const uint8_t *tmpl, uint64_t *out_lba, uint32_t *out_off)
Write a reserved run: the long-name chain, then the 8.3 entry.
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.
void priv_dir_walk_init_loc(const ra8_fs_mount_t *m, const dir_loc_t *loc, dir_walk_t *w)
Initialise a directory walker for an arbitrary directory location.
ra8_err_t priv_dir_walk_next_sector(const ra8_fs_mount_t *m, dir_walk_t *w, uint8_t *out_eod)
Advance the walker to the next sector.
void priv_fat_entry_stamp_create(uint8_t *entry)
Stamp a fresh FAT directory entry's create, write, and access fields.
@ k_dir_off_attr
MS FAT spec sec 6 "DIR_Attr".
@ k_dir_name_field_len
8 + 3 raw chars (no dot).
@ k_dir_off_name
MS FAT spec sec 6 "DIR_Name" (11 bytes).
@ k_dir_marker_free_used
Slot was used, deleted.
@ k_dir_marker_free_perm
End-of-directory.
@ k_cluster_first_data
Cluster numbers start at 2.
@ k_ra8_fs_type_exfat
exFAT (read + streaming write + format).
@ k_ra8_fs_attr_lfn
Long-file-name marker (we skip).
@ 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".
Everything decided about a new directory entry before anything is written.
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).
One resolved directory entry: where it is, and what is in it.
uint32_t off
Byte offset within that sector.
uint8_t entry[k_ra8_fs_dir_entry_bytes]
The entry as read from disk.
dir_loc_t parent
Directory the entry lives in.
uint64_t lba
Sector holding the entry.
Internal cursor used by the directory iterator.
uint64_t cur_lba
Currently loaded LBA.
Cached parse of one mounted FAT volume.
uint32_t sectors_per_cluster
BPB BPB_SecPerClus.