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

Volume-level metadata: free space, volume label, and per-entry utime. More...

#include <stdint.h>
#include "ra8_err.h"
#include "ra8_fs.h"
Include dependency graph for ra8_fs_meta.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ra8_fs_space_t
 A mounted volume's capacity, free space, and cluster geometry. More...

Enumerations

enum  ra8_fs_label_limit_t : uint8_t { k_ra8_fs_label_cap = 12 }
 Sizing constant for the volume-label API. More...
enum  ra8_fs_attr_settable_t : uint8_t { k_ra8_fs_attr_settable }
 The attribute bits ra8_fs_set_attr may change. More...

Functions

ra8_err_t ra8_fs_free_space (const ra8_fs_mount_t *handle, ra8_fs_space_t *out)
 Report a mounted volume's total, free, and used space.
ra8_err_t ra8_fs_get_label (const ra8_fs_mount_t *handle, char *out, uint32_t out_len)
 Read the volume label of a mounted volume.
ra8_err_t ra8_fs_set_label (const ra8_fs_mount_t *handle, const char *label)
 Set (or clear) the volume label of a mounted volume.
ra8_err_t ra8_fs_utime (const ra8_fs_mount_t *handle, const char *path, const ra8_fs_datetime_t *create, const ra8_fs_datetime_t *modify, const ra8_fs_datetime_t *access)
 Set a named entry's create / modify / access timestamps.
ra8_err_t ra8_fs_truncate (ra8_fs_file_t *file, uint64_t new_size)
 Set an open file's length to new_size, shrinking or growing it.
ra8_err_t ra8_fs_set_attr (const ra8_fs_mount_t *handle, const char *path, uint8_t set_mask, uint8_t clear_mask)
 Set and/or clear a named entry's file attributes (chmod-style).

Detailed Description

Volume-level metadata: free space, volume label, and per-entry utime.

The three metadata operations a general-purpose filesystem is expected to carry that the core ra8_fs.h surface (format / mount / open / read / write / stat / listdir / unlink / rename / mkdir / rmdir) does not:

  • ra8_fs_free_space – how much room is left, for a data logger that must know before a run whether to start, roll or stop, and for any UI that shows a free-space indicator. The counts already live inside the driver (FAT32's FSInfo free count, and the exFAT allocation bitmap); this exposes them, falling back to a full FAT / bitmap walk when no trusted count exists.
  • ra8_fs_get_label / ra8_fs_set_label – read and change the human name of the medium after format, the "which card is this" a product shows and a host lets you rename.
  • ra8_fs_utime – put a chosen create / modify / access time on a named entry, so a backup or sync restore can preserve original timestamps instead of stamping every restored file with the moment of the restore.

They live in their own header, in the shape of ra8_fs_stat and the rest of ra8_fs.h, because they are an optional metadata extension rather than the read/write core: a consumer that only moves bytes never includes this file and pays nothing for its existence. This header pulls in ra8_fs.h for the mount handle and (through it) the ra8_fs_datetime_t the utime reads.

Since
0.1.0

Definition in file ra8_fs_meta.h.

Enumeration Type Documentation

◆ ra8_fs_attr_settable_t

enum ra8_fs_attr_settable_t : uint8_t

The attribute bits ra8_fs_set_attr may change.

The FAT/exFAT attribute byte also carries the DIRECTORY, VOLUME_ID and long-name bits, which describe what an entry IS rather than how a host wants it treated; changing them would reclassify the entry and corrupt the volume. So the set/clear masks are confined to the four host-controlled bits – read-only, hidden, system and archive – and a request naming any other bit is rejected.

See also
ra8_fs_set_attr()
Since
0.1.0
Enumerator
k_ra8_fs_attr_settable 

Union of the four settable bits (0x27).

Definition at line 323 of file ra8_fs_meta.h.

◆ ra8_fs_label_limit_t

enum ra8_fs_label_limit_t : uint8_t

Sizing constant for the volume-label API.

Enumerator
k_ra8_fs_label_cap 

11-char FAT/exFAT label + NUL: min out size.

Definition at line 55 of file ra8_fs_meta.h.

Function Documentation

◆ ra8_fs_free_space()

ra8_err_t ra8_fs_free_space ( const ra8_fs_mount_t * handle,
ra8_fs_space_t * out )
nodiscard

Report a mounted volume's total, free, and used space.

Answers "how much room is left" from the counts the driver already keeps. On FAT32 whose FSInfo validated at mount the free count is the cached one (O(1)); otherwise – FAT12/FAT16, or a FAT32 whose FSInfo was absent or untrusted – the FAT is walked once and the result is cached for subsequent queries. On exFAT the allocation bitmap (which alone is authoritative for allocation state) is population-counted, also cached. The byte totals are the cluster counts scaled by the allocation-unit size, so a caller can compare bytes directly without knowing the cluster geometry.

Parameters
[in]handleMount handle from ra8_fs_mount().
[out]outReceives the capacity / free / used figures on success.
Returns
ra8_err_t Error code.
Return values
k_ra8_okFigures reported in out.
k_ra8_err_null_ptrhandle or out is NULL.
k_ra8_err_invalid_stateMount is not in use.
k_ra8_err_*Backend read failure while walking the FAT or the allocation bitmap.
Precondition
handle and out are non-NULL.
Mount is in use.
Postcondition
On k_ra8_ok out->used_clusters + out->free_clusters == out->total_clusters and the byte totals equal the cluster totals scaled by out->bytes_per_cluster.
No volume state is modified.
Note
Not thread-safe unless a lock is installed (see ra8_fs_set_lock()).
See also
ra8_fs_space_t
Since
0.1.0

Definition at line 327 of file ra8_fs_fat_space.c.

References internal_space_locked(), priv_lock_acquire(), priv_lock_release(), and ra8_fs_free_space().

Referenced by internal_native_free_space(), and ra8_fs_free_space().

◆ ra8_fs_get_label()

ra8_err_t ra8_fs_get_label ( const ra8_fs_mount_t * handle,
char * out,
uint32_t out_len )
nodiscard

Read the volume label of a mounted volume.

On FAT the label is read from the root directory's ATTR_VOLUME_ID entry when one exists (the copy a desktop shows and edits), falling back to the boot sector's BS_VolLab; the specification's unlabelled sentinel "NO NAME " reports as the empty string. On exFAT the root-directory Volume Label entry (type 0x83) is decoded from UTF-16LE. The result is NUL-terminated and stripped of trailing padding spaces.

Parameters
[in]handleMount handle.
[out]outBuffer receiving the NUL-terminated label.
[in]out_lenCapacity of out in bytes; k_ra8_fs_label_cap holds any label this filesystem can store.
Returns
ra8_err_t Error code.
Return values
k_ra8_okLabel written to out (possibly empty).
k_ra8_err_null_ptrhandle or out is NULL.
k_ra8_err_invalid_argout_len is 0.
k_ra8_err_invalid_stateMount is not in use.
k_ra8_err_*Backend read failure.
Precondition
handle and out are non-NULL; out_len >= 1.
Mount is in use.
Postcondition
On k_ra8_ok out is NUL-terminated (truncated to fit out_len).
No volume state is modified.
Note
Not thread-safe unless a lock is installed (see ra8_fs_set_lock()).
See also
ra8_fs_set_label()
Since
0.1.0

Definition at line 585 of file ra8_fs_fat_label.c.

References internal_get_label_locked(), priv_lock_acquire(), priv_lock_release(), and ra8_fs_get_label().

Referenced by ra8_fs_get_label().

◆ ra8_fs_set_attr()

ra8_err_t ra8_fs_set_attr ( const ra8_fs_mount_t * handle,
const char * path,
uint8_t set_mask,
uint8_t clear_mask )
nodiscard

Set and/or clear a named entry's file attributes (chmod-style).

Patches the entry's on-disk attribute byte to (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. Only the four host-controlled bits are settable (k_ra8_fs_attr_settable) – read-only, hidden, system, archive; a mask naming DIRECTORY, VOLUME_ID or a long-name bit, or a bit that appears in BOTH masks, is rejected without touching the volume, so a caller cannot reclassify a directory as a file or give one contradictory instructions.

This is how a read-only marker is PUT ON a file (so a later write / unlink / rename is refused with k_ra8_err_access_denied) or taken OFF one, and how hidden / system / archive are managed to match host behaviour. On FAT the byte lives in the directory entry; on exFAT it is the low byte of the File entry's FileAttributes, and the entry set's SetChecksum is recomputed after the patch. The volume root has no entry of its own and is rejected.

Parameters
[in]handleMount handle.
[in]pathPath to the entry (resolved as ra8_fs_stat() does).
[in]set_maskAttribute bits to set (subset of k_ra8_fs_attr_settable).
[in]clear_maskAttribute bits to clear (subset of k_ra8_fs_attr_settable).
Returns
ra8_err_t Error code.
Return values
k_ra8_okAttribute byte patched (or both masks 0: a no-op success).
k_ra8_err_null_ptrhandle or path is NULL.
k_ra8_err_invalid_stateMount is not in use.
k_ra8_err_invalid_argpath names the volume root or is not a valid name; or a mask names a non-settable bit or a bit in both masks.
k_ra8_err_not_foundNothing at path.
k_ra8_err_*Backend read/write failure.
Precondition
handle and path are non-NULL; the mount is in use.
set_mask & ~k_ra8_fs_attr_settable == 0 and likewise for clear_mask.
Postcondition
On k_ra8_ok a later ra8_fs_stat reports (old & ~clear_mask) | set_mask for the settable bits, and no other bit changed.
On any error the entry's attribute byte is unchanged.
Note
Not thread-safe unless a lock is installed (see ra8_fs_set_lock()).
See also
ra8_fs_stat() Reports the attribute byte this patches.
Since
0.1.0

Definition at line 266 of file ra8_fs_fat_attr.c.

References internal_setattr_locked(), priv_lock_acquire(), priv_lock_release(), and ra8_fs_set_attr().

Referenced by ra8_fs_set_attr().

◆ ra8_fs_set_label()

ra8_err_t ra8_fs_set_label ( const ra8_fs_mount_t * handle,
const char * label )
nodiscard

Set (or clear) the volume label of a mounted volume.

On FAT the boot sector's BS_VolLab and the root directory's ATTR_VOLUME_ID entry are kept in step: a non-empty label writes both (creating the root entry if absent), an empty label restores the "NO NAME " sentinel and removes the root entry, so fsck.fat reports neither a blank nor a mismatched label. On exFAT the root Volume Label entry (type 0x83) is rewritten in place with the new UTF-16LE label and character count. Data and every other entry are untouched.

Parameters
[in]handleMount handle.
[in]labelNew label (<= 11 characters), or NULL / "" to clear it.
Returns
ra8_err_t Error code.
Return values
k_ra8_okLabel written.
k_ra8_err_null_ptrhandle is NULL.
k_ra8_err_invalid_arglabel is longer than 11 characters.
k_ra8_err_invalid_stateMount is not in use.
k_ra8_err_no_memThe root directory has no free slot for a new label entry.
k_ra8_err_*Backend read/write failure.
Precondition
handle is non-NULL and the mount is in use.
No host label longer than 11 characters is requested.
Postcondition
On k_ra8_ok a later ra8_fs_get_label reports label (empty when label was NULL/"").
On an argument error the volume is unchanged.
Note
Not thread-safe unless a lock is installed (see ra8_fs_set_lock()).
See also
ra8_fs_get_label()
Since
0.1.0

Definition at line 594 of file ra8_fs_fat_label.c.

References internal_set_label_locked(), priv_lock_acquire(), priv_lock_release(), and ra8_fs_set_label().

Referenced by ra8_fs_set_label().

◆ ra8_fs_truncate()

ra8_err_t ra8_fs_truncate ( ra8_fs_file_t * file,
uint64_t new_size )
nodiscard

Set an open file's length to new_size, shrinking or growing it.

The ftruncate() verb in both directions (#680), for a handle open in a writing mode. It is the only way to give a file an arbitrary length: writing extends only where bytes land, and ra8_fs_seek clamps to the current size, so neither can pre-size a file or trim it to N > 0 bytes. A shrink frees the tail clusters and lowers the length; a grow extends the file and the gap [old_size, new_size) reads back as zero – FAT zero-fills the fresh clusters on disk, exFAT raises DataLength while ValidDataLength stays at the written prefix so the format serves the gap as zero (and converts a run that outgrows its contiguous space to a real FAT chain). The offset is left where it was, pulled down only by a shrink that lands below it. Lengths are 64-bit: an exFAT file truncates to any size the volume can hold, past 4 GiB included (#676). On FAT12/16/32 a new_size above k_ra8_fs_fat_max_file_bytes is refused with k_ra8_err_invalid_sizeDIR_FileSize is 32-bit, so the format itself cannot express it.

Parameters
[in,out]fileOpen handle in k_ra8_fs_mode_write or _append.
[in]new_sizeDesired length in bytes.
Return values
k_ra8_okLength set; the entry / directory reflects it.
k_ra8_err_null_ptrfile is NULL.
k_ra8_err_invalid_stateNot open, or opened read-only.
k_ra8_err_invalid_sizeFAT volume and new_size exceeds 4 GiB - 1.
k_ra8_err_no_memA grow ran out of free clusters.
k_ra8_err_*Backend, FAT, or bitmap failure.
Precondition
file is a handle from ra8_fs_open() in write or append mode.
Postcondition
On k_ra8_ok ra8_fs_size() reports new_size and a re-read of the gap returns zeros.
On k_ra8_ok the offset is min(old_offset, new_size).
Note
Not thread-safe per file; the public entry holds the library lock.
See also
ra8_fs_write() Extends a file only where bytes are actually written.
Since
0.1.0

Definition at line 770 of file ra8_fs_fat_truncate.c.

References internal_truncate_locked(), priv_lock_acquire(), priv_lock_release(), and ra8_fs_truncate().

Referenced by ra8_fs_truncate().

◆ ra8_fs_utime()

ra8_err_t ra8_fs_utime ( const ra8_fs_mount_t * handle,
const char * path,
const ra8_fs_datetime_t * create,
const ra8_fs_datetime_t * modify,
const ra8_fs_datetime_t * access )
nodiscard

Set a named entry's create / modify / access timestamps.

The touch / utime primitive: each non-NULL reading overwrites that entry's corresponding timestamp fields, each NULL one leaves them unchanged. Unlike the close-time and write-time stamps – which come from the injected clock (see ra8_fs_set_clock()) – these are caller-chosen, so a backup or sync restore can put a file's ORIGINAL create / modify time back instead of the moment of the restore, which is what every "newest wins" incremental heuristic keys on.

FAT stores a create date+time, a modify date+time and an access DATE only (there is no access time); exFAT stores all three as full timestamps plus the 10 ms increments and UtcOffset bytes, and its entry-set SetChecksum is recomputed after the patch. Each reading is clamped into the range the on-disk format can express, so an out-of-range field is recorded as the nearest legal value rather than failing the call. The entry may be a file or a directory; the volume root has no entry to stamp and is rejected.

Parameters
[in]handleMount handle.
[in]pathPath to the entry (resolved as ra8_fs_stat() resolves).
[in]createCreate stamp to write, or NULL to leave it unchanged.
[in]modifyModify stamp to write, or NULL to leave it unchanged.
[in]accessAccess stamp to write, or NULL to leave it unchanged.
Returns
ra8_err_t Error code.
Return values
k_ra8_okRequested stamps written.
k_ra8_err_null_ptrhandle or path is NULL.
k_ra8_err_invalid_stateMount is not in use.
k_ra8_err_invalid_argpath names the volume root, or is not a valid name for this filesystem.
k_ra8_err_not_foundNothing at path.
k_ra8_err_*Backend read/write failure.
Precondition
handle and path are non-NULL; the mount is in use.
No open handle is mid-write on path (its close would re-stamp it).
Postcondition
On k_ra8_ok each non-NULL reading's fields hold that (clamped) instant.
A NULL reading's fields, and any non-time byte, are unchanged.
Note
Not thread-safe unless a lock is installed (see ra8_fs_set_lock()).
See also
ra8_fs_set_clock() Installs the clock the automatic stamps use.
Since
0.1.0

Definition at line 255 of file ra8_fs_fat_utime.c.

References internal_utime_locked(), priv_lock_acquire(), priv_lock_release(), and ra8_fs_utime().

Referenced by ra8_fs_utime().