RTEMS 7.0-rc1
Loading...
Searching...
No Matches
rtems-fatfs.h
Go to the documentation of this file.
1
9/*
10 Copyright (C) 2025 Sepehr Ganji <sepehrganji79@gmail.com>
11*/
12
13#ifndef RTEMS_FATFS_H
14#define RTEMS_FATFS_H
15
16#include <stdint.h>
17#include <string.h>
18#include <sys/stat.h>
19#include <sys/types.h>
20#include <time.h>
21
22#include <rtems/diskdevs.h>
23#include <rtems/libio.h>
24#include <rtems/seterr.h>
25
26#include "ff.h"
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32#define DT_REG 8
33#define DT_DIR 4
34
35typedef struct {
36 int fd;
38 bool initialized;
40
41#define RTEMS_FATFS_POSIX_CACHE_SIZE 64
42
43typedef struct {
44 char path[ 256 ];
45 time_t mtime;
46 time_t ctime;
47 bool valid;
49
50typedef struct {
51 FATFS fatfs;
52 rtems_recursive_mutex vol_mutex;
53 const rtems_filesystem_file_handlers_r *file_handlers;
54 const rtems_filesystem_file_handlers_r *dir_handlers;
55 uint8_t drive_number;
56 char mount_path[ 256 ];
57 char current_dir[ 256 ];
58 rtems_fatfs_posix_cache_entry_t posix_cache[ RTEMS_FATFS_POSIX_CACHE_SIZE ];
59 int posix_cache_next;
61
62typedef struct {
63 union {
64 FIL file;
65 DIR dir;
66 } handle;
67 FILINFO info;
68 bool is_directory;
69 bool is_open;
70 char path[ 256 ];
71 bool is_root_node;
72 int ref_count;
73 time_t posix_mtime;
74 time_t posix_ctime;
75 bool posix_time_valid;
77
78/* Disk I/O interface */
79int fatfs_diskio_register_device( uint8_t pdrv, const char *device_path );
80void fatfs_diskio_unregister_device( uint8_t pdrv );
81
82/* Utility functions */
83static inline int rtems_fatfs_get_full_path(
84 const rtems_fatfs_fs_info_t *fs_info,
85 const char *relative_path,
86 char *full_path,
87 size_t path_size
88)
89{
90 size_t mount_len = strlen( fs_info->mount_path );
91 size_t rel_len = strlen( relative_path );
92
93 if ( mount_len + rel_len >= path_size ) {
95 }
96
97 memcpy( full_path, fs_info->mount_path, mount_len );
98 memcpy( full_path + mount_len, relative_path, rel_len + 1 );
99
100 return 0;
101}
102
103static inline int rtems_fatfs_fresult_to_errno( FRESULT fr )
104{
105 switch ( fr ) {
106 case FR_OK:
107 return 0;
108 case FR_DISK_ERR:
109 case FR_INT_ERR:
110 case FR_NOT_READY:
111 return EIO;
112 case FR_NO_FILE:
113 case FR_NO_PATH:
114 return ENOENT;
115 case FR_INVALID_NAME:
116 return EINVAL;
117 case FR_DENIED:
118 return EACCES;
119 case FR_EXIST:
120 return EEXIST;
121 case FR_INVALID_OBJECT:
122 return EBADF;
123 case FR_WRITE_PROTECTED:
124 return EROFS;
125 case FR_INVALID_DRIVE:
126 case FR_NOT_ENABLED:
127 case FR_NO_FILESYSTEM:
128 return ENXIO;
129 case FR_MKFS_ABORTED:
130 return EINVAL;
131 case FR_TIMEOUT:
132 return ETIMEDOUT;
133 case FR_LOCKED:
134 return EBUSY;
135 case FR_NOT_ENOUGH_CORE:
136 return ENOMEM;
137 case FR_TOO_MANY_OPEN_FILES:
138 return EMFILE;
139 case FR_INVALID_PARAMETER:
140 return EINVAL;
141 default:
142 return EIO;
143 }
144}
145
146static inline void rtems_fatfs_unlock(
148)
149{
150 rtems_fatfs_fs_info_t *fs_info = (rtems_fatfs_fs_info_t *) mt_entry->fs_info;
151 rtems_recursive_mutex_unlock( &fs_info->vol_mutex );
152}
153
154static inline int rtems_fatfs_resolve_node_path(
155 const rtems_fatfs_fs_info_t *fs_info,
156 const rtems_fatfs_node_t *node,
157 char *full_path,
158 size_t path_size,
160)
161{
162 int
163 rc = rtems_fatfs_get_full_path( fs_info, node->path, full_path, path_size );
164 if ( rc != 0 && mt_entry != NULL ) {
165 rtems_fatfs_unlock( mt_entry );
166 }
167 return rc;
168}
169
170static inline void rtems_fatfs_filinfo_to_stat(
171 const FILINFO *fno,
172 struct stat *st
173)
174{
175 const char *name = fno->fname;
176 ino_t inode_hash = 1;
177
178 memset( st, 0, sizeof( *st ) );
179
180 while ( *name != '\0' ) {
181 inode_hash = ( inode_hash * 33 ) + (unsigned char) *name;
182 name++;
183 }
184 inode_hash ^= fno->fsize ^ ( fno->fdate << 16 ) ^ fno->ftime;
185
186 st->st_ino = ( inode_hash != 0 ) ? inode_hash : 1;
187 st->st_dev = 1;
188 st->st_size = (off_t) fno->fsize;
189 st->st_blksize = 512;
190 st->st_blocks = ( st->st_size + 511 ) / 512;
191
192 if ( fno->fdate != 0 || fno->ftime != 0 ) {
193 struct tm tm;
194 memset( &tm, 0, sizeof( tm ) );
195
196 tm.tm_year = ( ( fno->fdate >> 9 ) & 0x7F ) + 80;
197 tm.tm_mon = ( ( fno->fdate >> 5 ) & 0x0F ) - 1;
198 tm.tm_mday = fno->fdate & 0x1F;
199 tm.tm_hour = ( fno->ftime >> 11 ) & 0x1F;
200 tm.tm_min = ( fno->ftime >> 5 ) & 0x3F;
201 tm.tm_sec = ( fno->ftime & 0x1F ) * 2;
202
203 st->st_mtime = mktime( &tm );
204 st->st_ctime = st->st_mtime;
205 st->st_atime = st->st_mtime;
206 }
207
208 if ( fno->fattrib & AM_DIR ) {
209 st->st_mode = S_IFDIR | 0755;
210 } else {
211 st->st_mode = S_IFREG | 0644;
212 }
213
214 if ( fno->fattrib & AM_RDO ) {
215 st->st_mode &= ~( S_IWUSR | S_IWGRP | S_IWOTH );
216 }
217}
218
219static inline void rtems_fatfs_node_to_stat_basic(
220 const rtems_fatfs_node_t *node,
221 struct stat *st
222)
223{
224 rtems_fatfs_filinfo_to_stat( &node->info, st );
225}
226
227static inline void rtems_fatfs_node_to_stat(
228 const rtems_fatfs_node_t *node,
229 struct stat *st,
230 rtems_fatfs_fs_info_t *fs_info
231)
232{
233 rtems_fatfs_filinfo_to_stat( &node->info, st );
234
235 if ( fs_info != NULL ) {
236 blksize_t cluster_size = fs_info->fatfs.csize * 512;
237 st->st_blksize = cluster_size;
238 blkcnt_t clusters_used = ( st->st_size + cluster_size - 1 ) / cluster_size;
239 st->st_blocks = clusters_used * fs_info->fatfs.csize;
240 }
241
242 if ( node->posix_time_valid ) {
243 st->st_mtime = node->posix_mtime;
244 st->st_ctime = node->posix_ctime;
245 st->st_atime = node->posix_mtime;
246 } else if ( fs_info != NULL ) {
247 for ( int i = 0; i < RTEMS_FATFS_POSIX_CACHE_SIZE; i++ ) {
248 if ( fs_info->posix_cache[ i ].valid &&
249 strcmp( fs_info->posix_cache[ i ].path, node->path ) == 0 ) {
250 st->st_mtime = fs_info->posix_cache[ i ].mtime;
251 st->st_ctime = fs_info->posix_cache[ i ].ctime;
252 st->st_atime = fs_info->posix_cache[ i ].mtime;
253 break;
254 }
255 }
256 }
257}
258
259static inline void rtems_fatfs_lock(
261)
262{
263 rtems_fatfs_fs_info_t *fs_info = (rtems_fatfs_fs_info_t *) mt_entry->fs_info;
264 rtems_recursive_mutex_lock( &fs_info->vol_mutex );
265}
266
267/* Filesystem operations - declared in rtems-fatfs-init.c */
270 const void *data
271);
272
273void rtems_fatfs_fsunmount_me( rtems_filesystem_mount_table_entry_t *mt_entry );
274
275void rtems_fatfs_eval_path( rtems_filesystem_eval_path_context_t *ctx );
276
277int rtems_fatfs_mknod(
278 const rtems_filesystem_location_info_t *parentloc,
279 const char *name,
280 size_t namelen,
281 mode_t mode,
282 dev_t dev
283);
284
285int rtems_fatfs_rmnod(
286 const rtems_filesystem_location_info_t *parentloc,
288);
289
290int rtems_fatfs_rename(
291 const rtems_filesystem_location_info_t *old_parent_loc,
293 const rtems_filesystem_location_info_t *new_parent_loc,
294 const char *new_name,
295 size_t new_namelen
296);
297
298int rtems_fatfs_utimens(
300 struct timespec times[ 2 ]
301);
302
303int rtems_fatfs_statvfs(
304 const rtems_filesystem_location_info_t *root_loc,
305 struct statvfs *sb
306);
307
308bool rtems_fatfs_are_nodes_equal(
311);
312
313int rtems_fatfs_clone_node( rtems_filesystem_location_info_t *loc );
314
315void rtems_fatfs_free_node( const rtems_filesystem_location_info_t *loc );
316
317/* File operations - declared in rtems-fatfs-file.c */
318ssize_t rtems_fatfs_file_read( rtems_libio_t *iop, void *buffer, size_t count );
319
320ssize_t rtems_fatfs_file_write(
321 rtems_libio_t *iop,
322 const void *buffer,
323 size_t count
324);
325
326off_t rtems_fatfs_file_lseek( rtems_libio_t *iop, off_t offset, int whence );
327
328int rtems_fatfs_file_fstat(
330 struct stat *buf
331);
332
333int rtems_fatfs_file_ftruncate( rtems_libio_t *iop, off_t length );
334
335int rtems_fatfs_file_fsync( rtems_libio_t *iop );
336
337/* Directory operations - declared in rtems-fatfs-dir.c */
338ssize_t rtems_fatfs_dir_read( rtems_libio_t *iop, void *buffer, size_t count );
339
340int rtems_fatfs_dir_fstat(
342 struct stat *buf
343);
344
345int rtems_fatfs_opendir(
346 rtems_libio_t *iop,
347 const char *path,
348 int oflag,
349 mode_t mode
350);
351
352int rtems_fatfs_closedir( rtems_libio_t *iop );
353
354int rtems_fatfs_openfile(
355 rtems_libio_t *iop,
356 const char *path,
357 int oflag,
358 mode_t mode
359);
360
361int rtems_fatfs_closefile( rtems_libio_t *iop );
362
363/* Handler tables */
364extern const rtems_filesystem_operations_table rtems_fatfs_ops;
365extern const rtems_filesystem_file_handlers_r rtems_fatfs_file_handlers;
366extern const rtems_filesystem_file_handlers_r rtems_fatfs_dir_handlers;
367
368#ifdef __cplusplus
369}
370#endif
371
372#endif /* RTEMS_FATFS_H */
clock_t times(struct tms *ptms)
Definition: __times.c:97
Block Device Disk Management API.
int rtems_fatfs_initialize(rtems_filesystem_mount_table_entry_t *mt_entry, const void *data)
Initialize FatFS filesystem.
Definition: rtems-fatfs-init.c:150
#define rtems_set_errno_and_return_minus_one(_error)
Definition: seterr.h:67
Basic IO API.
This header file defines macros to set errno and return minus one.
Definition: ff.h:241
Definition: ff.h:150
Definition: ff.h:260
Definition: ff.h:218
File system node operations table.
Definition: libio.h:1008
File system operations table.
Definition: libio.h:475
Definition: rtems-fatfs.h:35
Description of a disk device (logical and physical disks).
Definition: diskdevs.h:177
Definition: rtems-fatfs.h:50
Definition: rtems-fatfs.h:62
Definition: rtems-fatfs.h:43
Path evaluation context.
Definition: libio.h:105
File system location.
Definition: fs.h:72
Mount table entry.
Definition: libio.h:1661
An open file data structure.
Definition: libio.h:1325
Definition: statvfs.h:56