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

Set / clear a named entry's file attributes (ra8_fs_set_attr()). More...

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

Go to the source code of this file.

Functions

static ra8_err_t internal_setattr_fat (const ra8_fs_mount_t *m, const char *path, uint8_t set_mask, uint8_t clear_mask)
 Patch the attribute byte of a FAT12/16/32 entry.
static ra8_err_t internal_setattr_exfat (const ra8_fs_mount_t *m, const char *path, uint8_t set_mask, uint8_t clear_mask)
 Patch the FileAttributes byte of an exFAT root-level entry.
static ra8_err_t internal_setattr_locked (const ra8_fs_mount_t *handle, const char *path, uint8_t set_mask, uint8_t clear_mask)
 Set attributes – the guarded body of 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)
 Set and/or clear a named entry's file attributes (chmod-style).

Detailed Description

Set / clear a named entry's file attributes (ra8_fs_set_attr()).

The chmod-style primitive for the FAT/exFAT attribute byte. ra8_fs_stat() already REPORTS the read-only / hidden / system / archive bits; this file is how they are CHANGED. Its first job is the read-only bit: putting it on a file makes every mutating path (open for writing, write, write_file, unlink, rename) refuse the file with k_ra8_err_access_denied, and taking it off restores ordinary access (#681).

Only the four host-controlled bits are settable. The same byte also carries the DIRECTORY, VOLUME_ID and long-name bits, which say what an entry IS rather than how a host wants it treated – patching those would reclassify the entry and corrupt the volume – so a mask naming any of them, or naming one bit in both the set and clear masks, is rejected before a sector is touched.

On FAT the byte is patched in the directory entry in place. On exFAT it is the low byte of the File entry's FileAttributes field, and because the entry set's SetChecksum covers it, the whole set is re-read, patched and re-checksummed – exactly as ra8_fs_utime() does for the timestamp fields. exFAT operations here are root-directory only, matching that sibling.

References (every shorthand citation in this file):

  • "exFAT spec" = Microsoft Corp., "exFAT file system specification", revision 1.00, section 7 "Directory Structure".

NASA Power-of-Ten compliance:

  • Rule 2: the exFAT re-read loop is bounded by the set's entry count, itself <= k_exfat_set_max_entries.
  • Rule 3: zero malloc; the entry-set buffer is a bounded stack array.
  • Rule 7: every backend and resolver call is checked.
Since
0.1.0

Definition in file ra8_fs_fat_attr.c.

Function Documentation

◆ internal_setattr_exfat()

ra8_err_t internal_setattr_exfat ( const ra8_fs_mount_t * m,
const char * path,
uint8_t set_mask,
uint8_t clear_mask )
static

Patch the FileAttributes byte of an exFAT root-level entry.

Locates the file's directory-entry set, re-reads every entry back into a buffer (the SetChecksum covers them all), rewrites the low byte of the File entry's FileAttributes to (attr & ~clear) | set, recomputes the SetChecksum over the whole set, and writes the File entry back – the only entry whose bytes changed. Root-directory namespace only, matching every other exFAT operation here.

Parameters
[in]mMounted exFAT volume.
[in]pathRoot-level name.
[in]set_maskAttribute bits to set.
[in]clear_maskAttribute bits to clear.
Returns
Error code.
Return values
k_ra8_okThe attribute byte was patched.
k_ra8_err_not_foundNo such name in the root directory.
k_ra8_err_*Backend read/write failure.
Precondition
m and path are non-NULL; m->type is exFAT.
The mount is in use and the masks have already been validated.
Postcondition
On success the File entry's FileAttributes low byte is (old & ~clear) | set and the set's SetChecksum is valid.
On failure the set is unchanged.
Note
Bounded loop (NASA Rule 2): the set's entry count, <= k_exfat_set_max_entries.
Not thread-safe; callers serialise filesystem operations.
Since
0.1.0

Definition at line 146 of file ra8_fs_fat_attr.c.

References exfat_setpos_t::cluster, exfat_setpos_t::index, k_exfat_entry_bytes, k_exfat_off_file_attr, k_exfat_off_file_csum, k_exfat_set_max_entries, k_ra8_ok, priv_exfat_dir_root(), priv_exfat_find_set(), priv_exfat_next_entry(), priv_exfat_set_checksum(), priv_exfat_write_dir_set(), and priv_wr16().

◆ internal_setattr_fat()

ra8_err_t internal_setattr_fat ( const ra8_fs_mount_t * m,
const char * path,
uint8_t set_mask,
uint8_t clear_mask )
static

Patch the attribute byte of a FAT12/16/32 entry.

Resolves path to its directory entry the way ra8_fs_stat() does – parent walk, then packed 8.3 lookup with a VFAT long-name fallback – reads the sector holding the entry, rewrites the DIR_Attr byte to (attr & ~clear_mask) | set_mask, and writes the sector back. Only the attribute byte changes; the name, cluster, size and timestamps are untouched. A directory entry is patched as readily as a file's.

Parameters
[in]mMounted FAT volume.
[in]pathPath to the entry (never the volume root here).
[in]set_maskAttribute bits to set.
[in]clear_maskAttribute bits to clear.
Returns
Error code.
Return values
k_ra8_okThe attribute byte was patched.
k_ra8_err_invalid_argA path component is not a valid 8.3 name.
k_ra8_err_not_foundNothing at path.
k_ra8_err_*Backend read/write failure.
Precondition
m and path are non-NULL; m->type is not exFAT.
The mount is in use and the masks have already been validated.
Postcondition
On success the entry's attribute byte is (old & ~clear) | set.
On failure the entry is unchanged.
Note
Not thread-safe; callers serialise filesystem operations.
Since
0.1.0

Definition at line 79 of file ra8_fs_fat_attr.c.

References k_max_8_3_name, k_ra8_err_not_found, k_ra8_fs_dir_entry_bytes, k_ra8_ok, priv_dir_find(), priv_dir_find_long(), priv_fat_entry_apply_attr(), priv_path_to_83(), priv_read_sector(), priv_resolve_parent(), priv_sec_walk(), and priv_write_sector().

Referenced by internal_setattr_locked().

◆ internal_setattr_locked()

ra8_err_t internal_setattr_locked ( const ra8_fs_mount_t * handle,
const char * path,
uint8_t set_mask,
uint8_t clear_mask )
static

Set attributes – the guarded body of ra8_fs_set_attr().

Validates the arguments, refuses the volume root (no entry to patch), rejects a mask that names a non-settable bit or a bit in both masks, and dispatches to the FAT or exFAT patcher. Both masks 0 is a no-op success – a set-attr that changes nothing changed nothing. The public ra8_fs_set_attr brackets this with the library lock; the full contract is documented there.

Parameters
[in]handleMount handle.
[in]pathPath to the entry.
[in]set_maskAttribute bits to set.
[in]clear_maskAttribute bits to clear.
Returns
Error code.
Return values
k_ra8_okAttribute byte patched (or both masks 0).
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
The library lock is held (or none is installed).
handle and path are non-NULL.
Postcondition
On success the requested bits hold their new state.
On failure the entry is unchanged.
Note
Never call this from outside ra8_fs; it is the unlocked half.
Since
0.1.0

Definition at line 227 of file ra8_fs_fat_attr.c.

References internal_setattr_fat(), internal_setattr_locked(), k_ra8_err_invalid_arg, k_ra8_err_null_ptr, k_ra8_fs_attr_settable, and k_ra8_fs_type_exfat.

Referenced by internal_setattr_locked(), and ra8_fs_set_attr().

◆ 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().