-
Notifications
You must be signed in to change notification settings - Fork 601
/
fs.h
676 lines (625 loc) · 21.3 KB
/
fs.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
/*
* Copyright (c) 2016 Intel Corporation.
* Copyright (c) 2020-2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_FS_FS_H_
#define ZEPHYR_INCLUDE_FS_FS_H_
#include <sys/types.h>
#include <zephyr/sys/dlist.h>
#include <zephyr/fs/fs_interface.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief File System APIs
* @defgroup file_system_api File System APIs
* @since 1.5
* @version 1.0.0
* @ingroup os_services
* @{
*/
struct fs_file_system_t;
/**
* @brief Enumeration for directory entry types
*/
enum fs_dir_entry_type {
/** Identifier for file entry */
FS_DIR_ENTRY_FILE = 0,
/** Identifier for directory entry */
FS_DIR_ENTRY_DIR
};
/** @brief Enumeration to uniquely identify file system types.
*
* Zephyr supports in-tree file systems and external ones. Each
* requires a unique identifier used to register the file system
* implementation and to associate a mount point with the file system
* type. This anonymous enum defines global identifiers for the
* in-tree file systems.
*
* External file systems should be registered using unique identifiers
* starting at @c FS_TYPE_EXTERNAL_BASE. It is the responsibility of
* applications that use external file systems to ensure that these
* identifiers are unique if multiple file system implementations are
* used by the application.
*/
enum {
/** Identifier for in-tree FatFS file system. */
FS_FATFS = 0,
/** Identifier for in-tree LittleFS file system. */
FS_LITTLEFS,
/** Identifier for in-tree Ext2 file system. */
FS_EXT2,
/** Base identifier for external file systems. */
FS_TYPE_EXTERNAL_BASE,
};
/** Flag prevents formatting device if requested file system not found */
#define FS_MOUNT_FLAG_NO_FORMAT BIT(0)
/** Flag makes mounted file system read-only */
#define FS_MOUNT_FLAG_READ_ONLY BIT(1)
/** Flag used in pre-defined mount structures that are to be mounted
* on startup.
*
* This flag has no impact in user-defined mount structures.
*/
#define FS_MOUNT_FLAG_AUTOMOUNT BIT(2)
/** Flag requests file system driver to use Disk Access API. When the flag is
* set to the fs_mount_t.flags prior to fs_mount call, a file system
* needs to use the Disk Access API, otherwise mount callback for the driver
* should return -ENOSUP; when the flag is not set the file system driver
* should use Flash API by default, unless it only supports Disc Access API.
* When file system will use Disk Access API and the flag is not set, the mount
* callback for the file system should set the flag on success.
*/
#define FS_MOUNT_FLAG_USE_DISK_ACCESS BIT(3)
/**
* @brief File system mount info structure
*/
struct fs_mount_t {
/** Entry for the fs_mount_list list */
sys_dnode_t node;
/** File system type */
int type;
/** Mount point directory name (ex: "/fatfs") */
const char *mnt_point;
/** Pointer to file system specific data */
void *fs_data;
/** Pointer to backend storage device */
void *storage_dev;
/* The following fields are filled by file system core */
/** Length of Mount point string */
size_t mountp_len;
/** Pointer to File system interface of the mount point */
const struct fs_file_system_t *fs;
/** Mount flags */
uint8_t flags;
};
/**
* @brief Structure to receive file or directory information
*
* Used in functions that read the directory entries to get
* file or directory information.
*/
struct fs_dirent {
/**
* File/directory type (FS_DIR_ENTRY_FILE or FS_DIR_ENTRY_DIR)
*/
enum fs_dir_entry_type type;
/** Name of file or directory */
char name[MAX_FILE_NAME + 1];
/** Size of file (0 if directory). */
size_t size;
};
/**
* @brief Structure to receive volume statistics
*
* Used to retrieve information about total and available space
* in the volume.
*/
struct fs_statvfs {
/** Optimal transfer block size */
unsigned long f_bsize;
/** Allocation unit size */
unsigned long f_frsize;
/** Size of FS in f_frsize units */
unsigned long f_blocks;
/** Number of free blocks */
unsigned long f_bfree;
};
/**
* @name fs_open open and creation mode flags
* @{
*/
/** Open for read flag */
#define FS_O_READ 0x01
/** Open for write flag */
#define FS_O_WRITE 0x02
/** Open for read-write flag combination */
#define FS_O_RDWR (FS_O_READ | FS_O_WRITE)
/** Bitmask for read and write flags */
#define FS_O_MODE_MASK 0x03
/** Create file if it does not exist */
#define FS_O_CREATE 0x10
/** Open/create file for append */
#define FS_O_APPEND 0x20
/** Bitmask for open/create flags */
#define FS_O_FLAGS_MASK 0x30
/** Bitmask for open flags */
#define FS_O_MASK (FS_O_MODE_MASK | FS_O_FLAGS_MASK)
/**
* @}
*/
/**
* @name fs_seek whence parameter values
* @{
*/
#ifndef FS_SEEK_SET
/** Seek from the beginning of file */
#define FS_SEEK_SET 0
#endif
#ifndef FS_SEEK_CUR
/** Seek from a current position */
#define FS_SEEK_CUR 1
#endif
#ifndef FS_SEEK_END
/** Seek from the end of file */
#define FS_SEEK_END 2
#endif
/**
* @}
*/
/**
* @brief Get the common mount flags for an fstab entry.
* @param node_id the node identifier for a child entry in a
* zephyr,fstab node.
* @return a value suitable for initializing an fs_mount_t flags
* member.
*/
#define FSTAB_ENTRY_DT_MOUNT_FLAGS(node_id) \
((DT_PROP(node_id, automount) ? FS_MOUNT_FLAG_AUTOMOUNT : 0) \
| (DT_PROP(node_id, read_only) ? FS_MOUNT_FLAG_READ_ONLY : 0) \
| (DT_PROP(node_id, no_format) ? FS_MOUNT_FLAG_NO_FORMAT : 0) \
| (DT_PROP(node_id, disk_access) ? FS_MOUNT_FLAG_USE_DISK_ACCESS : 0))
/**
* @brief The name under which a zephyr,fstab entry mount structure is
* defined.
*
* @param node_id the node identifier for a child entry in a zephyr,fstab node.
*/
#define FS_FSTAB_ENTRY(node_id) _CONCAT(z_fsmp_, node_id)
/**
* @brief Generate a declaration for the externally defined fstab
* entry.
*
* This will evaluate to the name of a struct fs_mount_t object.
*
* @param node_id the node identifier for a child entry in a zephyr,fstab node.
*/
#define FS_FSTAB_DECLARE_ENTRY(node_id) \
extern struct fs_mount_t FS_FSTAB_ENTRY(node_id)
/**
* @brief Initialize fs_file_t object
*
* Initializes the fs_file_t object; the function needs to be invoked
* on object before first use with fs_open.
*
* @param zfp Pointer to file object
*
*/
static inline void fs_file_t_init(struct fs_file_t *zfp)
{
zfp->filep = NULL;
zfp->mp = NULL;
zfp->flags = 0;
}
/**
* @brief Initialize fs_dir_t object
*
* Initializes the fs_dir_t object; the function needs to be invoked
* on object before first use with fs_opendir.
*
* @param zdp Pointer to file object
*
*/
static inline void fs_dir_t_init(struct fs_dir_t *zdp)
{
zdp->dirp = NULL;
zdp->mp = NULL;
}
/**
* @brief Open or create file
*
* Opens or possibly creates a file and associates a stream with it.
* Successfully opened file, when no longer in use, should be closed
* with fs_close().
*
* @details
* @p flags can be 0 or a binary combination of one or more of the following
* identifiers:
* - @c FS_O_READ open for read
* - @c FS_O_WRITE open for write
* - @c FS_O_RDWR open for read/write (<tt>FS_O_READ | FS_O_WRITE</tt>)
* - @c FS_O_CREATE create file if it does not exist
* - @c FS_O_APPEND move to end of file before each write
*
* @warning If @p flags are set to 0 the function will open file, if it exists
* and is accessible, but you will have no read/write access to it.
*
* @param zfp Pointer to a file object
* @param file_name The name of a file to open
* @param flags The mode flags
*
* @retval 0 on success;
* @retval -EBUSY when zfp is already used;
* @retval -EINVAL when a bad file name is given;
* @retval -EROFS when opening read-only file for write, or attempting to
* create a file on a system that has been mounted with the
* FS_MOUNT_FLAG_READ_ONLY flag;
* @retval -ENOENT when the file does not exist at the path;
* @retval -ENOTSUP when not implemented by underlying file system driver;
* @retval <0 an other negative errno code, depending on a file system back-end.
*/
int fs_open(struct fs_file_t *zfp, const char *file_name, fs_mode_t flags);
/**
* @brief Close file
*
* Flushes the associated stream and closes the file.
*
* @param zfp Pointer to the file object
*
* @retval 0 on success;
* @retval -ENOTSUP when not implemented by underlying file system driver;
* @retval <0 a negative errno code on error.
*/
int fs_close(struct fs_file_t *zfp);
/**
* @brief Unlink file
*
* Deletes the specified file or directory
*
* @param path Path to the file or directory to delete
*
* @retval 0 on success;
* @retval -EINVAL when a bad file name is given;
* @retval -EROFS if file is read-only, or when file system has been mounted
* with the FS_MOUNT_FLAG_READ_ONLY flag;
* @retval -ENOTSUP when not implemented by underlying file system driver;
* @retval <0 an other negative errno code on error.
*/
int fs_unlink(const char *path);
/**
* @brief Rename file or directory
*
* Performs a rename and / or move of the specified source path to the
* specified destination. The source path can refer to either a file or a
* directory. All intermediate directories in the destination path must
* already exist. If the source path refers to a file, the destination path
* must contain a full filename path, rather than just the new parent
* directory. If an object already exists at the specified destination path,
* this function causes it to be unlinked prior to the rename (i.e., the
* destination gets clobbered).
* @note Current implementation does not allow moving files between mount
* points.
*
* @param from The source path
* @param to The destination path
*
* @retval 0 on success;
* @retval -EINVAL when a bad file name is given, or when rename would cause move
* between mount points;
* @retval -EROFS if file is read-only, or when file system has been mounted
* with the FS_MOUNT_FLAG_READ_ONLY flag;
* @retval -ENOTSUP when not implemented by underlying file system driver;
* @retval <0 an other negative errno code on error.
*/
int fs_rename(const char *from, const char *to);
/**
* @brief Read file
*
* Reads up to @p size bytes of data to @p ptr pointed buffer, returns number
* of bytes read. A returned value may be lower than @p size if there were
* fewer bytes available than requested.
*
* @param zfp Pointer to the file object
* @param ptr Pointer to the data buffer
* @param size Number of bytes to be read
*
* @retval >=0 a number of bytes read, on success;
* @retval -EBADF when invoked on zfp that represents unopened/closed file;
* @retval -ENOTSUP when not implemented by underlying file system driver;
* @retval <0 a negative errno code on error.
*/
ssize_t fs_read(struct fs_file_t *zfp, void *ptr, size_t size);
/**
* @brief Write file
*
* Attempts to write @p size number of bytes to the specified file.
* If a negative value is returned from the function, the file pointer has not
* been advanced.
* If the function returns a non-negative number that is lower than @p size,
* the global @c errno variable should be checked for an error code,
* as the device may have no free space for data.
*
* @param zfp Pointer to the file object
* @param ptr Pointer to the data buffer
* @param size Number of bytes to be written
*
* @retval >=0 a number of bytes written, on success;
* @retval -EBADF when invoked on zfp that represents unopened/closed file;
* @retval -ENOTSUP when not implemented by underlying file system driver;
* @retval <0 an other negative errno code on error.
*/
ssize_t fs_write(struct fs_file_t *zfp, const void *ptr, size_t size);
/**
* @brief Seek file
*
* Moves the file position to a new location in the file. The @p offset is added
* to file position based on the @p whence parameter.
*
* @param zfp Pointer to the file object
* @param offset Relative location to move the file pointer to
* @param whence Relative location from where offset is to be calculated.
* - @c FS_SEEK_SET for the beginning of the file;
* - @c FS_SEEK_CUR for the current position;
* - @c FS_SEEK_END for the end of the file.
*
* @retval 0 on success;
* @retval -EBADF when invoked on zfp that represents unopened/closed file;
* @retval -ENOTSUP if not supported by underlying file system driver;
* @retval <0 an other negative errno code on error.
*/
int fs_seek(struct fs_file_t *zfp, off_t offset, int whence);
/**
* @brief Get current file position.
*
* Retrieves and returns the current position in the file stream.
*
* @param zfp Pointer to the file object
*
* @retval >= 0 a current position in file;
* @retval -EBADF when invoked on zfp that represents unopened/closed file;
* @retval -ENOTSUP if not supported by underlying file system driver;
* @retval <0 an other negative errno code on error.
*
* The current revision does not validate the file object.
*/
off_t fs_tell(struct fs_file_t *zfp);
/**
* @brief Truncate or extend an open file to a given size
*
* Truncates the file to the new length if it is shorter than the current
* size of the file. Expands the file if the new length is greater than the
* current size of the file. The expanded region would be filled with zeroes.
*
* @note In the case of expansion, if the volume got full during the
* expansion process, the function will expand to the maximum possible length
* and return success. Caller should check if the expanded size matches the
* requested length.
*
* @param zfp Pointer to the file object
* @param length New size of the file in bytes
*
* @retval 0 on success;
* @retval -EBADF when invoked on zfp that represents unopened/closed file;
* @retval -ENOTSUP when not implemented by underlying file system driver;
* @retval <0 an other negative errno code on error.
*/
int fs_truncate(struct fs_file_t *zfp, off_t length);
/**
* @brief Flush cached write data buffers of an open file
*
* The function flushes the cache of an open file; it can be invoked to ensure
* data gets written to the storage media immediately, e.g. to avoid data loss
* in case if power is removed unexpectedly.
* @note Closing a file will cause caches to be flushed correctly so the
* function need not be called when the file is being closed.
*
* @param zfp Pointer to the file object
*
* @retval 0 on success;
* @retval -EBADF when invoked on zfp that represents unopened/closed file;
* @retval -ENOTSUP when not implemented by underlying file system driver;
* @retval <0 a negative errno code on error.
*/
int fs_sync(struct fs_file_t *zfp);
/**
* @brief Directory create
*
* Creates a new directory using specified path.
*
* @param path Path to the directory to create
*
* @retval 0 on success;
* @retval -EEXIST if entry of given name exists;
* @retval -EROFS if @p path is within read-only directory, or when
* file system has been mounted with the FS_MOUNT_FLAG_READ_ONLY flag;
* @retval -ENOTSUP when not implemented by underlying file system driver;
* @retval <0 an other negative errno code on error
*/
int fs_mkdir(const char *path);
/**
* @brief Directory open
*
* Opens an existing directory specified by the path.
*
* @param zdp Pointer to the directory object
* @param path Path to the directory to open
*
* @retval 0 on success;
* @retval -EINVAL when a bad directory path is given;
* @retval -EBUSY when zdp is already used;
* @retval -ENOTSUP when not implemented by underlying file system driver;
* @retval <0 a negative errno code on error.
*/
int fs_opendir(struct fs_dir_t *zdp, const char *path);
/**
* @brief Directory read entry
*
* Reads directory entries of an open directory. In end-of-dir condition,
* the function will return 0 and set the <tt>entry->name[0]</tt> to 0.
*
* @note: Most existing underlying file systems do not generate POSIX
* special directory entries "." or "..". For consistency the
* abstraction layer will remove these from lower layer results so
* higher layers see consistent results.
*
* @param zdp Pointer to the directory object
* @param entry Pointer to zfs_dirent structure to read the entry into
*
* @retval 0 on success or end-of-dir;
* @retval -ENOENT when no such directory found;
* @retval -ENOTSUP when not implemented by underlying file system driver;
* @retval <0 a negative errno code on error.
*/
int fs_readdir(struct fs_dir_t *zdp, struct fs_dirent *entry);
/**
* @brief Directory close
*
* Closes an open directory.
*
* @param zdp Pointer to the directory object
*
* @retval 0 on success;
* @retval -ENOTSUP when not implemented by underlying file system driver;
* @retval <0 a negative errno code on error.
*/
int fs_closedir(struct fs_dir_t *zdp);
/**
* @brief Mount filesystem
*
* Perform steps needed for mounting a file system like
* calling the file system specific mount function and adding
* the mount point to mounted file system list.
*
* @note Current implementation of ELM FAT driver allows only following mount
* points: "/RAM:","/NAND:","/CF:","/SD:","/SD2:","/USB:","/USB2:","/USB3:"
* or mount points that consist of single digit, e.g: "/0:", "/1:" and so forth.
*
* @param mp Pointer to the fs_mount_t structure. Referenced object
* is not changed if the mount operation failed.
* A reference is captured in the fs infrastructure if the
* mount operation succeeds, and the application must not
* mutate the structure contents until fs_unmount is
* successfully invoked on the same pointer.
*
* @retval 0 on success;
* @retval -ENOENT when file system type has not been registered;
* @retval -ENOTSUP when not supported by underlying file system driver;
* when @c FS_MOUNT_FLAG_USE_DISK_ACCESS is set but driver does not
* support it.
* @retval -EROFS if system requires formatting but @c FS_MOUNT_FLAG_READ_ONLY
* has been set;
* @retval <0 an other negative errno code on error.
*/
int fs_mount(struct fs_mount_t *mp);
/**
* @brief Unmount filesystem
*
* Perform steps needed to unmount a file system like
* calling the file system specific unmount function and removing
* the mount point from mounted file system list.
*
* @param mp Pointer to the fs_mount_t structure
*
* @retval 0 on success;
* @retval -EINVAL if no system has been mounted at given mount point;
* @retval -ENOTSUP when not supported by underlying file system driver;
* @retval <0 an other negative errno code on error.
*/
int fs_unmount(struct fs_mount_t *mp);
/**
* @brief Get path of mount point at index
*
* This function iterates through the list of mount points and returns
* the directory name of the mount point at the given @p index.
* On success @p index is incremented and @p name is set to the mount directory
* name. If a mount point with the given @p index does not exist, @p name will
* be set to @c NULL.
*
* @param index Pointer to mount point index
* @param name Pointer to pointer to path name
*
* @retval 0 on success;
* @retval -ENOENT if there is no mount point with given index.
*/
int fs_readmount(int *index, const char **name);
/**
* @brief File or directory status
*
* Checks the status of a file or directory specified by the @p path.
* @note The file on a storage device may not be updated until it is closed.
*
* @param path Path to the file or directory
* @param entry Pointer to the zfs_dirent structure to fill if the file or
* directory exists.
*
* @retval 0 on success;
* @retval -EINVAL when a bad directory or file name is given;
* @retval -ENOENT when no such directory or file is found;
* @retval -ENOTSUP when not supported by underlying file system driver;
* @retval <0 negative errno code on error.
*/
int fs_stat(const char *path, struct fs_dirent *entry);
/**
* @brief Retrieves statistics of the file system volume
*
* Returns the total and available space in the file system volume.
*
* @param path Path to the mounted directory
* @param stat Pointer to the zfs_statvfs structure to receive the fs
* statistics.
*
* @retval 0 on success;
* @retval -EINVAL when a bad path to a directory, or a file, is given;
* @retval -ENOTSUP when not implemented by underlying file system driver;
* @retval <0 an other negative errno code on error.
*/
int fs_statvfs(const char *path, struct fs_statvfs *stat);
/**
* @brief Create fresh file system
*
* @param fs_type Type of file system to create.
* @param dev_id Id of storage device.
* @param cfg Backend dependent init object. If NULL then default configuration is used.
* @param flags Additional flags for file system implementation.
*
* @retval 0 on success;
* @retval <0 negative errno code on error.
*/
int fs_mkfs(int fs_type, uintptr_t dev_id, void *cfg, int flags);
/**
* @brief Register a file system
*
* Register file system with virtual file system.
* Number of allowed file system types to be registered is controlled with the
* CONFIG_FILE_SYSTEM_MAX_TYPES Kconfig option.
*
* @param type Type of file system (ex: @c FS_FATFS)
* @param fs Pointer to File system
*
* @retval 0 on success;
* @retval -EALREADY when a file system of a given type has already been registered;
* @retval -ENOSCP when there is no space left, in file system registry, to add
* this file system type.
*/
int fs_register(int type, const struct fs_file_system_t *fs);
/**
* @brief Unregister a file system
*
* Unregister file system from virtual file system.
*
* @param type Type of file system (ex: @c FS_FATFS)
* @param fs Pointer to File system
*
* @retval 0 on success;
* @retval -EINVAL when file system of a given type has not been registered.
*/
int fs_unregister(int type, const struct fs_file_system_t *fs);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_FS_FS_H_ */