Mbed OS Reference
Loading...
Searching...
No Matches
lfs2.h
1/*
2 * The little filesystem
3 *
4 * Copyright (c) 2017, Arm Limited. All rights reserved.
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7#ifndef LFS2_H
8#define LFS2_H
9
10#include <stdint.h>
11#include <stdbool.h>
12
13#ifdef __cplusplus
14extern "C"
15{
16#endif
17
18
19/// Version info ///
20
21// Software library version
22// Major (top-nibble), incremented on backwards incompatible changes
23// Minor (bottom-nibble), incremented on feature additions
24#define LFS2_VERSION 0x00020002
25#define LFS2_VERSION_MAJOR (0xffff & (LFS2_VERSION >> 16))
26#define LFS2_VERSION_MINOR (0xffff & (LFS2_VERSION >> 0))
27
28// Version of On-disk data structures
29// Major (top-nibble), incremented on backwards incompatible changes
30// Minor (bottom-nibble), incremented on feature additions
31#define LFS2_DISK_VERSION 0x00020000
32#define LFS2_DISK_VERSION_MAJOR (0xffff & (LFS2_DISK_VERSION >> 16))
33#define LFS2_DISK_VERSION_MINOR (0xffff & (LFS2_DISK_VERSION >> 0))
34
35
36/// Definitions ///
37
38// Type definitions
39typedef uint32_t lfs2_size_t;
40typedef uint32_t lfs2_off_t;
41
42typedef int32_t lfs2_ssize_t;
43typedef int32_t lfs2_soff_t;
44
45typedef uint32_t lfs2_block_t;
46
47// Maximum name size in bytes, may be redefined to reduce the size of the
48// info struct. Limited to <= 1022. Stored in superblock and must be
49// respected by other littlefs drivers.
50#ifndef LFS2_NAME_MAX
51#define LFS2_NAME_MAX 255
52#endif
53
54// Maximum size of a file in bytes, may be redefined to limit to support other
55// drivers. Limited on disk to <= 4294967296. However, above 2147483647 the
56// functions lfs2_file_seek, lfs2_file_size, and lfs2_file_tell will return
57// incorrect values due to using signed integers. Stored in superblock and
58// must be respected by other littlefs drivers.
59#ifndef LFS2_FILE_MAX
60#define LFS2_FILE_MAX 2147483647
61#endif
62
63// Maximum size of custom attributes in bytes, may be redefined, but there is
64// no real benefit to using a smaller LFS2_ATTR_MAX. Limited to <= 1022.
65#ifndef LFS2_ATTR_MAX
66#define LFS2_ATTR_MAX 1022
67#endif
68
69// Possible error codes, these are negative to allow
70// valid positive return values
71enum lfs2_error {
72 LFS2_ERR_OK = 0, // No error
73 LFS2_ERR_IO = -5, // Error during device operation
74 LFS2_ERR_CORRUPT = -84, // Corrupted
75 LFS2_ERR_NOENT = -2, // No directory entry
76 LFS2_ERR_EXIST = -17, // Entry already exists
77 LFS2_ERR_NOTDIR = -20, // Entry is not a dir
78 LFS2_ERR_ISDIR = -21, // Entry is a dir
79 LFS2_ERR_NOTEMPTY = -39, // Dir is not empty
80 LFS2_ERR_BADF = -9, // Bad file number
81 LFS2_ERR_FBIG = -27, // File too large
82 LFS2_ERR_INVAL = -22, // Invalid parameter
83 LFS2_ERR_NOSPC = -28, // No space left on device
84 LFS2_ERR_NOMEM = -12, // No more memory available
85 LFS2_ERR_NOATTR = -61, // No data/attr available
86 LFS2_ERR_NAMETOOLONG = -36, // File name too long
87};
88
89// File types
90enum lfs2_type {
91 // file types
92 LFS2_TYPE_REG = 0x001,
93 LFS2_TYPE_DIR = 0x002,
94
95 // internally used types
96 LFS2_TYPE_SPLICE = 0x400,
97 LFS2_TYPE_NAME = 0x000,
98 LFS2_TYPE_STRUCT = 0x200,
99 LFS2_TYPE_USERATTR = 0x300,
100 LFS2_TYPE_FROM = 0x100,
101 LFS2_TYPE_TAIL = 0x600,
102 LFS2_TYPE_GLOBALS = 0x700,
103 LFS2_TYPE_CRC = 0x500,
104
105 // internally used type specializations
106 LFS2_TYPE_CREATE = 0x401,
107 LFS2_TYPE_DELETE = 0x4ff,
108 LFS2_TYPE_SUPERBLOCK = 0x0ff,
109 LFS2_TYPE_DIRSTRUCT = 0x200,
110 LFS2_TYPE_CTZSTRUCT = 0x202,
111 LFS2_TYPE_INLINESTRUCT = 0x201,
112 LFS2_TYPE_SOFTTAIL = 0x600,
113 LFS2_TYPE_HARDTAIL = 0x601,
114 LFS2_TYPE_MOVESTATE = 0x7ff,
115
116 // internal chip sources
117 LFS2_FROM_NOOP = 0x000,
118 LFS2_FROM_MOVE = 0x101,
119 LFS2_FROM_USERATTRS = 0x102,
120};
121
122// File open flags
123enum lfs2_open_flags {
124 // open flags
125 LFS2_O_RDONLY = 1, // Open a file as read only
126 LFS2_O_WRONLY = 2, // Open a file as write only
127 LFS2_O_RDWR = 3, // Open a file as read and write
128 LFS2_O_CREAT = 0x0100, // Create a file if it does not exist
129 LFS2_O_EXCL = 0x0200, // Fail if a file already exists
130 LFS2_O_TRUNC = 0x0400, // Truncate the existing file to zero size
131 LFS2_O_APPEND = 0x0800, // Move to end of file on every write
132
133 // internally used flags
134 LFS2_F_DIRTY = 0x010000, // File does not match storage
135 LFS2_F_WRITING = 0x020000, // File has been written since last flush
136 LFS2_F_READING = 0x040000, // File has been read since last flush
137 LFS2_F_ERRED = 0x080000, // An error occured during write
138 LFS2_F_INLINE = 0x100000, // Currently inlined in directory entry
139 LFS2_F_OPENED = 0x200000, // File has been opened
140};
141
142// File seek flags
143enum lfs2_whence_flags {
144 LFS2_SEEK_SET = 0, // Seek relative to an absolute position
145 LFS2_SEEK_CUR = 1, // Seek relative to the current file position
146 LFS2_SEEK_END = 2, // Seek relative to the end of the file
147};
148
149
150// Configuration provided during initialization of the littlefs
152 // Opaque user provided context that can be used to pass
153 // information to the block device operations
154 void *context;
155
156 // Read a region in a block. Negative error codes are propogated
157 // to the user.
158 int (*read)(const struct lfs2_config *c, lfs2_block_t block,
159 lfs2_off_t off, void *buffer, lfs2_size_t size);
160
161 // Program a region in a block. The block must have previously
162 // been erased. Negative error codes are propogated to the user.
163 // May return LFS2_ERR_CORRUPT if the block should be considered bad.
164 int (*prog)(const struct lfs2_config *c, lfs2_block_t block,
165 lfs2_off_t off, const void *buffer, lfs2_size_t size);
166
167 // Erase a block. A block must be erased before being programmed.
168 // The state of an erased block is undefined. Negative error codes
169 // are propogated to the user.
170 // May return LFS2_ERR_CORRUPT if the block should be considered bad.
171 int (*erase)(const struct lfs2_config *c, lfs2_block_t block);
172
173 // Sync the state of the underlying block device. Negative error codes
174 // are propogated to the user.
175 int (*sync)(const struct lfs2_config *c);
176
177 // Minimum size of a block read. All read operations will be a
178 // multiple of this value.
179 lfs2_size_t read_size;
180
181 // Minimum size of a block program. All program operations will be a
182 // multiple of this value.
183 lfs2_size_t prog_size;
184
185 // Size of an erasable block. This does not impact ram consumption and
186 // may be larger than the physical erase size. However, non-inlined files
187 // take up at minimum one block. Must be a multiple of the read
188 // and program sizes.
189 lfs2_size_t block_size;
190
191 // Number of erasable blocks on the device.
192 lfs2_size_t block_count;
193
194 // Number of erase cycles before littlefs evicts metadata logs and moves
195 // the metadata to another block. Suggested values are in the
196 // range 100-1000, with large values having better performance at the cost
197 // of less consistent wear distribution.
198 //
199 // Set to -1 to disable block-level wear-leveling.
200 int32_t block_cycles;
201
202 // Size of block caches. Each cache buffers a portion of a block in RAM.
203 // The littlefs needs a read cache, a program cache, and one additional
204 // cache per file. Larger caches can improve performance by storing more
205 // data and reducing the number of disk accesses. Must be a multiple of
206 // the read and program sizes, and a factor of the block size.
207 lfs2_size_t cache_size;
208
209 // Size of the lookahead buffer in bytes. A larger lookahead buffer
210 // increases the number of blocks found during an allocation pass. The
211 // lookahead buffer is stored as a compact bitmap, so each byte of RAM
212 // can track 8 blocks. Must be a multiple of 8.
213 lfs2_size_t lookahead_size;
214
215 // Optional statically allocated read buffer. Must be cache_size.
216 // By default lfs2_malloc is used to allocate this buffer.
217 void *read_buffer;
218
219 // Optional statically allocated program buffer. Must be cache_size.
220 // By default lfs2_malloc is used to allocate this buffer.
221 void *prog_buffer;
222
223 // Optional statically allocated lookahead buffer. Must be lookahead_size
224 // and aligned to a 32-bit boundary. By default lfs2_malloc is used to
225 // allocate this buffer.
226 void *lookahead_buffer;
227
228 // Optional upper limit on length of file names in bytes. No downside for
229 // larger names except the size of the info struct which is controlled by
230 // the LFS2_NAME_MAX define. Defaults to LFS2_NAME_MAX when zero. Stored in
231 // superblock and must be respected by other littlefs drivers.
232 lfs2_size_t name_max;
233
234 // Optional upper limit on files in bytes. No downside for larger files
235 // but must be <= LFS2_FILE_MAX. Defaults to LFS2_FILE_MAX when zero. Stored
236 // in superblock and must be respected by other littlefs drivers.
237 lfs2_size_t file_max;
238
239 // Optional upper limit on custom attributes in bytes. No downside for
240 // larger attributes size but must be <= LFS2_ATTR_MAX. Defaults to
241 // LFS2_ATTR_MAX when zero.
242 lfs2_size_t attr_max;
243};
244
245// File info structure
246struct lfs2_info {
247 // Type of the file, either LFS2_TYPE_REG or LFS2_TYPE_DIR
248 uint8_t type;
249
250 // Size of the file, only valid for REG files. Limited to 32-bits.
251 lfs2_size_t size;
252
253 // Name of the file stored as a null-terminated string. Limited to
254 // LFS2_NAME_MAX+1, which can be changed by redefining LFS2_NAME_MAX to
255 // reduce RAM. LFS2_NAME_MAX is stored in superblock and must be
256 // respected by other littlefs drivers.
257 char name[LFS2_NAME_MAX+1];
258};
259
260// Custom attribute structure, used to describe custom attributes
261// committed atomically during file writes.
262struct lfs2_attr {
263 // 8-bit type of attribute, provided by user and used to
264 // identify the attribute
265 uint8_t type;
266
267 // Pointer to buffer containing the attribute
268 void *buffer;
269
270 // Size of attribute in bytes, limited to LFS2_ATTR_MAX
271 lfs2_size_t size;
272};
273
274// Optional configuration provided during lfs2_file_opencfg
276 // Optional statically allocated file buffer. Must be cache_size.
277 // By default lfs2_malloc is used to allocate this buffer.
278 void *buffer;
279
280 // Optional list of custom attributes related to the file. If the file
281 // is opened with read access, these attributes will be read from disk
282 // during the open call. If the file is opened with write access, the
283 // attributes will be written to disk every file sync or close. This
284 // write occurs atomically with update to the file's contents.
285 //
286 // Custom attributes are uniquely identified by an 8-bit type and limited
287 // to LFS2_ATTR_MAX bytes. When read, if the stored attribute is smaller
288 // than the buffer, it will be padded with zeros. If the stored attribute
289 // is larger, then it will be silently truncated. If the attribute is not
290 // found, it will be created implicitly.
291 struct lfs2_attr *attrs;
292
293 // Number of custom attributes in the list
294 lfs2_size_t attr_count;
295};
296
297
298/// internal littlefs data structures ///
299typedef struct lfs2_cache {
300 lfs2_block_t block;
301 lfs2_off_t off;
302 lfs2_size_t size;
303 uint8_t *buffer;
305
306typedef struct lfs2_mdir {
307 lfs2_block_t pair[2];
308 uint32_t rev;
309 lfs2_off_t off;
310 uint32_t etag;
311 uint16_t count;
312 bool erased;
313 bool split;
314 lfs2_block_t tail[2];
316
317// littlefs directory type
318typedef struct lfs2_dir {
319 struct lfs2_dir *next;
320 uint16_t id;
321 uint8_t type;
322 lfs2_mdir_t m;
323
324 lfs2_off_t pos;
325 lfs2_block_t head[2];
326} lfs2_dir_t;
327
328// littlefs file type
329typedef struct lfs2_file {
330 struct lfs2_file *next;
331 uint16_t id;
332 uint8_t type;
333 lfs2_mdir_t m;
334
335 struct lfs2_ctz {
336 lfs2_block_t head;
337 lfs2_size_t size;
338 } ctz;
339
340 uint32_t flags;
341 lfs2_off_t pos;
342 lfs2_block_t block;
343 lfs2_off_t off;
344 lfs2_cache_t cache;
345
346 const struct lfs2_file_config *cfg;
348
349typedef struct lfs2_superblock {
350 uint32_t version;
351 lfs2_size_t block_size;
352 lfs2_size_t block_count;
353 lfs2_size_t name_max;
354 lfs2_size_t file_max;
355 lfs2_size_t attr_max;
357
358typedef struct lfs2_gstate {
359 uint32_t tag;
360 lfs2_block_t pair[2];
362
363// The littlefs filesystem type
364typedef struct lfs2 {
365 lfs2_cache_t rcache;
366 lfs2_cache_t pcache;
367
368 lfs2_block_t root[2];
369 struct lfs2_mlist {
370 struct lfs2_mlist *next;
371 uint16_t id;
372 uint8_t type;
373 lfs2_mdir_t m;
374 } *mlist;
375 uint32_t seed;
376
377 lfs2_gstate_t gstate;
378 lfs2_gstate_t gdisk;
379 lfs2_gstate_t gdelta;
380
381 struct lfs2_free {
382 lfs2_block_t off;
383 lfs2_block_t size;
384 lfs2_block_t i;
385 lfs2_block_t ack;
386 uint32_t *buffer;
387 } free;
388
389 const struct lfs2_config *cfg;
390 lfs2_size_t name_max;
391 lfs2_size_t file_max;
392 lfs2_size_t attr_max;
393
394#ifdef LFS2_MIGRATE
395 struct lfs21 *lfs21;
396#endif
397} lfs2_t;
398
399
400/// Filesystem functions ///
401
402// Format a block device with the littlefs
403//
404// Requires a littlefs object and config struct. This clobbers the littlefs
405// object, and does not leave the filesystem mounted. The config struct must
406// be zeroed for defaults and backwards compatibility.
407//
408// Returns a negative error code on failure.
409int lfs2_format(lfs2_t *lfs2, const struct lfs2_config *config);
410
411// Mounts a littlefs
412//
413// Requires a littlefs object and config struct. Multiple filesystems
414// may be mounted simultaneously with multiple littlefs objects. Both
415// lfs2 and config must be allocated while mounted. The config struct must
416// be zeroed for defaults and backwards compatibility.
417//
418// Returns a negative error code on failure.
419int lfs2_mount(lfs2_t *lfs2, const struct lfs2_config *config);
420
421// Unmounts a littlefs
422//
423// Does nothing besides releasing any allocated resources.
424// Returns a negative error code on failure.
425int lfs2_unmount(lfs2_t *lfs2);
426
427/// General operations ///
428
429// Removes a file or directory
430//
431// If removing a directory, the directory must be empty.
432// Returns a negative error code on failure.
433int lfs2_remove(lfs2_t *lfs2, const char *path);
434
435// Rename or move a file or directory
436//
437// If the destination exists, it must match the source in type.
438// If the destination is a directory, the directory must be empty.
439//
440// Returns a negative error code on failure.
441int lfs2_rename(lfs2_t *lfs2, const char *oldpath, const char *newpath);
442
443// Find info about a file or directory
444//
445// Fills out the info structure, based on the specified file or directory.
446// Returns a negative error code on failure.
447int lfs2_stat(lfs2_t *lfs2, const char *path, struct lfs2_info *info);
448
449// Get a custom attribute
450//
451// Custom attributes are uniquely identified by an 8-bit type and limited
452// to LFS2_ATTR_MAX bytes. When read, if the stored attribute is smaller than
453// the buffer, it will be padded with zeros. If the stored attribute is larger,
454// then it will be silently truncated. If no attribute is found, the error
455// LFS2_ERR_NOATTR is returned and the buffer is filled with zeros.
456//
457// Returns the size of the attribute, or a negative error code on failure.
458// Note, the returned size is the size of the attribute on disk, irrespective
459// of the size of the buffer. This can be used to dynamically allocate a buffer
460// or check for existance.
461lfs2_ssize_t lfs2_getattr(lfs2_t *lfs2, const char *path,
462 uint8_t type, void *buffer, lfs2_size_t size);
463
464// Set custom attributes
465//
466// Custom attributes are uniquely identified by an 8-bit type and limited
467// to LFS2_ATTR_MAX bytes. If an attribute is not found, it will be
468// implicitly created.
469//
470// Returns a negative error code on failure.
471int lfs2_setattr(lfs2_t *lfs2, const char *path,
472 uint8_t type, const void *buffer, lfs2_size_t size);
473
474// Removes a custom attribute
475//
476// If an attribute is not found, nothing happens.
477//
478// Returns a negative error code on failure.
479int lfs2_removeattr(lfs2_t *lfs2, const char *path, uint8_t type);
480
481
482/// File operations ///
483
484// Open a file
485//
486// The mode that the file is opened in is determined by the flags, which
487// are values from the enum lfs2_open_flags that are bitwise-ored together.
488//
489// Returns a negative error code on failure.
490int lfs2_file_open(lfs2_t *lfs2, lfs2_file_t *file,
491 const char *path, int flags);
492
493// Open a file with extra configuration
494//
495// The mode that the file is opened in is determined by the flags, which
496// are values from the enum lfs2_open_flags that are bitwise-ored together.
497//
498// The config struct provides additional config options per file as described
499// above. The config struct must be allocated while the file is open, and the
500// config struct must be zeroed for defaults and backwards compatibility.
501//
502// Returns a negative error code on failure.
503int lfs2_file_opencfg(lfs2_t *lfs2, lfs2_file_t *file,
504 const char *path, int flags,
505 const struct lfs2_file_config *config);
506
507// Close a file
508//
509// Any pending writes are written out to storage as though
510// sync had been called and releases any allocated resources.
511//
512// Returns a negative error code on failure.
513int lfs2_file_close(lfs2_t *lfs2, lfs2_file_t *file);
514
515// Synchronize a file on storage
516//
517// Any pending writes are written out to storage.
518// Returns a negative error code on failure.
519int lfs2_file_sync(lfs2_t *lfs2, lfs2_file_t *file);
520
521// Read data from file
522//
523// Takes a buffer and size indicating where to store the read data.
524// Returns the number of bytes read, or a negative error code on failure.
525lfs2_ssize_t lfs2_file_read(lfs2_t *lfs2, lfs2_file_t *file,
526 void *buffer, lfs2_size_t size);
527
528// Write data to file
529//
530// Takes a buffer and size indicating the data to write. The file will not
531// actually be updated on the storage until either sync or close is called.
532//
533// Returns the number of bytes written, or a negative error code on failure.
534lfs2_ssize_t lfs2_file_write(lfs2_t *lfs2, lfs2_file_t *file,
535 const void *buffer, lfs2_size_t size);
536
537// Change the position of the file
538//
539// The change in position is determined by the offset and whence flag.
540// Returns the new position of the file, or a negative error code on failure.
541lfs2_soff_t lfs2_file_seek(lfs2_t *lfs2, lfs2_file_t *file,
542 lfs2_soff_t off, int whence);
543
544// Truncates the size of the file to the specified size
545//
546// Returns a negative error code on failure.
547int lfs2_file_truncate(lfs2_t *lfs2, lfs2_file_t *file, lfs2_off_t size);
548
549// Return the position of the file
550//
551// Equivalent to lfs2_file_seek(lfs2, file, 0, LFS2_SEEK_CUR)
552// Returns the position of the file, or a negative error code on failure.
553lfs2_soff_t lfs2_file_tell(lfs2_t *lfs2, lfs2_file_t *file);
554
555// Change the position of the file to the beginning of the file
556//
557// Equivalent to lfs2_file_seek(lfs2, file, 0, LFS2_SEEK_SET)
558// Returns a negative error code on failure.
559int lfs2_file_rewind(lfs2_t *lfs2, lfs2_file_t *file);
560
561// Return the size of the file
562//
563// Similar to lfs2_file_seek(lfs2, file, 0, LFS2_SEEK_END)
564// Returns the size of the file, or a negative error code on failure.
565lfs2_soff_t lfs2_file_size(lfs2_t *lfs2, lfs2_file_t *file);
566
567
568/// Directory operations ///
569
570// Create a directory
571//
572// Returns a negative error code on failure.
573int lfs2_mkdir(lfs2_t *lfs2, const char *path);
574
575// Open a directory
576//
577// Once open a directory can be used with read to iterate over files.
578// Returns a negative error code on failure.
579int lfs2_dir_open(lfs2_t *lfs2, lfs2_dir_t *dir, const char *path);
580
581// Close a directory
582//
583// Releases any allocated resources.
584// Returns a negative error code on failure.
585int lfs2_dir_close(lfs2_t *lfs2, lfs2_dir_t *dir);
586
587// Read an entry in the directory
588//
589// Fills out the info structure, based on the specified file or directory.
590// Returns a positive value on success, 0 at the end of directory,
591// or a negative error code on failure.
592int lfs2_dir_read(lfs2_t *lfs2, lfs2_dir_t *dir, struct lfs2_info *info);
593
594// Change the position of the directory
595//
596// The new off must be a value previous returned from tell and specifies
597// an absolute offset in the directory seek.
598//
599// Returns a negative error code on failure.
600int lfs2_dir_seek(lfs2_t *lfs2, lfs2_dir_t *dir, lfs2_off_t off);
601
602// Return the position of the directory
603//
604// The returned offset is only meant to be consumed by seek and may not make
605// sense, but does indicate the current position in the directory iteration.
606//
607// Returns the position of the directory, or a negative error code on failure.
608lfs2_soff_t lfs2_dir_tell(lfs2_t *lfs2, lfs2_dir_t *dir);
609
610// Change the position of the directory to the beginning of the directory
611//
612// Returns a negative error code on failure.
613int lfs2_dir_rewind(lfs2_t *lfs2, lfs2_dir_t *dir);
614
615
616/// Filesystem-level filesystem operations
617
618// Finds the current size of the filesystem
619//
620// Note: Result is best effort. If files share COW structures, the returned
621// size may be larger than the filesystem actually is.
622//
623// Returns the number of allocated blocks, or a negative error code on failure.
624lfs2_ssize_t lfs2_fs_size(lfs2_t *lfs2);
625
626// Traverse through all blocks in use by the filesystem
627//
628// The provided callback will be called with each block address that is
629// currently in use by the filesystem. This can be used to determine which
630// blocks are in use or how much of the storage is available.
631//
632// Returns a negative error code on failure.
633int lfs2_fs_traverse(lfs2_t *lfs2, int (*cb)(void*, lfs2_block_t), void *data);
634
635#ifdef LFS2_MIGRATE
636// Attempts to migrate a previous version of littlefs
637//
638// Behaves similarly to the lfs2_format function. Attempts to mount
639// the previous version of littlefs and update the filesystem so it can be
640// mounted with the current version of littlefs.
641//
642// Requires a littlefs object and config struct. This clobbers the littlefs
643// object, and does not leave the filesystem mounted. The config struct must
644// be zeroed for defaults and backwards compatibility.
645//
646// Returns a negative error code on failure.
647int lfs2_migrate(lfs2_t *lfs2, const struct lfs2_config *cfg);
648#endif
649
650
651#ifdef __cplusplus
652} /* extern "C" */
653#endif
654
655#endif
The key size.
internal littlefs data structures ///
Definition: lfs2.h:299
Definition: lfs2.h:318
Definition: lfs2.h:364