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