Mistake on this page?
Report an issue in GitHub or email us
lfs.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 LFS_H
8 #define LFS_H
9 
10 #include <stdint.h>
11 #include <stdbool.h>
12 
13 #ifdef __cplusplus
14 extern "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 LFS_VERSION 0x00010006
25 #define LFS_VERSION_MAJOR (0xffff & (LFS_VERSION >> 16))
26 #define LFS_VERSION_MINOR (0xffff & (LFS_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 LFS_DISK_VERSION 0x00010001
32 #define LFS_DISK_VERSION_MAJOR (0xffff & (LFS_DISK_VERSION >> 16))
33 #define LFS_DISK_VERSION_MINOR (0xffff & (LFS_DISK_VERSION >> 0))
34 
35 
36 /// Definitions ///
37 
38 // Type definitions
39 typedef uint32_t lfs_size_t;
40 typedef uint32_t lfs_off_t;
41 
42 typedef int32_t lfs_ssize_t;
43 typedef int32_t lfs_soff_t;
44 
45 typedef uint32_t lfs_block_t;
46 
47 // Max name size in bytes
48 #ifndef LFS_NAME_MAX
49 #define LFS_NAME_MAX 255
50 #endif
51 
52 // Possible error codes, these are negative to allow
53 // valid positive return values
54 enum lfs_error {
55  LFS_ERR_OK = 0, // No error
56  LFS_ERR_IO = -5, // Error during device operation
57  LFS_ERR_CORRUPT = -52, // Corrupted
58  LFS_ERR_NOENT = -2, // No directory entry
59  LFS_ERR_EXIST = -17, // Entry already exists
60  LFS_ERR_NOTDIR = -20, // Entry is not a dir
61  LFS_ERR_ISDIR = -21, // Entry is a dir
62  LFS_ERR_NOTEMPTY = -39, // Dir is not empty
63  LFS_ERR_BADF = -9, // Bad file number
64  LFS_ERR_INVAL = -22, // Invalid parameter
65  LFS_ERR_NOSPC = -28, // No space left on device
66  LFS_ERR_NOMEM = -12, // No more memory available
67 };
68 
69 // File types
70 enum lfs_type {
71  LFS_TYPE_REG = 0x11,
72  LFS_TYPE_DIR = 0x22,
73  LFS_TYPE_SUPERBLOCK = 0x2e,
74 };
75 
76 // File open flags
77 enum lfs_open_flags {
78  // open flags
79  LFS_O_RDONLY = 1, // Open a file as read only
80  LFS_O_WRONLY = 2, // Open a file as write only
81  LFS_O_RDWR = 3, // Open a file as read and write
82  LFS_O_CREAT = 0x0100, // Create a file if it does not exist
83  LFS_O_EXCL = 0x0200, // Fail if a file already exists
84  LFS_O_TRUNC = 0x0400, // Truncate the existing file to zero size
85  LFS_O_APPEND = 0x0800, // Move to end of file on every write
86 
87  // internally used flags
88  LFS_F_DIRTY = 0x10000, // File does not match storage
89  LFS_F_WRITING = 0x20000, // File has been written since last flush
90  LFS_F_READING = 0x40000, // File has been read since last flush
91  LFS_F_ERRED = 0x80000, // An error occurred during write
92 };
93 
94 // File seek flags
95 enum lfs_whence_flags {
96  LFS_SEEK_SET = 0, // Seek relative to an absolute position
97  LFS_SEEK_CUR = 1, // Seek relative to the current file position
98  LFS_SEEK_END = 2, // Seek relative to the end of the file
99 };
100 
101 
102 // Configuration provided during initialization of the littlefs
103 struct lfs_config {
104  // Opaque user provided context that can be used to pass
105  // information to the block device operations
106  void *context;
107 
108  // Read a region in a block. Negative error codes are propogated
109  // to the user.
110  int (*read)(const struct lfs_config *c, lfs_block_t block,
111  lfs_off_t off, void *buffer, lfs_size_t size);
112 
113  // Program a region in a block. The block must have previously
114  // been erased. Negative error codes are propogated to the user.
115  // May return LFS_ERR_CORRUPT if the block should be considered bad.
116  int (*prog)(const struct lfs_config *c, lfs_block_t block,
117  lfs_off_t off, const void *buffer, lfs_size_t size);
118 
119  // Erase a block. A block must be erased before being programmed.
120  // The state of an erased block is undefined. Negative error codes
121  // are propogated to the user.
122  // May return LFS_ERR_CORRUPT if the block should be considered bad.
123  int (*erase)(const struct lfs_config *c, lfs_block_t block);
124 
125  // Sync the state of the underlying block device. Negative error codes
126  // are propogated to the user.
127  int (*sync)(const struct lfs_config *c);
128 
129  // Minimum size of a block read. This determines the size of read buffers.
130  // This may be larger than the physical read size to improve performance
131  // by caching more of the block device.
132  lfs_size_t read_size;
133 
134  // Minimum size of a block program. This determines the size of program
135  // buffers. This may be larger than the physical program size to improve
136  // performance by caching more of the block device.
137  // Must be a multiple of the read size.
138  lfs_size_t prog_size;
139 
140  // Size of an erasable block. This does not impact ram consumption and
141  // may be larger than the physical erase size. However, this should be
142  // kept small as each file currently takes up an entire block.
143  // Must be a multiple of the program size.
144  lfs_size_t block_size;
145 
146  // Number of erasable blocks on the device.
147  lfs_size_t block_count;
148 
149  // Number of blocks to lookahead during block allocation. A larger
150  // lookahead reduces the number of passes required to allocate a block.
151  // The lookahead buffer requires only 1 bit per block so it can be quite
152  // large with little ram impact. Should be a multiple of 32.
153  lfs_size_t lookahead;
154 
155  // Optional, statically allocated read buffer. Must be read sized.
156  void *read_buffer;
157 
158  // Optional, statically allocated program buffer. Must be program sized.
159  void *prog_buffer;
160 
161  // Optional, statically allocated lookahead buffer. Must be 1 bit per
162  // lookahead block.
163  void *lookahead_buffer;
164 
165  // Optional, statically allocated buffer for files. Must be program sized.
166  // If enabled, only one file may be opened at a time.
167  void *file_buffer;
168 };
169 
170 // Optional configuration provided during lfs_file_opencfg
172  // Optional, statically allocated buffer for files. Must be program sized.
173  // If NULL, malloc will be used by default.
174  void *buffer;
175 };
176 
177 // File info structure
178 struct lfs_info {
179  // Type of the file, either LFS_TYPE_REG or LFS_TYPE_DIR
180  uint8_t type;
181 
182  // Size of the file, only valid for REG files
183  lfs_size_t size;
184 
185  // Name of the file stored as a null-terminated string
186  char name[LFS_NAME_MAX+1];
187 };
188 
189 
190 /// littlefs data structures ///
191 typedef struct lfs_entry {
192  lfs_off_t off;
193 
194  struct lfs_disk_entry {
195  uint8_t type;
196  uint8_t elen;
197  uint8_t alen;
198  uint8_t nlen;
199  union {
200  struct {
201  lfs_block_t head;
202  lfs_size_t size;
203  } file;
204  lfs_block_t dir[2];
205  } u;
206  } d;
207 } lfs_entry_t;
208 
209 typedef struct lfs_cache {
210  lfs_block_t block;
211  lfs_off_t off;
212  uint8_t *buffer;
213 } lfs_cache_t;
214 
215 typedef struct lfs_file {
216  struct lfs_file *next;
217  lfs_block_t pair[2];
218  lfs_off_t poff;
219 
220  lfs_block_t head;
221  lfs_size_t size;
222 
223  const struct lfs_file_config *cfg;
224  uint32_t flags;
225  lfs_off_t pos;
226  lfs_block_t block;
227  lfs_off_t off;
228  lfs_cache_t cache;
229 } lfs_file_t;
230 
231 typedef struct lfs_dir {
232  struct lfs_dir *next;
233  lfs_block_t pair[2];
234  lfs_off_t off;
235 
236  lfs_block_t head[2];
237  lfs_off_t pos;
238 
239  struct lfs_disk_dir {
240  uint32_t rev;
241  lfs_size_t size;
242  lfs_block_t tail[2];
243  } d;
244 } lfs_dir_t;
245 
246 typedef struct lfs_superblock {
247  lfs_off_t off;
248 
250  uint8_t type;
251  uint8_t elen;
252  uint8_t alen;
253  uint8_t nlen;
254  lfs_block_t root[2];
255  uint32_t block_size;
256  uint32_t block_count;
257  uint32_t version;
258  char magic[8];
259  } d;
261 
262 typedef struct lfs_free {
263  lfs_block_t off;
264  lfs_block_t size;
265  lfs_block_t i;
266  lfs_block_t ack;
267  uint32_t *buffer;
268 } lfs_free_t;
269 
270 // The littlefs type
271 typedef struct lfs {
272  const struct lfs_config *cfg;
273 
274  lfs_block_t root[2];
275  lfs_file_t *files;
276  lfs_dir_t *dirs;
277 
278  lfs_cache_t rcache;
279  lfs_cache_t pcache;
280 
281  lfs_free_t free;
282  bool deorphaned;
283 } lfs_t;
284 
285 
286 /// Filesystem functions ///
287 
288 // Format a block device with the littlefs
289 //
290 // Requires a littlefs object and config struct. This clobbers the littlefs
291 // object, and does not leave the filesystem mounted. The config struct must
292 // be zeroed for defaults and backwards compatibility.
293 //
294 // Returns a negative error code on failure.
295 int lfs_format(lfs_t *lfs, const struct lfs_config *config);
296 
297 // Mounts a littlefs
298 //
299 // Requires a littlefs object and config struct. Multiple filesystems
300 // may be mounted simultaneously with multiple littlefs objects. Both
301 // lfs and config must be allocated while mounted. The config struct must
302 // be zeroed for defaults and backwards compatibility.
303 //
304 // Returns a negative error code on failure.
305 int lfs_mount(lfs_t *lfs, const struct lfs_config *config);
306 
307 // Unmounts a littlefs
308 //
309 // Does nothing besides releasing any allocated resources.
310 // Returns a negative error code on failure.
311 int lfs_unmount(lfs_t *lfs);
312 
313 /// General operations ///
314 
315 // Removes a file or directory
316 //
317 // If removing a directory, the directory must be empty.
318 // Returns a negative error code on failure.
319 int lfs_remove(lfs_t *lfs, const char *path);
320 
321 // Rename or move a file or directory
322 //
323 // If the destination exists, it must match the source in type.
324 // If the destination is a directory, the directory must be empty.
325 //
326 // Returns a negative error code on failure.
327 int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath);
328 
329 // Find info about a file or directory
330 //
331 // Fills out the info structure, based on the specified file or directory.
332 // Returns a negative error code on failure.
333 int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info);
334 
335 
336 /// File operations ///
337 
338 // Open a file
339 //
340 // The mode that the file is opened in is determined by the flags, which
341 // are values from the enum lfs_open_flags that are bitwise-ored together.
342 //
343 // Returns a negative error code on failure.
344 int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
345  const char *path, int flags);
346 
347 // Open a file with extra configuration
348 //
349 // The mode that the file is opened in is determined by the flags, which
350 // are values from the enum lfs_open_flags that are bitwise-ored together.
351 //
352 // The config struct provides additional config options per file as described
353 // above. The config struct must be allocated while the file is open, and the
354 // config struct must be zeroed for defaults and backwards compatibility.
355 //
356 // Returns a negative error code on failure.
357 int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file,
358  const char *path, int flags,
359  const struct lfs_file_config *config);
360 
361 // Close a file
362 //
363 // Any pending writes are written out to storage as though
364 // sync had been called and releases any allocated resources.
365 //
366 // Returns a negative error code on failure.
367 int lfs_file_close(lfs_t *lfs, lfs_file_t *file);
368 
369 // Synchronize a file on storage
370 //
371 // Any pending writes are written out to storage.
372 // Returns a negative error code on failure.
373 int lfs_file_sync(lfs_t *lfs, lfs_file_t *file);
374 
375 // Read data from file
376 //
377 // Takes a buffer and size indicating where to store the read data.
378 // Returns the number of bytes read, or a negative error code on failure.
379 lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file,
380  void *buffer, lfs_size_t size);
381 
382 // Write data to file
383 //
384 // Takes a buffer and size indicating the data to write. The file will not
385 // actually be updated on the storage until either sync or close is called.
386 //
387 // Returns the number of bytes written, or a negative error code on failure.
388 lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
389  const void *buffer, lfs_size_t size);
390 
391 // Change the position of the file
392 //
393 // The change in position is determined by the offset and whence flag.
394 // Returns the old position of the file, or a negative error code on failure.
395 lfs_soff_t lfs_file_seek(lfs_t *lfs, lfs_file_t *file,
396  lfs_soff_t off, int whence);
397 
398 // Truncates the size of the file to the specified size
399 //
400 // Returns a negative error code on failure.
401 int lfs_file_truncate(lfs_t *lfs, lfs_file_t *file, lfs_off_t size);
402 
403 // Return the position of the file
404 //
405 // Equivalent to lfs_file_seek(lfs, file, 0, LFS_SEEK_CUR)
406 // Returns the position of the file, or a negative error code on failure.
407 lfs_soff_t lfs_file_tell(lfs_t *lfs, lfs_file_t *file);
408 
409 // Change the position of the file to the beginning of the file
410 //
411 // Equivalent to lfs_file_seek(lfs, file, 0, LFS_SEEK_CUR)
412 // Returns a negative error code on failure.
413 int lfs_file_rewind(lfs_t *lfs, lfs_file_t *file);
414 
415 // Return the size of the file
416 //
417 // Similar to lfs_file_seek(lfs, file, 0, LFS_SEEK_END)
418 // Returns the size of the file, or a negative error code on failure.
419 lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file);
420 
421 
422 /// Directory operations ///
423 
424 // Create a directory
425 //
426 // Returns a negative error code on failure.
427 int lfs_mkdir(lfs_t *lfs, const char *path);
428 
429 // Open a directory
430 //
431 // Once open a directory can be used with read to iterate over files.
432 // Returns a negative error code on failure.
433 int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path);
434 
435 // Close a directory
436 //
437 // Releases any allocated resources.
438 // Returns a negative error code on failure.
439 int lfs_dir_close(lfs_t *lfs, lfs_dir_t *dir);
440 
441 // Read an entry in the directory
442 //
443 // Fills out the info structure, based on the specified file or directory.
444 // Returns a negative error code on failure.
445 int lfs_dir_read(lfs_t *lfs, lfs_dir_t *dir, struct lfs_info *info);
446 
447 // Change the position of the directory
448 //
449 // The new off must be a value previous returned from tell and specifies
450 // an absolute offset in the directory seek.
451 //
452 // Returns a negative error code on failure.
453 int lfs_dir_seek(lfs_t *lfs, lfs_dir_t *dir, lfs_off_t off);
454 
455 // Return the position of the directory
456 //
457 // The returned offset is only meant to be consumed by seek and may not make
458 // sense, but does indicate the current position in the directory iteration.
459 //
460 // Returns the position of the directory, or a negative error code on failure.
461 lfs_soff_t lfs_dir_tell(lfs_t *lfs, lfs_dir_t *dir);
462 
463 // Change the position of the directory to the beginning of the directory
464 //
465 // Returns a negative error code on failure.
466 int lfs_dir_rewind(lfs_t *lfs, lfs_dir_t *dir);
467 
468 
469 /// Miscellaneous littlefs specific operations ///
470 
471 // Traverse through all blocks in use by the filesystem
472 //
473 // The provided callback will be called with each block address that is
474 // currently in use by the filesystem. This can be used to determine which
475 // blocks are in use or how much of the storage is available.
476 //
477 // Returns a negative error code on failure.
478 int lfs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data);
479 
480 // Prunes any recoverable errors that may have occurred in the filesystem
481 //
482 // Not needed to be called by user unless an operation is interrupted
483 // but the filesystem is still mounted. This is already called on first
484 // allocation.
485 //
486 // Returns a negative error code on failure.
487 int lfs_deorphan(lfs_t *lfs);
488 
489 
490 #ifdef __cplusplus
491 } /* extern "C" */
492 #endif
493 
494 #endif
Definition: lfs.h:215
The key size.
Definition: lfs.h:178
Definition: lfs.h:194
Definition: lfs.h:231
littlefs data structures ///
Definition: lfs.h:191
Definition: lfs.h:209
Definition: lfs.h:271
Definition: lfs.h:262
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.