• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * The little filesystem
3  *
4  * Copyright (c) 2022, The littlefs authors.
5  * Copyright (c) 2017, Arm Limited. All rights reserved.
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 #ifndef LFS_H
9 #define LFS_H
10 
11 #include <stdint.h>
12 #include <stdbool.h>
13 #include "lfs_util.h"
14 
15 #ifdef __cplusplus
16 extern "C"
17 {
18 #endif
19 
20 
21 /// Version info ///
22 
23 // Software library version
24 // Major (top-nibble), incremented on backwards incompatible changes
25 // Minor (bottom-nibble), incremented on feature additions
26 #define LFS_VERSION 0x00020005
27 #define LFS_VERSION_MAJOR (0xffff & (LFS_VERSION >> 16))
28 #define LFS_VERSION_MINOR (0xffff & (LFS_VERSION >>  0))
29 
30 // Version of On-disk data structures
31 // Major (top-nibble), incremented on backwards incompatible changes
32 // Minor (bottom-nibble), incremented on feature additions
33 #define LFS_DISK_VERSION 0x00020000
34 #define LFS_DISK_VERSION_MAJOR (0xffff & (LFS_DISK_VERSION >> 16))
35 #define LFS_DISK_VERSION_MINOR (0xffff & (LFS_DISK_VERSION >>  0))
36 
37 
38 /// Definitions ///
39 
40 // Type definitions
41 typedef uint32_t lfs_size_t;
42 typedef uint32_t lfs_off_t;
43 
44 typedef int32_t  lfs_ssize_t;
45 typedef int32_t  lfs_soff_t;
46 
47 typedef uint32_t lfs_block_t;
48 
49 // Maximum name size in bytes, may be redefined to reduce the size of the
50 // info struct. Limited to <= 1022. Stored in superblock and must be
51 // respected by other littlefs drivers.
52 #ifndef LFS_NAME_MAX
53 #define LFS_NAME_MAX 255
54 #endif
55 
56 // Maximum size of a file in bytes, may be redefined to limit to support other
57 // drivers. Limited on disk to <= 4294967296. However, above 2147483647 the
58 // functions lfs_file_seek, lfs_file_size, and lfs_file_tell will return
59 // incorrect values due to using signed integers. Stored in superblock and
60 // must be respected by other littlefs drivers.
61 #ifndef LFS_FILE_MAX
62 #define LFS_FILE_MAX 2147483647
63 #endif
64 
65 // Maximum size of custom attributes in bytes, may be redefined, but there is
66 // no real benefit to using a smaller LFS_ATTR_MAX. Limited to <= 1022.
67 #ifndef LFS_ATTR_MAX
68 #define LFS_ATTR_MAX 1022
69 #endif
70 
71 // Possible error codes, these are negative to allow
72 // valid positive return values
73 enum lfs_error {
74     LFS_ERR_OK          = 0,    // No error
75     LFS_ERR_IO          = -5,   // Error during device operation
76     LFS_ERR_CORRUPT     = -84,  // Corrupted
77     LFS_ERR_NOENT       = -2,   // No directory entry
78     LFS_ERR_EXIST       = -17,  // Entry already exists
79     LFS_ERR_NOTDIR      = -20,  // Entry is not a dir
80     LFS_ERR_ISDIR       = -21,  // Entry is a dir
81     LFS_ERR_NOTEMPTY    = -39,  // Dir is not empty
82     LFS_ERR_BADF        = -9,   // Bad file number
83     LFS_ERR_FBIG        = -27,  // File too large
84     LFS_ERR_INVAL       = -22,  // Invalid parameter
85     LFS_ERR_NOSPC       = -28,  // No space left on device
86     LFS_ERR_NOMEM       = -12,  // No more memory available
87     LFS_ERR_NOATTR      = -61,  // No data/attr available
88     LFS_ERR_NAMETOOLONG = -36,  // File name too long
89 };
90 
91 // File types
92 enum lfs_type {
93     // file types
94     LFS_TYPE_REG            = 0x001,
95     LFS_TYPE_DIR            = 0x002,
96 
97     // internally used types
98     LFS_TYPE_SPLICE         = 0x400,
99     LFS_TYPE_NAME           = 0x000,
100     LFS_TYPE_STRUCT         = 0x200,
101     LFS_TYPE_USERATTR       = 0x300,
102     LFS_TYPE_FROM           = 0x100,
103     LFS_TYPE_TAIL           = 0x600,
104     LFS_TYPE_GLOBALS        = 0x700,
105     LFS_TYPE_CRC            = 0x500,
106 
107     // internally used type specializations
108     LFS_TYPE_CREATE         = 0x401,
109     LFS_TYPE_DELETE         = 0x4ff,
110     LFS_TYPE_SUPERBLOCK     = 0x0ff,
111     LFS_TYPE_DIRSTRUCT      = 0x200,
112     LFS_TYPE_CTZSTRUCT      = 0x202,
113     LFS_TYPE_INLINESTRUCT   = 0x201,
114     LFS_TYPE_SOFTTAIL       = 0x600,
115     LFS_TYPE_HARDTAIL       = 0x601,
116     LFS_TYPE_MOVESTATE      = 0x7ff,
117 
118     // internal chip sources
119     LFS_FROM_NOOP           = 0x000,
120     LFS_FROM_MOVE           = 0x101,
121     LFS_FROM_USERATTRS      = 0x102,
122 };
123 
124 // File open flags
125 enum lfs_open_flags {
126     // open flags
127     LFS_O_RDONLY = 1,         // Open a file as read only
128 #ifndef LFS_READONLY
129     LFS_O_WRONLY = 2,         // Open a file as write only
130     LFS_O_RDWR   = 3,         // Open a file as read and write
131     LFS_O_CREAT  = 0x0100,    // Create a file if it does not exist
132     LFS_O_EXCL   = 0x0200,    // Fail if a file already exists
133     LFS_O_TRUNC  = 0x0400,    // Truncate the existing file to zero size
134     LFS_O_APPEND = 0x0800,    // Move to end of file on every write
135 #endif
136 
137     // internally used flags
138 #ifndef LFS_READONLY
139     LFS_F_DIRTY   = 0x010000, // File does not match storage
140     LFS_F_WRITING = 0x020000, // File has been written since last flush
141 #endif
142     LFS_F_READING = 0x040000, // File has been read since last flush
143 #ifndef LFS_READONLY
144     LFS_F_ERRED   = 0x080000, // An error occurred during write
145 #endif
146     LFS_F_INLINE  = 0x100000, // Currently inlined in directory entry
147 };
148 
149 // File seek flags
150 enum lfs_whence_flags {
151     LFS_SEEK_SET = 0,   // Seek relative to an absolute position
152     LFS_SEEK_CUR = 1,   // Seek relative to the current file position
153     LFS_SEEK_END = 2,   // Seek relative to the end of the file
154 };
155 
156 
157 // Configuration provided during initialization of the littlefs
158 struct lfs_config {
159     // Opaque user provided context that can be used to pass
160     // information to the block device operations
161     void *context;
162 
163     // Read a region in a block. Negative error codes are propagated
164     // to the user.
165     int (*read)(const struct lfs_config *c, lfs_block_t block,
166             lfs_off_t off, void *buffer, lfs_size_t size);
167 
168     // Program a region in a block. The block must have previously
169     // been erased. Negative error codes are propagated to the user.
170     // May return LFS_ERR_CORRUPT if the block should be considered bad.
171     int (*prog)(const struct lfs_config *c, lfs_block_t block,
172             lfs_off_t off, const void *buffer, lfs_size_t size);
173 
174     // Erase a block. A block must be erased before being programmed.
175     // The state of an erased block is undefined. Negative error codes
176     // are propagated to the user.
177     // May return LFS_ERR_CORRUPT if the block should be considered bad.
178     int (*erase)(const struct lfs_config *c, lfs_block_t block);
179 
180     // Sync the state of the underlying block device. Negative error codes
181     // are propagated to the user.
182     int (*sync)(const struct lfs_config *c);
183 
184 #ifdef LFS_THREADSAFE
185     // Lock the underlying block device. Negative error codes
186     // are propagated to the user.
187     int (*lock)(const struct lfs_config *c);
188 
189     // Unlock the underlying block device. Negative error codes
190     // are propagated to the user.
191     int (*unlock)(const struct lfs_config *c);
192 #endif
193 
194     // Minimum size of a block read in bytes. All read operations will be a
195     // multiple of this value.
196     lfs_size_t read_size;
197 
198     // Minimum size of a block program in bytes. All program operations will be
199     // a multiple of this value.
200     lfs_size_t prog_size;
201 
202     // Size of an erasable block in bytes. This does not impact ram consumption
203     // and may be larger than the physical erase size. However, non-inlined
204     // files take up at minimum one block. Must be a multiple of the read and
205     // program sizes.
206     lfs_size_t block_size;
207 
208     // Number of erasable blocks on the device.
209     lfs_size_t block_count;
210 
211     // Number of erase cycles before littlefs evicts metadata logs and moves
212     // the metadata to another block. Suggested values are in the
213     // range 100-1000, with large values having better performance at the cost
214     // of less consistent wear distribution.
215     //
216     // Set to -1 to disable block-level wear-leveling.
217     int32_t block_cycles;
218 
219     // Size of block caches in bytes. Each cache buffers a portion of a block in
220     // RAM. The littlefs needs a read cache, a program cache, and one additional
221     // cache per file. Larger caches can improve performance by storing more
222     // data and reducing the number of disk accesses. Must be a multiple of the
223     // read and program sizes, and a factor of the block size.
224     lfs_size_t cache_size;
225 
226     // Size of the lookahead buffer in bytes. A larger lookahead buffer
227     // increases the number of blocks found during an allocation pass. The
228     // lookahead buffer is stored as a compact bitmap, so each byte of RAM
229     // can track 8 blocks. Must be a multiple of 8.
230     lfs_size_t lookahead_size;
231 
232     // Optional statically allocated read buffer. Must be cache_size.
233     // By default lfs_malloc is used to allocate this buffer.
234     void *read_buffer;
235 
236     // Optional statically allocated program buffer. Must be cache_size.
237     // By default lfs_malloc is used to allocate this buffer.
238     void *prog_buffer;
239 
240     // Optional statically allocated lookahead buffer. Must be lookahead_size
241     // and aligned to a 32-bit boundary. By default lfs_malloc is used to
242     // allocate this buffer.
243     void *lookahead_buffer;
244 
245     // Optional upper limit on length of file names in bytes. No downside for
246     // larger names except the size of the info struct which is controlled by
247     // the LFS_NAME_MAX define. Defaults to LFS_NAME_MAX when zero. Stored in
248     // superblock and must be respected by other littlefs drivers.
249     lfs_size_t name_max;
250 
251     // Optional upper limit on files in bytes. No downside for larger files
252     // but must be <= LFS_FILE_MAX. Defaults to LFS_FILE_MAX when zero. Stored
253     // in superblock and must be respected by other littlefs drivers.
254     lfs_size_t file_max;
255 
256     // Optional upper limit on custom attributes in bytes. No downside for
257     // larger attributes size but must be <= LFS_ATTR_MAX. Defaults to
258     // LFS_ATTR_MAX when zero.
259     lfs_size_t attr_max;
260 
261     // Optional upper limit on total space given to metadata pairs in bytes. On
262     // devices with large blocks (e.g. 128kB) setting this to a low size (2-8kB)
263     // can help bound the metadata compaction time. Must be <= block_size.
264     // Defaults to block_size when zero.
265     lfs_size_t metadata_max;
266 };
267 
268 // File info structure
269 struct lfs_info {
270     // Type of the file, either LFS_TYPE_REG or LFS_TYPE_DIR
271     uint8_t type;
272 
273     // Size of the file, only valid for REG files. Limited to 32-bits.
274     lfs_size_t size;
275 
276     // Name of the file stored as a null-terminated string. Limited to
277     // LFS_NAME_MAX+1, which can be changed by redefining LFS_NAME_MAX to
278     // reduce RAM. LFS_NAME_MAX is stored in superblock and must be
279     // respected by other littlefs drivers.
280     char name[LFS_NAME_MAX+1];
281 };
282 
283 // Custom attribute structure, used to describe custom attributes
284 // committed atomically during file writes.
285 struct lfs_attr {
286     // 8-bit type of attribute, provided by user and used to
287     // identify the attribute
288     uint8_t type;
289 
290     // Pointer to buffer containing the attribute
291     void *buffer;
292 
293     // Size of attribute in bytes, limited to LFS_ATTR_MAX
294     lfs_size_t size;
295 };
296 
297 // Optional configuration provided during lfs_file_opencfg
298 struct lfs_file_config {
299     // Optional statically allocated file buffer. Must be cache_size.
300     // By default lfs_malloc is used to allocate this buffer.
301     void *buffer;
302 
303     // Optional list of custom attributes related to the file. If the file
304     // is opened with read access, these attributes will be read from disk
305     // during the open call. If the file is opened with write access, the
306     // attributes will be written to disk every file sync or close. This
307     // write occurs atomically with update to the file's contents.
308     //
309     // Custom attributes are uniquely identified by an 8-bit type and limited
310     // to LFS_ATTR_MAX bytes. When read, if the stored attribute is smaller
311     // than the buffer, it will be padded with zeros. If the stored attribute
312     // is larger, then it will be silently truncated. If the attribute is not
313     // found, it will be created implicitly.
314     struct lfs_attr *attrs;
315 
316     // Number of custom attributes in the list
317     lfs_size_t attr_count;
318 };
319 
320 
321 /// internal littlefs data structures ///
322 typedef struct lfs_cache {
323     lfs_block_t block;
324     lfs_off_t off;
325     lfs_size_t size;
326     uint8_t *buffer;
327 } lfs_cache_t;
328 
329 typedef struct lfs_mdir {
330     lfs_block_t pair[2];
331     uint32_t rev;
332     lfs_off_t off;
333     uint32_t etag;
334     uint16_t count;
335     bool erased;
336     bool split;
337     lfs_block_t tail[2];
338 } lfs_mdir_t;
339 
340 // littlefs directory type
341 typedef struct lfs_dir {
342     struct lfs_dir *next;
343     uint16_t id;
344     uint8_t type;
345     lfs_mdir_t m;
346 
347     lfs_off_t pos;
348     lfs_block_t head[2];
349 } lfs_dir_t;
350 
351 // littlefs file type
352 typedef struct lfs_file {
353     struct lfs_file *next;
354     uint16_t id;
355     uint8_t type;
356     lfs_mdir_t m;
357 
358     struct lfs_ctz {
359         lfs_block_t head;
360         lfs_size_t size;
361     } ctz;
362 
363     uint32_t flags;
364     lfs_off_t pos;
365     lfs_block_t block;
366     lfs_off_t off;
367     lfs_cache_t cache;
368 
369     const struct lfs_file_config *cfg;
370 } lfs_file_t;
371 
372 typedef struct lfs_superblock {
373     uint32_t version;
374     lfs_size_t block_size;
375     lfs_size_t block_count;
376     lfs_size_t name_max;
377     lfs_size_t file_max;
378     lfs_size_t attr_max;
379 } lfs_superblock_t;
380 
381 typedef struct lfs_gstate {
382     uint32_t tag;
383     lfs_block_t pair[2];
384 } lfs_gstate_t;
385 
386 // The littlefs filesystem type
387 typedef struct lfs {
388     lfs_cache_t rcache;
389     lfs_cache_t pcache;
390 
391     lfs_block_t root[2];
392     struct lfs_mlist {
393         struct lfs_mlist *next;
394         uint16_t id;
395         uint8_t type;
396         lfs_mdir_t m;
397     } *mlist;
398     uint32_t seed;
399 
400     lfs_gstate_t gstate;
401     lfs_gstate_t gdisk;
402     lfs_gstate_t gdelta;
403 
404     struct lfs_free {
405         lfs_block_t off;
406         lfs_block_t size;
407         lfs_block_t i;
408         lfs_block_t ack;
409         uint32_t *buffer;
410     } free;
411 
412     const struct lfs_config *cfg;
413     lfs_size_t name_max;
414     lfs_size_t file_max;
415     lfs_size_t attr_max;
416 
417 #ifdef LFS_MIGRATE
418     struct lfs1 *lfs1;
419 #endif
420 } lfs_t;
421 
422 
423 /// Filesystem functions ///
424 
425 #ifndef LFS_READONLY
426 // Format a block device with the littlefs
427 //
428 // Requires a littlefs object and config struct. This clobbers the littlefs
429 // object, and does not leave the filesystem mounted. The config struct must
430 // be zeroed for defaults and backwards compatibility.
431 //
432 // Returns a negative error code on failure.
433 int lfs_format(lfs_t *lfs, const struct lfs_config *config);
434 #endif
435 
436 // Mounts a littlefs
437 //
438 // Requires a littlefs object and config struct. Multiple filesystems
439 // may be mounted simultaneously with multiple littlefs objects. Both
440 // lfs and config must be allocated while mounted. The config struct must
441 // be zeroed for defaults and backwards compatibility.
442 //
443 // Returns a negative error code on failure.
444 int lfs_mount(lfs_t *lfs, const struct lfs_config *config);
445 
446 // Unmounts a littlefs
447 //
448 // Does nothing besides releasing any allocated resources.
449 // Returns a negative error code on failure.
450 int lfs_unmount(lfs_t *lfs);
451 
452 /// General operations ///
453 
454 #ifndef LFS_READONLY
455 // Removes a file or directory
456 //
457 // If removing a directory, the directory must be empty.
458 // Returns a negative error code on failure.
459 int lfs_remove(lfs_t *lfs, const char *path);
460 #endif
461 
462 #ifndef LFS_READONLY
463 // Rename or move a file or directory
464 //
465 // If the destination exists, it must match the source in type.
466 // If the destination is a directory, the directory must be empty.
467 //
468 // Returns a negative error code on failure.
469 int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath);
470 #endif
471 
472 // Find info about a file or directory
473 //
474 // Fills out the info structure, based on the specified file or directory.
475 // Returns a negative error code on failure.
476 int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info);
477 
478 // Get a custom attribute
479 //
480 // Custom attributes are uniquely identified by an 8-bit type and limited
481 // to LFS_ATTR_MAX bytes. When read, if the stored attribute is smaller than
482 // the buffer, it will be padded with zeros. If the stored attribute is larger,
483 // then it will be silently truncated. If no attribute is found, the error
484 // LFS_ERR_NOATTR is returned and the buffer is filled with zeros.
485 //
486 // Returns the size of the attribute, or a negative error code on failure.
487 // Note, the returned size is the size of the attribute on disk, irrespective
488 // of the size of the buffer. This can be used to dynamically allocate a buffer
489 // or check for existence.
490 lfs_ssize_t lfs_getattr(lfs_t *lfs, const char *path,
491         uint8_t type, void *buffer, lfs_size_t size);
492 
493 #ifndef LFS_READONLY
494 // Set custom attributes
495 //
496 // Custom attributes are uniquely identified by an 8-bit type and limited
497 // to LFS_ATTR_MAX bytes. If an attribute is not found, it will be
498 // implicitly created.
499 //
500 // Returns a negative error code on failure.
501 int lfs_setattr(lfs_t *lfs, const char *path,
502         uint8_t type, const void *buffer, lfs_size_t size);
503 #endif
504 
505 #ifndef LFS_READONLY
506 // Removes a custom attribute
507 //
508 // If an attribute is not found, nothing happens.
509 //
510 // Returns a negative error code on failure.
511 int lfs_removeattr(lfs_t *lfs, const char *path, uint8_t type);
512 #endif
513 
514 
515 /// File operations ///
516 
517 #ifndef LFS_NO_MALLOC
518 // Open a file
519 //
520 // The mode that the file is opened in is determined by the flags, which
521 // are values from the enum lfs_open_flags that are bitwise-ored together.
522 //
523 // Returns a negative error code on failure.
524 int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
525         const char *path, int flags);
526 
527 // if LFS_NO_MALLOC is defined, lfs_file_open() will fail with LFS_ERR_NOMEM
528 // thus use lfs_file_opencfg() with config.buffer set.
529 #endif
530 
531 // Open a file with extra configuration
532 //
533 // The mode that the file is opened in is determined by the flags, which
534 // are values from the enum lfs_open_flags that are bitwise-ored together.
535 //
536 // The config struct provides additional config options per file as described
537 // above. The config struct must be allocated while the file is open, and the
538 // config struct must be zeroed for defaults and backwards compatibility.
539 //
540 // Returns a negative error code on failure.
541 int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file,
542         const char *path, int flags,
543         const struct lfs_file_config *config);
544 
545 // Close a file
546 //
547 // Any pending writes are written out to storage as though
548 // sync had been called and releases any allocated resources.
549 //
550 // Returns a negative error code on failure.
551 int lfs_file_close(lfs_t *lfs, lfs_file_t *file);
552 
553 // Synchronize a file on storage
554 //
555 // Any pending writes are written out to storage.
556 // Returns a negative error code on failure.
557 int lfs_file_sync(lfs_t *lfs, lfs_file_t *file);
558 
559 // Read data from file
560 //
561 // Takes a buffer and size indicating where to store the read data.
562 // Returns the number of bytes read, or a negative error code on failure.
563 lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file,
564         void *buffer, lfs_size_t size);
565 
566 #ifndef LFS_READONLY
567 // Write data to file
568 //
569 // Takes a buffer and size indicating the data to write. The file will not
570 // actually be updated on the storage until either sync or close is called.
571 //
572 // Returns the number of bytes written, or a negative error code on failure.
573 lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
574         const void *buffer, lfs_size_t size);
575 #endif
576 
577 // Change the position of the file
578 //
579 // The change in position is determined by the offset and whence flag.
580 // Returns the new position of the file, or a negative error code on failure.
581 lfs_soff_t lfs_file_seek(lfs_t *lfs, lfs_file_t *file,
582         lfs_soff_t off, int whence);
583 
584 #ifndef LFS_READONLY
585 // Truncates the size of the file to the specified size
586 //
587 // Returns a negative error code on failure.
588 int lfs_file_truncate(lfs_t *lfs, lfs_file_t *file, lfs_off_t size);
589 #endif
590 
591 // Return the position of the file
592 //
593 // Equivalent to lfs_file_seek(lfs, file, 0, LFS_SEEK_CUR)
594 // Returns the position of the file, or a negative error code on failure.
595 lfs_soff_t lfs_file_tell(lfs_t *lfs, lfs_file_t *file);
596 
597 // Change the position of the file to the beginning of the file
598 //
599 // Equivalent to lfs_file_seek(lfs, file, 0, LFS_SEEK_SET)
600 // Returns a negative error code on failure.
601 int lfs_file_rewind(lfs_t *lfs, lfs_file_t *file);
602 
603 // Return the size of the file
604 //
605 // Similar to lfs_file_seek(lfs, file, 0, LFS_SEEK_END)
606 // Returns the size of the file, or a negative error code on failure.
607 lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file);
608 
609 
610 /// Directory operations ///
611 
612 #ifndef LFS_READONLY
613 // Create a directory
614 //
615 // Returns a negative error code on failure.
616 int lfs_mkdir(lfs_t *lfs, const char *path);
617 #endif
618 
619 // Open a directory
620 //
621 // Once open a directory can be used with read to iterate over files.
622 // Returns a negative error code on failure.
623 int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path);
624 
625 // Close a directory
626 //
627 // Releases any allocated resources.
628 // Returns a negative error code on failure.
629 int lfs_dir_close(lfs_t *lfs, lfs_dir_t *dir);
630 
631 // Read an entry in the directory
632 //
633 // Fills out the info structure, based on the specified file or directory.
634 // Returns a positive value on success, 0 at the end of directory,
635 // or a negative error code on failure.
636 int lfs_dir_read(lfs_t *lfs, lfs_dir_t *dir, struct lfs_info *info);
637 
638 // Change the position of the directory
639 //
640 // The new off must be a value previous returned from tell and specifies
641 // an absolute offset in the directory seek.
642 //
643 // Returns a negative error code on failure.
644 int lfs_dir_seek(lfs_t *lfs, lfs_dir_t *dir, lfs_off_t off);
645 
646 // Return the position of the directory
647 //
648 // The returned offset is only meant to be consumed by seek and may not make
649 // sense, but does indicate the current position in the directory iteration.
650 //
651 // Returns the position of the directory, or a negative error code on failure.
652 lfs_soff_t lfs_dir_tell(lfs_t *lfs, lfs_dir_t *dir);
653 
654 // Change the position of the directory to the beginning of the directory
655 //
656 // Returns a negative error code on failure.
657 int lfs_dir_rewind(lfs_t *lfs, lfs_dir_t *dir);
658 
659 
660 /// Filesystem-level filesystem operations
661 
662 // Finds the current size of the filesystem
663 //
664 // Note: Result is best effort. If files share COW structures, the returned
665 // size may be larger than the filesystem actually is.
666 //
667 // Returns the number of allocated blocks, or a negative error code on failure.
668 lfs_ssize_t lfs_fs_size(lfs_t *lfs);
669 
670 // Traverse through all blocks in use by the filesystem
671 //
672 // The provided callback will be called with each block address that is
673 // currently in use by the filesystem. This can be used to determine which
674 // blocks are in use or how much of the storage is available.
675 //
676 // Returns a negative error code on failure.
677 int lfs_fs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data);
678 
679 #ifndef LFS_READONLY
680 #ifdef LFS_MIGRATE
681 // Attempts to migrate a previous version of littlefs
682 //
683 // Behaves similarly to the lfs_format function. Attempts to mount
684 // the previous version of littlefs and update the filesystem so it can be
685 // mounted with the current version of littlefs.
686 //
687 // Requires a littlefs object and config struct. This clobbers the littlefs
688 // object, and does not leave the filesystem mounted. The config struct must
689 // be zeroed for defaults and backwards compatibility.
690 //
691 // Returns a negative error code on failure.
692 int lfs_migrate(lfs_t *lfs, const struct lfs_config *cfg);
693 #endif
694 #endif
695 
696 
697 #ifdef __cplusplus
698 } /* extern "C" */
699 #endif
700 
701 #endif
702