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

FAT listdir / unlink / rename directory-entry operations. More...

#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "ra8_attributes.h"
#include "ra8_fs.h"
#include "ra8_fs_fat_internal.h"
Include dependency graph for ra8_fs_fat_dir.c:

Go to the source code of this file.

Data Structures

struct  ra8_fs_dir_private_t
 Private state stored inside one public opaque directory cursor. More...

Functions

static uint8_t internal_listdir_visit_sector (const ra8_fs_mount_t *m, const uint8_t *buf, lfn_state_t *lfn, ra8_fs_listdir_cb_t cb, void *ctx)
 Visit every visible entry in one already-loaded directory sector.
static ra8_err_t internal_listdir_locked (const ra8_fs_mount_t *handle, const char *path, ra8_fs_listdir_cb_t cb, void *ctx)
 Enumerate a directory – the guarded body of ra8_fs_listdir().
static ra8_err_t internal_fat_dir_advance_sector (ra8_fs_dir_private_t *state)
 Advance an independent FAT cursor to its next directory sector.
static void internal_fat_dir_scan_sector (ra8_fs_dir_private_t *state, const uint8_t *sector, ra8_fs_dirent_t *out, bool *out_entry)
 Scan one already-read sector's remaining entries for one visible entry.
static ra8_err_t internal_fat_dir_next (ra8_fs_dir_private_t *state, ra8_fs_dirent_t *out, bool *out_entry)
 Copy one visible FAT entry from an independent cursor.
static ra8_err_t internal_dir_open_locked (ra8_fs_mount_t *handle, const char *path, ra8_fs_dir_private_t *state)
 Resolve and initialize one private filesystem cursor.
static ra8_err_t internal_unlink_locate (const ra8_fs_mount_t *handle, const char *path, dir_target_t *out, uint32_t *out_cluster)
 Resolve a path to a deletable FILE's entry and first cluster.
static ra8_err_t internal_unlink_locked (const ra8_fs_mount_t *handle, const char *path)
 Delete a file – the guarded body of ra8_fs_unlink().
static ra8_err_t internal_rename_prepare (const ra8_fs_mount_t *handle, const char *old_path, const char *new_path, dir_loc_t *out_parent, const char **out_old, const char **out_new)
 Resolve a rename's old/new paths to a shared parent and two leaves.
static ra8_err_t internal_fat_rename (const ra8_fs_mount_t *handle, const char *old_path, const char *new_path)
 Rename by writing the new entry first, then taking the old one away.
static ra8_err_t internal_rename_locked (const ra8_fs_mount_t *handle, const char *old_path, const char *new_path)
 Rename – the guarded body of ra8_fs_rename().
ra8_err_t ra8_fs_listdir (const ra8_fs_mount_t *handle, const char *path, ra8_fs_listdir_cb_t cb, void *ctx)
 Enumerate directory entries; invoke cb once per visible entry.
ra8_err_t ra8_fs_dir_open (ra8_fs_mount_t *handle, const char *path, ra8_fs_dir_t *directory)
 Open a caller-owned directory cursor without holding the filesystem lock.
ra8_err_t ra8_fs_dir_next (ra8_fs_dir_t *directory, ra8_fs_dirent_t *out, bool *out_entry)
 Copy the next visible directory entry.
ra8_err_t ra8_fs_dir_close (ra8_fs_dir_t *directory)
 Consume one open directory cursor.
ra8_err_t ra8_fs_unlink (const ra8_fs_mount_t *handle, const char *path)
 Delete a file: mark its dir entry deleted and free its clusters.
ra8_err_t ra8_fs_rename (const ra8_fs_mount_t *handle, const char *old_path, const char *new_path)
 Rename a file within its own directory.

Detailed Description

FAT listdir / unlink / rename directory-entry operations.

The verbs that read and rewrite entries in a directory that already exists: listing it, deleting a file from it, and renaming one in place, dispatched across FAT and exFAT volumes. unlink refuses a directory – freeing the cluster chain behind one orphans every file inside it (#604); removing a directory is rmdir's job, in ra8_fs_fat_dirmk.c.

Since
0.1.0

Definition in file ra8_fs_fat_dir.c.

Function Documentation

◆ internal_dir_open_locked()

ra8_err_t internal_dir_open_locked ( ra8_fs_mount_t * handle,
const char * path,
ra8_fs_dir_private_t * state )
static

Resolve and initialize one private filesystem cursor.

Selects FAT or exFAT path resolution from the mounted format and initializes only the matching caller-owned walk state.

Parameters
[in,out]handleMounted filesystem.
[in]pathDirectory path.
[out]stateZeroed private cursor state.
Returns
Resolution or mount status.
Return values
k_ra8_okOne format-specific cursor is ready.
k_ra8_err_invalid_stateThe mount is not active.
k_ra8_err_*Path resolution or media failure.
Precondition
Required pointers are non-NULL and the filesystem lock is held.
state addresses writable private cursor storage.
Postcondition
Success initializes exactly one format-specific cursor.
Failure publishes no open public cursor handle.
Note
No resource remains locked after the public wrapper returns.
Since
0.1.0

Definition at line 366 of file ra8_fs_fat_dir.c.

References internal_dir_open_locked(), k_ra8_fs_type_exfat, k_ra8_ok, priv_exfat_cursor_init(), and priv_exfat_resolve_dir().

Referenced by internal_dir_open_locked(), and ra8_fs_dir_open().

◆ internal_fat_dir_advance_sector()

ra8_err_t internal_fat_dir_advance_sector ( ra8_fs_dir_private_t * state)
static

Advance an independent FAT cursor to its next directory sector.

Delegates the format-specific sector walk and records clean end in the stable cursor before returning the walk result.

Parameters
[in,out]stateOpen private FAT cursor state.
Returns
Sector-walk status.
Return values
k_ra8_okThe cursor advanced or reached clean end.
k_ra8_err_*Media, chain, or directory-walk failure.
Precondition
state is non-NULL and the filesystem lock is held.
state was initialized for a mounted FAT volume.
Postcondition
The sector walk advances according to the underlying FAT chain.
Clean end sets state->finished before this function returns.
Note
An error is returned unchanged even when the walker also reports end.
Since
0.1.0

Definition at line 225 of file ra8_fs_fat_dir.c.

References internal_fat_dir_advance_sector(), priv_dir_walk_next_sector(), and RA8_INTERNAL.

Referenced by internal_fat_dir_advance_sector().

◆ internal_fat_dir_next()

ra8_err_t internal_fat_dir_next ( ra8_fs_dir_private_t * state,
ra8_fs_dirent_t * out,
bool * out_entry )
static

Copy one visible FAT entry from an independent cursor.

Walks bounded directory sectors, assembles valid LFN fragments, and copies one stable name/attribute/size value per successful step.

Parameters
[in,out]stateOpen private cursor state.
[out]outStable copied entry value.
[out]out_entryTrue for one copied entry; false at clean end.
Returns
Media, corruption, or clean-end status.
Return values
k_ra8_okOne entry was copied or clean end was reached.
k_ra8_err_*Sector-walk or media-read failure.
Precondition
Required pointers are non-NULL and the filesystem lock is held.
state was initialized for a mounted FAT volume.
Postcondition
The cursor advances monotonically and out never borrows sector scratch.
Clean end leaves out_entry false without publishing scratch bytes.
Note
A sector is re-read on a later call; total work remains linear in entries.
Since
0.1.0

Definition at line 320 of file ra8_fs_fat_dir.c.

References internal_fat_dir_next(), internal_fat_dir_scan_sector(), k_ra8_ok, priv_read_sector(), and priv_sec_walk().

Referenced by internal_fat_dir_next(), and ra8_fs_dir_next().

◆ internal_fat_dir_scan_sector()

void internal_fat_dir_scan_sector ( ra8_fs_dir_private_t * state,
const uint8_t * sector,
ra8_fs_dirent_t * out,
bool * out_entry )
static

Scan one already-read sector's remaining entries for one visible entry.

Advances the entry cursor across free/used/LFN/dot entries, assembling valid LFN fragments, until a visible entry is copied, the directory's end marker is found, or the sector is exhausted.

Parameters
[in,out]stateOpen private cursor state.
[in]sectorBytes of the already-read directory sector.
[out]outStable copied entry value.
[out]out_entryTrue when one entry was copied into out.
Returns
Nothing.
Precondition
sector holds priv_bps(state->mount) valid bytes.
state->fat_walk.entry_idx indexes within sector.
Postcondition
One of: an entry was copied (*out_entry true), the directory's end marker was found (state->finished true), or the sector was exhausted so the caller must advance to the next one.
state->fat_walk.entry_idx advanced past every entry inspected in sector.
Note
Not thread-safe; caller holds the filesystem lock.
Since
0.1.0

Definition at line 255 of file ra8_fs_fat_dir.c.

References internal_fat_dir_scan_sector(), k_dir_marker_dot, k_dir_marker_free_used, k_dir_off_attr, k_dir_off_file_size, k_dir_off_name, k_dir_off_ntres, k_lfn_utf8_cap, k_ra8_fs_attr_lfn, k_ra8_fs_short_name_len, k_ra8_ok, memcpy(), priv_83_to_str(), priv_bps(), priv_lfn_add(), priv_lfn_reset(), priv_lfn_units_for(), priv_rd32(), priv_utf16_to_utf8(), RA8_INTERNAL, and strlen().

Referenced by internal_fat_dir_next(), and internal_fat_dir_scan_sector().

◆ internal_fat_rename()

ra8_err_t internal_fat_rename ( const ra8_fs_mount_t * handle,
const char * old_path,
const char * new_path )
static

Rename by writing the new entry first, then taking the old one away.

Rewriting the 11-byte name field in place, which is what this used to do, cannot be right once long names exist: the entry may be the tail of a VFAT chain that still spells the OLD name, and the new name may not fit eleven bytes at all. So the entry is re-filed – the old 32 bytes are carried across verbatim as the template, so the cluster, the size and the attributes survive, and only the name and its DIR_NTRes flags change.

The order is deliberate. Committing the new entry BEFORE erasing the old one means a failure between them leaves the file reachable under both names – untidy, but nothing is lost. The reverse order would put a window in the middle of the operation where the file has no name at all.

Parameters
[in]handleMounted FAT12/16/32 volume.
[in]old_pathExisting path.
[in]new_pathReplacement path (must not exist; same directory).
Returns
Error code.
Return values
k_ra8_okRenamed; the old name is gone, the new resolves.
k_ra8_err_invalid_argThe new leaf cannot be stored under any encoding.
k_ra8_err_not_foundold_path does not exist.
k_ra8_err_existsnew_path already resolves to an entry.
k_ra8_err_not_supportedThe two paths are in different directories.
k_ra8_err_no_memThe directory has no room for the new entry.
k_ra8_err_*Backend read/write error.
Precondition
handle and both path pointers are non-NULL; handle is a mounted FAT volume.
Neither old_path nor new_path is currently held open.
Postcondition
On k_ra8_ok, new_path resolves to the same cluster, size and attributes.
On k_ra8_ok, old_path no longer resolves and its chain is gone with it.
Note
Not thread-safe; callers serialise access to the mount.
Since
0.1.0

Definition at line 619 of file ra8_fs_fat_dir.c.

References dir_target_t::entry, internal_rename_prepare(), k_dir_off_attr, k_dir_off_name, k_ra8_err_access_denied, k_ra8_err_exists, k_ra8_fs_attr_read_only, k_ra8_fs_dir_entry_bytes, k_ra8_ok, dir_target_t::lba, dir_target_t::off, dir_target_t::parent, priv_dir_commit(), priv_dir_erase_chain(), priv_dir_lookup_any(), priv_dir_reserve(), and priv_fat_entry_stamp_access().

Referenced by internal_rename_locked().

◆ internal_listdir_locked()

ra8_err_t internal_listdir_locked ( const ra8_fs_mount_t * handle,
const char * path,
ra8_fs_listdir_cb_t cb,
void * ctx )
static

Enumerate a directory – the guarded body of ra8_fs_listdir().

Resolves path to a directory – priv_resolve_dir on FAT, priv_exfat_resolve_dir on exFAT – and walks it, invoking cb once per visible entry. Both filesystems take "/" or a nested path. FAT's synthetic "." and ".." entries are not reported; exFAT has none to report.

Parameters
[in,out]handleMount handle.
[in]pathDirectory path ("/" or a nested path).
[in]cbPer-entry callback.
[in]ctxOpaque pointer forwarded to cb.
Returns
Error code.
Return values
k_ra8_okDirectory walked successfully.
k_ra8_err_null_ptrAny required pointer was NULL.
k_ra8_err_invalid_stateMount not in use.
k_ra8_err_not_foundA path component does not exist.
k_ra8_err_invalid_argA path component names a file.
k_ra8_err_*Backend error.
Precondition
The library lock is held (or none is installed).
handle, path, and cb are non-NULL.
Mount is in use.
Postcondition
cb invoked once per visible directory entry.
No on-disk state modified.
Note
Not thread-safe; callers serialise.
Since
0.1.0

Definition at line 159 of file ra8_fs_fat_dir.c.

References internal_listdir_locked(), k_ra8_err_null_ptr, k_ra8_fs_type_exfat, k_ra8_ok, priv_exfat_listdir(), and priv_exfat_resolve_dir().

Referenced by internal_listdir_locked(), and ra8_fs_listdir().

◆ internal_listdir_visit_sector()

uint8_t internal_listdir_visit_sector ( const ra8_fs_mount_t * m,
const uint8_t * buf,
lfn_state_t * lfn,
ra8_fs_listdir_cb_t cb,
void * ctx )
static

Visit every visible entry in one already-loaded directory sector.

Skips deleted (0xE5) and LFN (attr 0x0F) entries and the synthetic "." / ".." directory entries. Stops on the end-of-directory marker (0x00).

Parameters
[in]mMounted volume (supplies the entries-per-sector bound).
[in]bufWhole-sector buffer holding directory entries.
[in,out]lfnLFN reassembly state carried across sectors.
[in]cbCaller-supplied per-entry callback.
[in]ctxOpaque pointer forwarded to cb.
Returns
1 if end-of-directory marker hit (caller can stop), 0 otherwise.
Return values
1End-of-directory reached; caller should stop.
0Sector exhausted without end-of-directory.
Precondition
buf and cb are non-NULL.
buf holds a sector loaded from disk.
Postcondition
No state modified by this function (callback may modify ctx).
cb invoked once per visible entry.
Note
Thread-safety inherited from cb.
Since
0.1.0

Definition at line 71 of file ra8_fs_fat_dir.c.

References k_dir_marker_dot, k_dir_marker_free_perm, k_dir_marker_free_used, k_dir_off_attr, k_dir_off_file_size, k_dir_off_name, k_dir_off_ntres, k_lfn_utf8_cap, k_ra8_fs_attr_lfn, k_ra8_fs_dir_entry_bytes, k_ra8_fs_short_name_len, k_ra8_ok, priv_83_to_str(), priv_dir_eps(), priv_lfn_add(), priv_lfn_reset(), priv_lfn_units_for(), priv_rd32(), and priv_utf16_to_utf8().

◆ internal_rename_locked()

ra8_err_t internal_rename_locked ( const ra8_fs_mount_t * handle,
const char * old_path,
const char * new_path )
static

Rename – the guarded body of ra8_fs_rename().

See the public header for the documented contract; dispatches to the FAT re-filing path or the exFAT entry-set rewrite.

Parameters
[in]handleSee header.
[in]old_pathSee header.
[in]new_pathSee header.
Returns
Result code.
Return values
k_ra8_okFile renamed.
Precondition
The library lock is held (or none is installed).
The volume is mounted.
Postcondition
On success the new name resolves to the same data.
On failure the directory is unchanged.
Note
Not thread-safe.
Since
0.1.0

Definition at line 684 of file ra8_fs_fat_dir.c.

References internal_fat_rename(), internal_rename_locked(), k_ra8_err_null_ptr, and k_ra8_fs_type_exfat.

Referenced by internal_rename_locked(), and ra8_fs_rename().

◆ internal_rename_prepare()

ra8_err_t internal_rename_prepare ( const ra8_fs_mount_t * handle,
const char * old_path,
const char * new_path,
dir_loc_t * out_parent,
const char ** out_old,
const char ** out_new )
static

Resolve a rename's old/new paths to a shared parent and two leaves.

Resolves both parents and requires them to be the same directory: an in-place rename cannot move an entry between directories. The leaf components are handed back unpacked, because whether either of them is an 8.3 name is no longer the rename's business – the reservation decides that, and both sides may be long names.

Parameters
[in]handleMounted FAT volume.
[in]old_pathExisting path.
[in]new_pathReplacement path (same directory).
[out]out_parentReceives the shared parent directory location.
[out]out_oldReceives a pointer into old_path at its leaf.
[out]out_newReceives a pointer into new_path at its leaf.
Returns
Error code.
Return values
k_ra8_okResolved; outputs populated.
k_ra8_err_not_supportedThe two paths are in different directories.
k_ra8_err_*Resolution / backend error.
Precondition
All pointer arguments are non-NULL.
Both paths outlive the outputs, which point into them.
Postcondition
On success both leaves and out_parent are set.
On failure the outputs are unspecified.
Note
Not thread-safe; callers serialise.
Since
0.1.0

Definition at line 545 of file ra8_fs_fat_dir.c.

References dir_loc_t::cluster, dir_loc_t::is_root, k_ra8_err_not_supported, k_ra8_ok, and priv_resolve_parent().

Referenced by internal_fat_rename().

◆ internal_unlink_locate()

ra8_err_t internal_unlink_locate ( const ra8_fs_mount_t * handle,
const char * path,
dir_target_t * out,
uint32_t * out_cluster )
static

Resolve a path to a deletable FILE's entry and first cluster.

Resolves the parent, packs the leaf to 8.3, looks it up, and requires the matched entry NOT to carry k_ra8_fs_attr_directory. The mirror image of priv_rmdir_locate(): each verb refuses the kind of entry the other owns, and both refuse before anything is freed. Split out of ra8_fs_unlink so it stays inside the function-size gate.

Parameters
[in]handleMounted FAT12/16/32 volume.
[in]pathFile path to delete.
[out]outReceives the parent, the entry position and the entry.
[out]out_clusterThe file's first cluster (0 when it has none).
Returns
Error code.
Return values
k_ra8_okLocated; outputs populated.
k_ra8_err_invalid_argpath is unstorable, or names a directory.
k_ra8_err_not_foundNo such entry.
k_ra8_err_*Backend error.
Precondition
All pointers are non-NULL; handle is a mounted FAT volume.
handle->type is not exFAT (the caller has dispatched already).
Postcondition
On success the outputs address a file entry on disk.
No on-disk state is modified.
Note
Not thread-safe; callers serialise.
Since
0.1.0

Definition at line 421 of file ra8_fs_fat_dir.c.

References dir_target_t::entry, k_dir_off_attr, k_ra8_err_access_denied, k_ra8_err_invalid_arg, k_ra8_fs_attr_directory, k_ra8_fs_attr_read_only, k_ra8_ok, dir_target_t::lba, dir_target_t::off, dir_target_t::parent, priv_dir_lookup_any(), priv_entry_first_cluster(), and priv_resolve_parent().

Referenced by internal_unlink_locked().

◆ internal_unlink_locked()

ra8_err_t internal_unlink_locked ( const ra8_fs_mount_t * handle,
const char * path )
static

Delete a file – the guarded body of ra8_fs_unlink().

Frees the cluster chain (if any) and marks the dir entry deleted by writing 0xE5 to the first byte of the name field. Refuses a directory: use ra8_fs_rmdir() for those.

Parameters
[in]handleMount handle.
[in]pathNUL-terminated path; only flat root names supported.
Returns
Error code.
Return values
k_ra8_okFile deleted.
k_ra8_err_null_ptrAny pointer was NULL.
k_ra8_err_invalid_stateMount not in use.
k_ra8_err_invalid_argPath is not a valid 8.3 name, or it names a directory.
k_ra8_err_not_foundNo such file.
k_ra8_err_*Backend or FAT error.
Precondition
The library lock is held (or none is installed).
handle and path are non-NULL.
Mount is in use; no file handle currently references this entry.
Postcondition
On success, file's clusters are free and dir entry is deleted.
On failure, on-disk state may be partially updated.
A path naming a directory leaves the volume untouched.
Note
Not thread-safe; callers serialise.
Since
0.1.0

Definition at line 485 of file ra8_fs_fat_dir.c.

References internal_unlink_locate(), internal_unlink_locked(), k_cluster_first_data, k_dir_off_name, k_ra8_err_null_ptr, k_ra8_fs_type_exfat, k_ra8_ok, priv_dir_erase_chain(), and priv_free_chain().

Referenced by internal_unlink_locked(), and ra8_fs_unlink().

◆ ra8_fs_dir_close()

ra8_err_t ra8_fs_dir_close ( ra8_fs_dir_t * directory)
nodiscard

Consume one open directory cursor.

Parameters
[in,out]directoryOpen caller-owned cursor.
Returns
Lifecycle status.
Postcondition
Success clears all cursor state; no backend resource remains owned.
Since
0.1.0

Definition at line 786 of file ra8_fs_fat_dir.c.

References ra8_fs_dir_t::is_open, k_ra8_err_invalid_state, k_ra8_err_null_ptr, and k_ra8_ok.

Referenced by internal_native_dir_close(), and internal_native_listdir().

◆ ra8_fs_dir_next()

ra8_err_t ra8_fs_dir_next ( ra8_fs_dir_t * directory,
ra8_fs_dirent_t * out,
bool * out_entry )
nodiscard

Copy the next visible directory entry.

Parameters
[in,out]directoryOpen caller-owned cursor.
[out]outStable entry value owned by the caller.
[out]out_entryTrue when out is populated; false at clean EOF.
Returns
Media, corruption, or lifecycle status.
Precondition
Required pointers are non-NULL and no forbidden directory mutation occurred.
Postcondition
No filesystem lock remains held; out survives later cursor calls.
Since
0.1.0

Definition at line 748 of file ra8_fs_fat_dir.c.

References internal_fat_dir_next(), k_ra8_err_invalid_state, k_ra8_err_null_ptr, k_ra8_fs_type_exfat, k_ra8_ok, priv_exfat_dir_next(), priv_lock_acquire(), priv_lock_release(), and ra8_fs_dir_next().

Referenced by internal_native_dir_next(), internal_native_listdir(), and ra8_fs_dir_next().

◆ ra8_fs_dir_open()

ra8_err_t ra8_fs_dir_open ( ra8_fs_mount_t * handle,
const char * path,
ra8_fs_dir_t * directory )
nodiscard

Open a caller-owned directory cursor without holding the filesystem lock.

Path resolution is locked only for this call. Each later next reacquires and releases the lock, so client metadata and stream operations are valid between entries. Two cursor objects advance independently. The enumerated directory and its ancestors must not be mutated until close; mutation elsewhere is permitted.

Parameters
[in,out]handleMounted filesystem.
[in]pathDirectory path.
[out]directoryIdle caller-owned cursor.
Returns
Path, mount, or lifecycle status.
Return values
k_ra8_okCursor opened.
k_ra8_err_busydirectory is already open.
Precondition
Required pointers are non-NULL and handle is mounted.
Postcondition
Success leaves no filesystem lock held.
Since
0.1.0

Definition at line 720 of file ra8_fs_fat_dir.c.

References internal_dir_open_locked(), k_ra8_err_null_ptr, k_ra8_ok, memset(), priv_lock_acquire(), priv_lock_release(), and ra8_fs_dir_open().

Referenced by internal_native_dir_open(), internal_native_listdir(), and ra8_fs_dir_open().

◆ ra8_fs_listdir()

ra8_err_t ra8_fs_listdir ( const ra8_fs_mount_t * handle,
const char * path,
ra8_fs_listdir_cb_t cb,
void * ctx )
nodiscard

Enumerate directory entries; invoke cb once per visible entry.

Every supported filesystem enumerates any directory by path ("/" for the root, "/books" for a subdirectory) – exFAT included since #605. FAT's synthetic "." and ".." entries are not reported; exFAT has none to report. A subdirectory appears in its parent's listing like any other entry, with the directory bit set in the attr argument.

Parameters
[in]handleMount handle.
[in]pathDirectory path ("/" or a nested path).
[in]cbCallback (must be non-NULL).
[in]ctxCookie forwarded to the callback.
Return values
k_ra8_okEnumeration complete.
k_ra8_err_null_ptrhandle/cb NULL.
k_ra8_err_not_foundA path component does not exist.
k_ra8_err_invalid_argA path component names a file.
Since
0.1.0

Definition at line 711 of file ra8_fs_fat_dir.c.

References internal_listdir_locked(), priv_lock_acquire(), priv_lock_release(), and ra8_fs_listdir().

Referenced by demo_file_ops(), fileops_step_listdir(), fs_fmt_assert_empty_root(), ra8_fs_listdir(), and sh_sd_scan().

◆ ra8_fs_rename()

ra8_err_t ra8_fs_rename ( const ra8_fs_mount_t * handle,
const char * old_path,
const char * new_path )
nodiscard

Rename a file within its own directory.

FAT12/16/32: re-files the entry under the new name – writing the new entry (with its long-name chain, if the new name needs one) before taking the old one away, so a failure between the two leaves the file reachable under both names rather than under neither. The cluster, the size and the attributes are carried across unchanged. Legacy note: this used to rewrite the 11-byte packed 8.3 name in the existing directory entry. exFAT: patches the Stream entry's NameLength and NameHash, rebuilds the Name entry, and recomputes the SetChecksum – supported when both names fit one Name entry (<= 15 characters), which keeps the entry-set length unchanged. Data clusters never move.

The LAST-ACCESS stamp advances; the modification stamp deliberately does not. A rename changes the name, not the bytes, so moving the modification time would tell every rsync, backup and "pick the newest image" heuristic that the contents changed. Neither format has a metadata-change field, so the access stamp is the honest record that the entry was touched.

Parameters
[in]handleMount handle.
[in]old_pathExisting path.
[in]new_pathReplacement path, in the same directory (must not already exist).
Return values
k_ra8_okFile renamed.
k_ra8_err_null_ptrAny pointer arg is NULL.
k_ra8_err_not_foundold_path does not exist.
k_ra8_err_access_deniedold_path's read-only attribute is set.
k_ra8_err_existsnew_path already resolves.
k_ra8_err_not_supportedexFAT name longer than 15 characters, or the two paths are in different directories.
k_ra8_err_invalid_argThe new leaf holds a character no FAT name may carry, or is longer than 247 characters.
k_ra8_err_no_memThe directory has no room for the new entry.
Precondition
The file is not open.
Postcondition
On success new_path resolves to the same data.
Since
0.1.0

Definition at line 808 of file ra8_fs_fat_dir.c.

References internal_rename_locked(), priv_lock_acquire(), priv_lock_release(), and ra8_fs_rename().

Referenced by fileops_suite_mutate(), fs_fmt_rename_and_verify(), internal_atomic_replace(), internal_native_rename(), and ra8_fs_rename().

◆ ra8_fs_unlink()

ra8_err_t ra8_fs_unlink ( const ra8_fs_mount_t * handle,
const char * path )
nodiscard

Delete a file: mark its dir entry deleted and free its clusters.

FAT12/16/32: 0xE5-marks the entry – together with the VFAT long-name chain in front of it, if it has one – and frees the FAT chain. exFAT: clears the in-use bit on the whole entry set and frees the clusters in the allocation bitmap (the bitmap is authoritative).

A DIRECTORY is refused on both filesystems. Deleting one this way would free the chain that holds its children while their own entries still claim their clusters, leaving them allocated and unreachable – lost clusters that only a reformat recovers. Use ra8_fs_rmdir().

Parameters
[in]handleMount handle.
[in]pathNUL-terminated path to the file.
Return values
k_ra8_okFile unlinked.
k_ra8_err_null_ptrhandle/path NULL.
k_ra8_err_invalid_argpath names a directory.
k_ra8_err_access_deniedpath's read-only attribute is set.
k_ra8_err_not_foundFile doesn't exist.
Precondition
handle and path are non-NULL; the mount is in use.
No open file handle refers to path.
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.
See also
ra8_fs_rmdir() Removes a directory instead.
Since
0.1.0

Definition at line 799 of file ra8_fs_fat_dir.c.

References internal_unlink_locked(), priv_lock_acquire(), priv_lock_release(), and ra8_fs_unlink().

Referenced by demo_file_ops(), fileops_suite_create(), fileops_suite_mutate(), fs_fmt_write_cycle(), internal_atomic_replace(), internal_compile_and_cache(), internal_native_unlink(), internal_write_stamp(), and ra8_fs_unlink().