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