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