ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_io_vfs_namespace.c
Go to the documentation of this file.
1
24
25#include <stdint.h>
26
27#include "ra8_attributes.h"
28#include "ra8_check.h"
29#include "ra8_err.h"
30#include "ra8_fs.h"
31#include "ra8_io_fsfmt.h"
32#include "ra8_io_vfs.h"
33#include "ra8_io_vfs_internal.h"
34
36static const char* const s_tag = "ra8_io_vfs_namespace";
37
39{
40 RA8_CHECK_NULL_PTR(path, s_tag, "path must not be nullptr");
41 vfs_slot_t* slot = nullptr;
42 const char* sub = nullptr;
43 RA8_RETURN_ON_ERROR(priv_ra8_io_vfs_resolve(path, &slot, nullptr, &sub), s_tag, "resolve");
44 if (slot->format->caps.read_only) {
46 }
47 if (slot->format->ops->unlink == nullptr) {
49 }
50 return slot->format->ops->unlink(slot->mount_ctx, sub);
51}
52
78 const char* new_path,
79 char* old_name,
80 char* new_name,
81 const char** out_old_sub,
82 const char** out_new_sub)
83{
84 RA8_RETURN_ON_ERROR(priv_ra8_io_vfs_split(old_path, old_name, out_old_sub), s_tag, "old path");
85 RA8_RETURN_ON_ERROR(priv_ra8_io_vfs_split(new_path, new_name, out_new_sub), s_tag, "new path");
86 if (!priv_ra8_io_vfs_streq(old_name, new_name)) {
88 }
89 return k_ra8_ok;
90}
91
92ra8_err_t ra8_io_vfs_rename(const char* old_path, const char* new_path)
93{
94 RA8_CHECK_NULL_PTR(old_path, s_tag, "old_path must not be nullptr");
95 RA8_CHECK_NULL_PTR(new_path, s_tag, "new_path must not be nullptr");
96 char old_name[(uint32_t)k_ra8_io_vfs_name_max];
97 char new_name[(uint32_t)k_ra8_io_vfs_name_max];
98 const char* old_sub = nullptr;
99 const char* new_sub = nullptr;
100 const ra8_err_t split =
101 internal_vfs_rename_split(old_path, new_path, old_name, new_name, &old_sub, &new_sub);
102 if (split != k_ra8_ok) {
103 return split;
104 }
105 vfs_slot_t* slot = priv_ra8_io_vfs_find(old_name, nullptr);
106 if (slot == nullptr) {
107 return k_ra8_err_not_found;
108 }
109 if (slot->format->caps.read_only) {
111 }
112 if (slot->format->ops->rename == nullptr) {
114 }
115 return slot->format->ops->rename(slot->mount_ctx, old_sub, new_sub);
116}
117
119{
120 RA8_CHECK_NULL_PTR(path, s_tag, "path must not be nullptr");
121 RA8_CHECK_NULL_PTR(out, s_tag, "out must not be nullptr");
122 *out = (ra8_io_vfs_stat_t){};
123 vfs_slot_t* slot = nullptr;
124 const char* sub = nullptr;
125 RA8_RETURN_ON_ERROR(priv_ra8_io_vfs_resolve(path, &slot, nullptr, &sub), s_tag, "resolve");
126 ra8_fs_stat_t stat = {};
127 const ra8_err_t e = slot->format->ops->stat(slot->mount_ctx, sub, &stat);
128 if (e == k_ra8_err_not_found) {
129 return k_ra8_ok;
130 }
131 if (e != k_ra8_ok) {
132 return e;
133 }
134 out->size_bytes = stat.size_bytes;
135 out->created = stat.created;
136 out->modified = stat.modified;
137 out->accessed = stat.accessed;
138 out->attr = stat.attr;
139 out->is_directory = stat.is_directory;
140 out->exists = true;
141 return k_ra8_ok;
142}
143
144ra8_err_t ra8_io_vfs_listdir(const char* path, ra8_fs_listdir_cb_t cb, void* ctx)
145{
146 RA8_CHECK_NULL_PTR(path, s_tag, "path must not be nullptr");
147 RA8_CHECK_NULL_PTR(cb, s_tag, "cb must not be nullptr");
148 vfs_slot_t* slot = nullptr;
149 const char* sub = nullptr;
150 RA8_RETURN_ON_ERROR(priv_ra8_io_vfs_resolve(path, &slot, nullptr, &sub), s_tag, "resolve");
151 return slot->format->ops->listdir(slot->mount_ctx, sub, cb, ctx);
152}
153
155 uint32_t* out_bytes,
156 uint8_t* out_align,
157 uint16_t* out_max_open)
158{
159 if ((path == nullptr) || (out_bytes == nullptr) || (out_align == nullptr) ||
160 (out_max_open == nullptr)) {
161 return k_ra8_err_null_ptr;
162 }
163 *out_bytes = 0U;
164 *out_align = 0U;
165 *out_max_open = 0U;
166 vfs_slot_t* slot = nullptr;
167 const char* sub = nullptr;
168 const ra8_err_t resolved = priv_ra8_io_vfs_resolve(path, &slot, nullptr, &sub);
169 (void)sub;
170 if (resolved != k_ra8_ok) {
171 return resolved;
172 }
173 if (!slot->format->caps.supports_dir_cursor) {
175 }
176 *out_bytes = slot->format->caps.directory_workspace_bytes;
177 *out_align = slot->format->caps.directory_workspace_align;
178 *out_max_open = slot->format->caps.max_open_directories;
179 return k_ra8_ok;
180}
181
183 ra8_io_vfs_dir_t* directory,
184 void* workspace,
185 uint32_t workspace_bytes)
186{
187 if ((path == nullptr) || (directory == nullptr) || (workspace == nullptr)) {
188 return k_ra8_err_null_ptr;
189 }
190 if (directory->is_open) {
191 return k_ra8_err_busy;
192 }
193 vfs_slot_t* slot = nullptr;
194 const char* sub = nullptr;
195 const ra8_err_t resolved = priv_ra8_io_vfs_resolve(path, &slot, nullptr, &sub);
196 if (resolved != k_ra8_ok) {
197 return resolved;
198 }
199 const ra8_io_fsfmt_caps_t* caps = &slot->format->caps;
200 if (!caps->supports_dir_cursor) {
202 }
203 if (workspace_bytes < caps->directory_workspace_bytes) {
204 return k_ra8_err_no_mem;
205 }
206 if (((uintptr_t)workspace % (uintptr_t)caps->directory_workspace_align) != 0U) {
208 }
209 const ra8_err_t opened =
210 slot->format->ops->dir_open(slot->mount_ctx, sub, workspace, workspace_bytes);
211 if (opened != k_ra8_ok) {
212 return opened;
213 }
214 *directory = (ra8_io_vfs_dir_t){.format = slot->format,
215 .state = workspace,
216 .state_bytes = workspace_bytes,
217 .is_open = true};
218 return k_ra8_ok;
219}
220
222{
223 if ((directory == nullptr) || (out == nullptr) || (out_entry == nullptr)) {
224 return k_ra8_err_null_ptr;
225 }
226 if (!directory->is_open || (directory->format == nullptr)) {
228 }
229 *out = (ra8_fs_dirent_t){};
230 *out_entry = false;
231 return directory->format->ops->dir_next(directory->state, out, out_entry);
232}
233
235{
236 if (directory == nullptr) {
237 return k_ra8_err_null_ptr;
238 }
239 if (!directory->is_open || (directory->format == nullptr)) {
241 }
242 const ra8_err_t closed = directory->format->ops->dir_close(directory->state);
243 *directory = (ra8_io_vfs_dir_t){};
244 return closed;
245}
246
248{
249 RA8_CHECK_NULL_PTR(path, s_tag, "path must not be nullptr");
250 vfs_slot_t* slot = nullptr;
251 const char* sub = nullptr;
252 RA8_RETURN_ON_ERROR(priv_ra8_io_vfs_resolve(path, &slot, nullptr, &sub), s_tag, "resolve");
253 if (slot->format->caps.read_only) {
255 }
256 if (!slot->format->caps.supports_mkdir) {
258 }
259 if (slot->format->ops->mkdir == nullptr) {
261 }
262 return slot->format->ops->mkdir(slot->mount_ctx, sub);
263}
264
266{
267 RA8_CHECK_NULL_PTR(path, s_tag, "path must not be nullptr");
268 vfs_slot_t* slot = nullptr;
269 const char* sub = nullptr;
270 RA8_RETURN_ON_ERROR(priv_ra8_io_vfs_resolve(path, &slot, nullptr, &sub), s_tag, "resolve");
271 if (slot->format->caps.read_only) {
273 }
274 if (!slot->format->caps.supports_rmdir) {
276 }
277 if (slot->format->ops->rmdir == nullptr) {
279 }
280 return slot->format->ops->rmdir(slot->mount_ctx, sub);
281}
static const char * s_tag
Logging / check tag.
Definition ra8_app.c:17
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_RETURN_ON_ERROR(err, tag, message)
Early return on error, propagating the code upward.
Definition ra8_check.h:184
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Definition ra8_check.h:243
Error Code Definitions for ra8-firmware.
@ k_ra8_err_not_supported
Requested feature not compiled in, not wired, or not supported by this MCU variant.
Definition ra8_err.h:180
@ k_ra8_err_no_mem
Static buffer exhausted (no dynamic memory on this project).
Definition ra8_err.h:142
@ k_ra8_err_busy
Resource busy – blocking operation cannot proceed.
Definition ra8_err.h:195
@ k_ra8_err_invalid_arg
Invalid function argument.
Definition ra8_err.h:152
@ k_ra8_err_invalid_state
Module in wrong state for requested operation.
Definition ra8_err.h:161
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
@ k_ra8_err_null_ptr
Pointer was NULL where a valid pointer was required.
Definition ra8_err.h:478
@ k_ra8_err_not_found
Requested item not found (lookup / search missed).
Definition ra8_err.h:173
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
Minimal FAT12/FAT16/FAT32 filesystem adapter (read + write).
void(* ra8_fs_listdir_cb_t)(const char *name, uint8_t attr, uint64_t size, void *ctx)
Callback invoked once per directory entry by ra8_fs_listdir().
ra8_io pluggable filesystem-format registry (probe + capabilities).
ra8_err_t priv_ra8_io_vfs_resolve(const char *path, vfs_slot_t **out_slot, uint8_t *out_index, const char **out_sub)
Resolve "name:sub" to a mount slot and sub-path.
Definition ra8_io_vfs.c:181
ra8_err_t priv_ra8_io_vfs_split(const char *path, char *out_name, const char **out_sub)
Split "name:sub" into a bounded name and sub-path pointer.
Definition ra8_io_vfs.c:160
bool priv_ra8_io_vfs_streq(const char *a, const char *b)
Compare two mount names within the fixed bound.
Definition ra8_io_vfs.c:45
vfs_slot_t * priv_ra8_io_vfs_find(const char *name, uint8_t *out_index)
Find an occupied mount slot by name and optionally report its index.
Definition ra8_io_vfs.c:120
ra8_io virtual filesystem – mount many volumes, address them by name.
@ k_ra8_io_vfs_name_max
Mount name length incl NUL.
Definition ra8_io_vfs.h:58
Module-private mount-slot layout and path resolvers for the ra8_io VFS.
ra8_err_t ra8_io_vfs_dir_requirements(const char *path, uint32_t *out_bytes, uint8_t *out_align, uint16_t *out_max_open)
Query cursor workspace requirements for a qualified directory path.
ra8_err_t ra8_io_vfs_listdir(const char *path, ra8_fs_listdir_cb_t cb, void *ctx)
Enumerate a directory named "name:/path".
ra8_err_t ra8_io_vfs_dir_next(ra8_io_vfs_dir_t *directory, ra8_fs_dirent_t *out, bool *out_entry)
Copy one stable entry or report clean end-of-directory.
ra8_err_t ra8_io_vfs_mkdir(const char *path)
Create a directory named "name:/path".
ra8_err_t ra8_io_vfs_unlink(const char *path)
Delete a file by "name:/path".
ra8_err_t ra8_io_vfs_dir_close(ra8_io_vfs_dir_t *directory)
Close and consume one caller-owned VFS directory cursor.
ra8_err_t ra8_io_vfs_stat(const char *path, ra8_io_vfs_stat_t *out)
Query metadata for "name:/path".
ra8_err_t ra8_io_vfs_rmdir(const char *path)
Remove the empty directory named "name:/path".
ra8_err_t ra8_io_vfs_dir_open(const char *path, ra8_io_vfs_dir_t *directory, void *workspace, uint32_t workspace_bytes)
Open a format-neutral incremental directory cursor.
static ra8_err_t internal_vfs_rename_split(const char *old_path, const char *new_path, char *old_name, char *new_name, const char **out_old_sub, const char **out_new_sub)
Split both rename paths and require them to name the same mount.
ra8_err_t ra8_io_vfs_rename(const char *old_path, const char *new_path)
Rename a file within one mount.
Stable directory-entry value copied by ra8_fs_dir_next.
What ra8_fs_stat() read out of a directory entry.
ra8_fs_timestamp_t accessed
Last-accessed timestamp (date-only on FAT).
uint8_t attr
The entry's own FAT attribute byte.
uint64_t size_bytes
File length in bytes; 0 for a directory.
ra8_fs_timestamp_t modified
Last-modified timestamp.
bool is_directory
true => the ATTR_DIRECTORY bit is set.
ra8_fs_timestamp_t created
Creation timestamp, or invalid for the root.
What a filesystem format supports.
bool supports_dir_cursor
true => incremental directory cursor exists.
uint8_t directory_workspace_align
Required cursor-workspace alignment.
Caller-owned format-neutral directory cursor.
Definition ra8_io_vfs.h:69
void * state
Caller-supplied format state.
Definition ra8_io_vfs.h:71
bool is_open
VFS lifecycle guard.
Definition ra8_io_vfs.h:73
const ra8_io_fsfmt_t * format
Format owning the cursor state.
Definition ra8_io_vfs.h:70
Metadata returned by ra8_io_vfs_stat.
Definition ra8_io_vfs.h:96
uint8_t attr
The entry's own FAT attribute byte.
Definition ra8_io_vfs.h:101
uint64_t size_bytes
File size in bytes (0 for directories).
Definition ra8_io_vfs.h:97
ra8_fs_timestamp_t modified
Last-modified time, when present.
Definition ra8_io_vfs.h:99
bool is_directory
true => path names a directory.
Definition ra8_io_vfs.h:102
ra8_fs_timestamp_t accessed
Last-accessed time/date, when present.
Definition ra8_io_vfs.h:100
ra8_fs_timestamp_t created
Creation time, when present.
Definition ra8_io_vfs.h:98
bool exists
true => the path resolves to an entry.
Definition ra8_io_vfs.h:103
One fixed named-mount slot.
void * mount_ctx
Format-private mounted context.
const ra8_io_fsfmt_t * format
Selected format descriptor.