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

Cross-TU prototypes of the exFAT DIRECTORY seam. More...

Include dependency graph for ra8_fs_fat_exfat_dir_internal.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void priv_exfat_dir_root (const ra8_fs_mount_t *m, exfat_dir_t *out)
 Fill out with the volume root's directory location.
void priv_exfat_dir_from_set (const ra8_fs_mount_t *m, const uint8_t *strm, exfat_dir_t *out)
 Build a directory location from a Stream entry's allocation fields.
void priv_exfat_cursor_init (const exfat_dir_t *dir, exfat_cursor_t *out)
 Aim a fresh cursor at the start of dir.
ra8_err_t priv_exfat_step_cluster (const ra8_fs_mount_t *m, uint32_t cluster, uint32_t contig_end, uint32_t *out_next)
 Compute the cluster that follows cluster in a directory.
ra8_err_t priv_exfat_resolve_parent (const ra8_fs_mount_t *m, const char *path, exfat_dir_t *out_parent, const char **out_leaf)
 Resolve every component of path but the last.
ra8_err_t priv_exfat_resolve_dir (const ra8_fs_mount_t *m, const char *path, exfat_dir_t *out)
 Resolve a whole path to the directory it names.
ra8_err_t priv_exfat_lookup (const ra8_fs_mount_t *m, const char *path, uint8_t *out_strm, uint8_t *out_attr)
 Resolve a path and return the leaf entry set's location fields.
ra8_err_t priv_exfat_mkdir (const ra8_fs_mount_t *m, const char *path)
 Create one exFAT directory at path.
ra8_err_t priv_exfat_rmdir (const ra8_fs_mount_t *m, const char *path)
 Remove one EMPTY exFAT directory at path.
ra8_err_t priv_exfat_bitmap_clear (const ra8_fs_mount_t *m, uint64_t bmp_lba, uint32_t clus, uint32_t count)
 Clear a contiguous cluster run in the allocation bitmap.
ra8_err_t priv_exfat_zero_cluster (const ra8_fs_mount_t *m, uint32_t clus)
 Zero every sector of one cluster.
ra8_err_t priv_exfat_seal_cluster (const ra8_fs_mount_t *m, uint32_t clus)
 Replace every end-of-directory marker in a cluster with an unused one.
ra8_err_t priv_exfat_find_dir_space (const ra8_fs_mount_t *m, const exfat_dir_t *dir, uint32_t need, uint32_t *out_clus, uint32_t *out_idx)
 Find need consecutive free entry slots inside one directory cluster.
ra8_err_t priv_exfat_drop_set (const ra8_fs_mount_t *m, const exfat_setpos_t *pos, uint32_t count)
 Retire an entry set by clearing the in-use bit on every entry.
ra8_err_t priv_exfat_unlink_at (const ra8_fs_mount_t *m, const exfat_dir_t *dir, const char *name)
 Delete a FILE named name from dir.
ra8_err_t priv_exfat_get_label (const ra8_fs_mount_t *m, char *out, uint32_t out_len)
 Read an exFAT volume's label into an ASCII buffer.
ra8_err_t priv_exfat_set_label (const ra8_fs_mount_t *m, const char *label)
 Set (or clear) an exFAT volume's label in place.

Detailed Description

Cross-TU prototypes of the exFAT DIRECTORY seam.

The adapter's general cross-TU prototypes live in the two alphabetical halves ra8_fs_fat_protos_a_internal.h and ra8_fs_fat_protos_b_internal.h. The helpers declared here are kept apart from those for the same reason the VFAT long-name write seam is: they are one feature rather than one letter range – everything needed to turn exFAT from a flat root-only namespace into a tree (#605). Splitting them out also keeps the two halves inside the 1000-line source cap, which they were already close to.

The seam spans four translation units, so the declarations cannot live in any one of them:

Aggregated by the ra8_fs_fat_internal.h umbrella, like the other themed sub-headers.

Since
0.1.0

Definition in file ra8_fs_fat_exfat_dir_internal.h.

Function Documentation

◆ priv_exfat_bitmap_clear()

ra8_err_t priv_exfat_bitmap_clear ( const ra8_fs_mount_t * m,
uint64_t bmp_lba,
uint32_t clus,
uint32_t count )

Clear a contiguous cluster run in the allocation bitmap.

Mirror of priv_exfat_bitmap_mark: clears one bit per cluster, batching read-modify-write per bitmap sector, and pulls the mount's next-free hint back to the space just released.

Parameters
[in]mMounted exFAT volume.
[in]bmp_lbaFirst LBA (volume-relative) of the bitmap.
[in]clusFirst cluster of the run.
[in]countNumber of clusters to mark free.
Returns
Error code.
Return values
k_ra8_okAll bits cleared and written.
k_ra8_err_*Backend read/write failure.
Precondition
m is non-NULL; the run is within the bitmap.
The entries referencing the run are already retired.
Postcondition
The count bits for the run read as 0.
Only the affected bitmap sectors are rewritten.
Note
Not thread-safe; callers serialise.
Since
0.1.0

Definition at line 28 of file ra8_fs_fat_exfat_mutate.c.

References k_cluster_first_data, k_exfat_bit_mask, k_exfat_bit_shift, k_ra8_ok, priv_alloc_hint_lower(), priv_bps(), priv_exfat_bmp_switch(), priv_sec_io(), and priv_write_sector().

Referenced by priv_exfat_free_clusters(), and priv_exfat_mkdir().

◆ priv_exfat_cursor_init()

void priv_exfat_cursor_init ( const exfat_dir_t * dir,
exfat_cursor_t * out )

Aim a fresh cursor at the start of dir.

Copies the location's first cluster and run bound into the cursor and zeroes the position and scan counters, so every directory walk in the adapter starts the same way instead of open-coding the initialiser.

Parameters
[in]dirDirectory to walk.
[out]outReceives the initialised cursor.
Returns
Nothing.
Precondition
dir and out are non-NULL.
dir was produced by priv_exfat_dir_root or priv_exfat_dir_from_set.
Postcondition
The cursor addresses the directory's first entry.
The cursor's scan counter is 0.
Note
Pure initialisation; trivially thread-safe.
Since
0.1.0

Definition at line 196 of file ra8_fs_fat_exfat_read.c.

References exfat_cursor_t::cluster, exfat_dir_t::cluster, exfat_cursor_t::contig_end, exfat_dir_t::contig_end, exfat_cursor_t::entry_in_cluster, and exfat_cursor_t::scanned.

Referenced by internal_dir_open_locked(), internal_exchk_scan_dir(), internal_exfat_dir_is_empty(), internal_exfat_locate_label(), priv_exfat_find(), priv_exfat_find_bitmap(), priv_exfat_find_set(), and priv_exfat_listdir().

◆ priv_exfat_dir_from_set()

void priv_exfat_dir_from_set ( const ra8_fs_mount_t * m,
const uint8_t * strm,
exfat_dir_t * out )

Build a directory location from a Stream entry's allocation fields.

A FAT-chained directory (nofat == 0) keeps a run bound of 0 and is walked through the FAT. A contiguous one records the cluster one past its last, derived from DataLength – which for an exFAT directory is its ALLOCATION, not a byte count, so the division is exact for every directory this driver writes.

Parameters
[in]mMounted exFAT volume.
[in]strmThe entry set's 32-byte Stream-extension entry.
[out]outReceives the directory location.
Returns
Nothing.
Precondition
m, strm and out are non-NULL.
strm came from priv_exfat_find or priv_exfat_find_set.
Postcondition
out->cluster is the entry's FirstCluster.
out->contig_end is 0, or that cluster plus the run's cluster count.
Note
Pure computation; trivially thread-safe.
Since
0.1.0

Definition at line 183 of file ra8_fs_fat_exfat_read.c.

References exfat_dir_t::cluster, exfat_dir_t::contig_end, k_exfat_secflag_no_fat, k_exfat_strm_off_clus, k_exfat_strm_off_dlen, k_exfat_strm_off_flags, priv_cluster_bytes(), priv_rd32(), and priv_rd64().

Referenced by internal_exchk_set_clusters(), internal_exfat_enter(), and internal_exfat_rmdir_locate().

◆ priv_exfat_dir_root()

void priv_exfat_dir_root ( const ra8_fs_mount_t * m,
exfat_dir_t * out )

Fill out with the volume root's directory location.

The root's first cluster comes from the VBR and its contents are always reached through the FAT – exFAT has no other shape for it – so the run bound is left at 0.

Parameters
[in]mMounted exFAT volume.
[out]outReceives the root's location.
Returns
Nothing.
Precondition
m and out are non-NULL; m->type is exFAT.
The mount carries a parsed VBR.
Postcondition
out->cluster is m->root_cluster.
out->contig_end is 0 (FAT-chained).
Note
Pure accessor; trivially thread-safe.
Since
0.1.0

Definition at line 171 of file ra8_fs_fat_exfat_read.c.

References exfat_dir_t::cluster, exfat_dir_t::contig_end, ra8_fs_mount_t::root_cluster, exfat_dir_t::self_cluster, and exfat_dir_t::self_index.

Referenced by internal_exchk_tree(), internal_exfat_locate_label(), internal_setattr_exfat(), internal_utime_exfat(), priv_exfat_find_bitmap(), priv_exfat_resolve_dir(), and priv_exfat_resolve_parent().

◆ priv_exfat_drop_set()

ra8_err_t priv_exfat_drop_set ( const ra8_fs_mount_t * m,
const exfat_setpos_t * pos,
uint32_t count )

Retire an entry set by clearing the in-use bit on every entry.

exFAT's delete marker is bit 7 of the type byte, so an entry keeps its type and its contents and simply stops being live. Shared by priv_exfat_unlink_at and priv_exfat_rmdir, which differ in what they prove BEFORE reaching this point, not in how they retire a set.

Parameters
[in]mMounted exFAT volume.
[in]posPositions from priv_exfat_find_set.
[in]countNumber of positions.
Returns
Error code.
Return values
k_ra8_okEvery entry rewritten with its in-use bit clear.
k_ra8_err_*Backend read/write failure.
Precondition
m and pos are non-NULL; count is the set's entry count.
pos came from priv_exfat_find_set on this volume.
Postcondition
The name no longer resolves.
No cluster is freed here.
Note
Not thread-safe; callers serialise.
Since
0.1.0

Definition at line 323 of file ra8_fs_fat_exfat_mutate.c.

References exfat_setpos_t::cluster, exfat_setpos_t::index, internal_exfat_put_entry(), k_exfat_entry_bytes, k_exfat_inuse_bit, k_ra8_ok, and priv_exfat_next_entry().

Referenced by internal_exfat_place_rename(), priv_exfat_rmdir(), and priv_exfat_unlink_at().

◆ priv_exfat_find_dir_space()

ra8_err_t priv_exfat_find_dir_space ( const ra8_fs_mount_t * m,
const exfat_dir_t * dir,
uint32_t need,
uint32_t * out_clus,
uint32_t * out_idx )

Find need consecutive free entry slots inside one directory cluster.

Walks dir cluster by cluster, scanning each for a run of reusable slots – end-of-directory markers and retired entries both qualify. A set is never split across two clusters, so the run must fit inside one. When no existing cluster has room, the directory is GROWN one zeroed cluster at a time (priv_exfat_grow_dir) and rescanned, so k_ra8_err_no_mem now means the VOLUME is full, not merely that the directory was (#677). One grow always yields at least k_exfat_set_writable free slots – a fresh cluster holds far more than any set needs – so the retry is bounded by k_exfat_dir_grow_max.

Parameters
[in]mMounted exFAT volume.
[in]dirDirectory to search (its own set location grows it).
[in]needNumber of consecutive free entries required.
[out]out_clusReceives the cluster holding the run.
[out]out_idxReceives the run's first entry index in that cluster.
Returns
Error code.
Return values
k_ra8_okA run was found (after growing, if it had to).
k_ra8_err_no_memThe volume has no free cluster to grow into.
k_ra8_err_*Bitmap or backend read/write failure.
Precondition
Every pointer argument is non-NULL; need >= 1.
m->type is exFAT.
Postcondition
On k_ra8_ok the run location is returned; the directory may be one or more clusters larger than on entry.
On any error no directory slot is reserved.
Note
Not thread-safe; callers serialise.
Since
0.1.0

Definition at line 420 of file ra8_fs_fat_exfat_write.c.

References internal_exfat_scan_dir_space(), k_exfat_dir_grow_max, k_ra8_err_no_mem, k_ra8_ok, and priv_exfat_grow_dir().

Referenced by internal_exfat_place_rename(), priv_exfat_link(), and priv_exfat_mkdir().

◆ priv_exfat_get_label()

ra8_err_t priv_exfat_get_label ( const ra8_fs_mount_t * m,
char * out,
uint32_t out_len )

Read an exFAT volume's label into an ASCII buffer.

Scans the root directory for the Volume Label directory entry (exFAT spec sec 7.7): an in-use entry (type 0x83) yields its UTF-16LE label decoded to ASCII (low byte of each code unit), truncated to out_len; a cleared entry (type 0x03) or no entry at all yields the empty string. The exFAT half of ra8_fs_get_label.

Parameters
[in]mMounted exFAT volume.
[out]outBuffer receiving the NUL-terminated label.
[in]out_lenCapacity of out in bytes (at least 1).
Returns
Error code.
Return values
k_ra8_okout holds the label (possibly empty).
k_ra8_err_*Backend read failure, or a volume with no directory.
Precondition
m and out are non-NULL; m->type is exFAT; out_len >= 1.
The mount is in use.
Postcondition
out is NUL-terminated.
No volume state is modified.
Note
Not thread-safe; callers serialise filesystem operations.
Since
0.1.0

Definition at line 141 of file ra8_fs_fat_exfat_label.c.

References internal_exfat_label_decode(), internal_exfat_locate_label(), k_exfat_entry_bytes, k_exfat_entry_label, and k_ra8_ok.

◆ priv_exfat_lookup()

ra8_err_t priv_exfat_lookup ( const ra8_fs_mount_t * m,
const char * path,
uint8_t * out_strm,
uint8_t * out_attr )

Resolve a path and return the leaf entry set's location fields.

priv_exfat_resolve_parent followed by priv_exfat_find in the resolved directory – the nested-path replacement for what used to be a flat root-level priv_exfat_find on the whole path.

Parameters
[in]mMounted exFAT volume.
[in]pathNUL-terminated path.
[out]out_strmReceives the matched 32-byte Stream-extension entry.
[out]out_attrReceives the FileAttributes low byte.
Returns
Error code.
Return values
k_ra8_okFound; outputs populated.
k_ra8_err_invalid_argpath names the volume root, or a component names a file.
k_ra8_err_not_foundNo such entry.
k_ra8_err_*Backend read failure.
Precondition
Every pointer argument is non-NULL; m->type is exFAT.
The volume is mounted.
Postcondition
On success the outputs describe one on-disk entry set.
No volume state is modified.
Note
Not thread-safe; callers serialise.
Since
0.1.0

Definition at line 212 of file ra8_fs_fat_exfat_dir.c.

References k_ra8_err_invalid_arg, k_ra8_ok, priv_exfat_find(), priv_exfat_resolve_parent(), and priv_strlen().

Referenced by priv_exfat_open().

◆ priv_exfat_mkdir()

ra8_err_t priv_exfat_mkdir ( const ra8_fs_mount_t * m,
const char * path )

Create one exFAT directory at path.

Resolves the parent, refuses a name that already exists, reserves the parent's entry-slot run, allocates and zeroes one cluster, and links a File + Stream + Name set carrying k_exfat_attr_directory. There are no "." / ".." entries to write – exFAT has none – so an all-zero cluster is already a valid empty directory. On a failure after allocation the cluster is returned to the bitmap, so the volume is never leaked.

Parameters
[in]mMounted exFAT volume.
[in]pathNUL-terminated directory path to create.
Returns
Error code.
Return values
k_ra8_okDirectory created.
k_ra8_err_invalid_argThe leaf is empty (the root) or over-long.
k_ra8_err_existsThe name already exists in the parent.
k_ra8_err_not_foundAn intermediate component does not exist.
k_ra8_err_no_memParent directory full, or volume full.
k_ra8_err_*Bitmap or backend failure.
Precondition
m and path are non-NULL; m->type is exFAT.
The parent path exists.
Postcondition
On success path resolves to an empty directory.
On failure no cluster is leaked.
Note
Not thread-safe; callers serialise.
Since
0.1.0

Definition at line 464 of file ra8_fs_fat_exfat_dir.c.

References internal_exfat_build_dir_set(), internal_exfat_dir_alloc(), internal_exfat_mkdir_check(), k_exfat_max_set_bytes, k_exfat_name_cap, k_exfat_name_per_entry, k_ra8_err_invalid_arg, k_ra8_err_no_mem, k_ra8_ok, priv_exfat_bitmap_clear(), priv_exfat_find_dir_space(), priv_exfat_name_to_units(), priv_exfat_resolve_parent(), and priv_exfat_write_dir_set().

◆ priv_exfat_resolve_dir()

ra8_err_t priv_exfat_resolve_dir ( const ra8_fs_mount_t * m,
const char * path,
exfat_dir_t * out )

Resolve a whole path to the directory it names.

"" and "/" are the volume root; anything else is resolved to its parent and then descended into. A trailing slash names the same directory as the path without one.

Parameters
[in]mMounted exFAT volume.
[in]pathNUL-terminated directory path.
[out]outReceives the directory location.
Returns
Error code.
Return values
k_ra8_okResolved; out populated.
k_ra8_err_invalid_argpath names a FILE, or a component does.
k_ra8_err_not_foundA component does not exist.
k_ra8_err_*Backend read failure.
Precondition
m, path and out are non-NULL; m->type is exFAT.
The volume is mounted.
Postcondition
On success out locates an existing directory.
No volume state is modified.
Note
Not thread-safe; callers serialise.
Since
0.1.0

Definition at line 186 of file ra8_fs_fat_exfat_dir.c.

References internal_exfat_enter(), k_ra8_ok, priv_exfat_dir_root(), priv_exfat_resolve_parent(), and priv_strlen().

Referenced by internal_dir_open_locked(), and internal_listdir_locked().

◆ priv_exfat_resolve_parent()

ra8_err_t priv_exfat_resolve_parent ( const ra8_fs_mount_t * m,
const char * path,
exfat_dir_t * out_parent,
const char ** out_leaf )

Resolve every component of path but the last.

Walks the path component by component from the volume root, descending into each intermediate name and requiring it to be a directory, then hands back that directory plus a pointer INTO path at the leaf. Runs of slashes are skipped, so "/a//b" and "a/b" resolve alike, and a trailing slash yields an empty leaf – which each caller rejects or interprets for itself. The exFAT mirror of priv_resolve_parent, and iterative for the same reason: NASA Power of 10 Rule 1 forbids recursion.

Parameters
[in]mMounted exFAT volume.
[in]pathNUL-terminated path.
[out]out_parentReceives the directory holding the leaf.
[out]out_leafReceives a pointer to the leaf within path.
Returns
Error code.
Return values
k_ra8_okResolved; outputs populated.
k_ra8_err_invalid_argA component names a FILE, is over-long, or the path is deeper than k_exfat_path_depth.
k_ra8_err_not_foundAn intermediate component does not exist.
k_ra8_err_protocol_errorA directory entry claims no data cluster.
k_ra8_err_*Backend read failure.
Precondition
Every pointer argument is non-NULL; m->type is exFAT.
path outlives the returned leaf pointer.
Postcondition
On success *out_leaf points into path.
No volume state is modified.
Note
Not thread-safe; callers serialise.
Since
0.1.0

Definition at line 145 of file ra8_fs_fat_exfat_dir.c.

References internal_exfat_enter(), k_exfat_path_depth, k_ra8_err_invalid_arg, k_ra8_ok, and priv_exfat_dir_root().

Referenced by internal_exfat_rename_prepare(), internal_exfat_rmdir_locate(), internal_stat_exfat(), priv_exfat_lookup(), priv_exfat_mkdir(), priv_exfat_open_write(), priv_exfat_resolve_dir(), and priv_exfat_unlink().

◆ priv_exfat_rmdir()

ra8_err_t priv_exfat_rmdir ( const ra8_fs_mount_t * m,
const char * path )

Remove one EMPTY exFAT directory at path.

Locates the entry set, requires it to be a directory, proves the directory holds no live entry, then clears the in-use bit on every entry of the set and frees its clusters in the allocation bitmap. The emptiness proof runs before anything is written, so a refused removal changes nothing on disk.

Parameters
[in]mMounted exFAT volume.
[in]pathNUL-terminated directory path to remove.
Returns
Error code.
Return values
k_ra8_okDirectory removed.
k_ra8_err_invalid_argpath is the root, or names a FILE.
k_ra8_err_not_foundNo such entry, or a component is missing.
k_ra8_err_not_emptyThe directory still holds entries.
k_ra8_err_protocol_errorThe entry claims no data cluster.
k_ra8_err_*Bitmap or backend failure.
Precondition
m and path are non-NULL; m->type is exFAT.
No open file handle refers to an entry inside path.
Postcondition
On success path no longer resolves and its clusters are free.
On any refusal the volume is unchanged.
Note
Not thread-safe; callers serialise.
Since
0.1.0

Definition at line 654 of file ra8_fs_fat_exfat_dir.c.

References internal_exfat_dir_is_empty(), internal_exfat_rmdir_locate(), k_exfat_entry_bytes, k_exfat_set_max_entries, k_ra8_err_not_empty, k_ra8_ok, priv_exfat_drop_set(), and priv_exfat_free_clusters().

◆ priv_exfat_seal_cluster()

ra8_err_t priv_exfat_seal_cluster ( const ra8_fs_mount_t * m,
uint32_t clus )

Replace every end-of-directory marker in a cluster with an unused one.

The subtlety that makes directory growth correct. exFAT spec sec 6.3.1: an entry type of 0x00 is EndOfDirectory, and NO entry past the first one may be anything else – a reader (and fsck.exfat) stops there. This driver never splits an entry set across a cluster, so the cluster that was the directory's tail is left with a run of trailing 0x00 slots, and once a grown cluster holds live entries AFTER it those 0x00 slots are a premature end that hides everything beyond them.

Rewriting each 0x00 in the old tail to a DELETED File type (0x85 with the in-use bit clear) keeps it a legal, skippable "unused" entry – which the walk steps over and the free-slot scan still calls free – while moving the one real EndOfDirectory to the trailing zeros of the freshly appended cluster, where the format requires it to be. Paired with priv_exfat_zero_cluster on the directory grow path (#677).

Parameters
[in]mMounted exFAT volume.
[in]clusCluster whose end-of-directory markers are to be retired.
Returns
Error code.
Return values
k_ra8_okEvery 0x00 slot in the cluster now reads as unused.
k_ra8_err_*Backend read/write failure.
Precondition
m is non-NULL; clus is a directory cluster of this volume.
No live entry set follows a 0x00 slot within clus (this driver's append-only invariant).
Postcondition
clus holds no 0x00 slot; the walk continues into the next cluster.
Only the sectors that held a 0x00 slot are rewritten.
Note
Not thread-safe; callers serialise filesystem operations.
Since
0.1.0

Definition at line 245 of file ra8_fs_fat_exfat_dir.c.

References k_exfat_entry_bytes, k_exfat_entry_eod, k_exfat_entry_file, k_exfat_inuse_bit, k_ra8_ok, priv_bps(), priv_cluster_to_lba(), priv_read_sector(), priv_sec_io(), priv_write_sector(), and ra8_fs_mount_t::sectors_per_cluster.

Referenced by internal_exfat_dir_append().

◆ priv_exfat_set_label()

ra8_err_t priv_exfat_set_label ( const ra8_fs_mount_t * m,
const char * label )

Set (or clear) an exFAT volume's label in place.

Rewrites the root Volume Label directory entry (exFAT spec sec 7.7) with the new UTF-16LE label and character count, creating one at the end-of-directory position when the volume carries none. A NULL or empty label writes a zero-length label entry (the unlabelled form). The exFAT half of ra8_fs_set_label.

Parameters
[in]mMounted exFAT volume.
[in]labelNew label (<= 11 characters), or NULL / "" to clear it.
Returns
Error code.
Return values
k_ra8_okLabel written.
k_ra8_err_not_foundThe root directory could not be scanned.
k_ra8_err_*Backend read/write failure.
Precondition
m is non-NULL; m->type is exFAT; the mount is in use.
label, when non-NULL, is at most 11 characters.
Postcondition
On success a later priv_exfat_get_label reports label.
Only the Volume Label entry is modified.
Note
Not thread-safe; callers serialise filesystem operations.
Since
0.1.0

Definition at line 159 of file ra8_fs_fat_exfat_label.c.

References exfat_setpos_t::cluster, exfat_setpos_t::index, internal_exfat_locate_label(), k_exfat_de_lbl_cnt, k_exfat_de_lbl_name, k_exfat_entry_bytes, k_exfat_entry_label, k_exfat_fmt_label_max, k_ra8_ok, and priv_exfat_write_dir_set().

◆ priv_exfat_step_cluster()

ra8_err_t priv_exfat_step_cluster ( const ra8_fs_mount_t * m,
uint32_t cluster,
uint32_t contig_end,
uint32_t * out_next )

Compute the cluster that follows cluster in a directory.

Two shapes, one answer. A FAT-chained directory (the volume root, or a subdirectory some other implementation grew) follows priv_fat_get and stops at end-of-chain. A contiguous run – what this driver creates, with NoFatChain set – steps to the adjacent cluster and stops at contig_end. Following the FAT for a NoFatChain run is not merely redundant: the exFAT specification declares those FAT entries invalid, and the ones this driver leaves behind read as 0 (free), which priv_is_eoc does not call end-of-chain, so the walk would continue into cluster 0.

Parameters
[in]mMounted exFAT volume.
[in]clusterThe directory's current cluster.
[in]contig_endOne past the run's last cluster; 0 => follow the FAT.
[out]out_nextReceives the successor cluster.
Returns
Error code.
Return values
k_ra8_ok*out_next is the next cluster.
k_ra8_err_not_foundThe directory ends here.
k_ra8_err_*FAT read failure.
Precondition
m and out_next are non-NULL.
cluster belongs to the directory being walked.
Postcondition
On k_ra8_ok *out_next addresses a heap cluster.
No volume state is modified.
Note
Not thread-safe; callers serialise.
MC/DC:
Decision: contig_end != 0 (1 condition).
  • a subdirectory created here (NoFatChain) -> true -> step to cluster + 1.
  • the volume root (FAT-chained) -> false -> follow the FAT. Decision: adjacent >= contig_end (1 condition), reached only on the true arm above.
  • the last cluster of the run -> true -> the directory ends.
  • a run of two or more clusters -> false -> the adjacent cluster.
Since
0.1.0

Definition at line 205 of file ra8_fs_fat_exfat_read.c.

References k_ra8_err_not_found, k_ra8_ok, priv_fat_get(), and priv_is_eoc().

Referenced by internal_exchk_mark_dir_alloc(), internal_exfat_scan_dir_space(), and priv_exfat_next_entry().

◆ priv_exfat_unlink_at()

ra8_err_t priv_exfat_unlink_at ( const ra8_fs_mount_t * m,
const exfat_dir_t * dir,
const char * name )

Delete a FILE named name from dir.

The directory-scoped half of priv_exfat_unlink: locates the entry set, refuses one carrying k_exfat_attr_directory, retires it and frees its clusters. ::priv_exfat_create calls it directly, having already resolved the parent, so a create-over-an-existing-name replaces rather than duplicates (#603).

Parameters
[in]mMounted exFAT volume.
[in]dirDirectory holding the name.
[in]nameLeaf name (ASCII).
Returns
Error code.
Return values
k_ra8_okFile deleted.
k_ra8_err_invalid_argname is a DIRECTORY; rmdir is the verb.
k_ra8_err_not_foundNo such name in dir.
k_ra8_err_*Bitmap or backend failure.
Precondition
m, dir and name are non-NULL; m->type is exFAT.
No open file handle refers to the name.
Postcondition
On success the name no longer resolves and its clusters are free.
On k_ra8_err_invalid_arg the volume is unchanged.
Note
Not thread-safe; callers serialise.
Since
0.1.0

Definition at line 347 of file ra8_fs_fat_exfat_mutate.c.

References k_exfat_attr_directory, k_exfat_attr_read_only, k_exfat_entry_bytes, k_exfat_off_file_attr, k_exfat_set_max_entries, k_ra8_err_access_denied, k_ra8_err_invalid_arg, k_ra8_ok, priv_exfat_drop_set(), priv_exfat_find_set(), and priv_exfat_free_clusters().

Referenced by priv_exfat_unlink().

◆ priv_exfat_zero_cluster()

ra8_err_t priv_exfat_zero_cluster ( const ra8_fs_mount_t * m,
uint32_t clus )

Zero every sector of one cluster.

An all-zero exFAT directory cluster is a valid EMPTY directory: the first entry's type byte is 0x00, which is the end-of-directory marker. There are no "." / ".." entries to stamp – exFAT has none. Used both to initialise a directory's first cluster (mkdir) and to initialise each cluster growth appends to it (#677).

Parameters
[in]mMounted exFAT volume.
[in]clusCluster to clear.
Returns
Error code.
Return values
k_ra8_okEvery sector of the cluster reads as zero.
k_ra8_err_*Backend write failure.
Precondition
m is non-NULL; clus is a heap cluster.
The cluster is not referenced by any entry set yet.
Postcondition
On success the cluster is an empty exFAT directory.
No bitmap or directory state is modified here.
Note
Not thread-safe; callers serialise.
Since
0.1.0

Definition at line 232 of file ra8_fs_fat_exfat_dir.c.

References k_ra8_ok, k_zero_sector, priv_cluster_to_lba(), priv_write_sector(), and ra8_fs_mount_t::sectors_per_cluster.

Referenced by internal_exfat_dir_alloc(), and internal_exfat_dir_append().