Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
lfs.h
00001 /* 00002 * The little filesystem 00003 * 00004 * Copyright (c) 2017, Arm Limited. All rights reserved. 00005 * SPDX-License-Identifier: BSD-3-Clause 00006 */ 00007 #ifndef LFS_H 00008 #define LFS_H 00009 00010 #include <stdint.h> 00011 #include <stdbool.h> 00012 00013 #ifdef __cplusplus 00014 extern "C" 00015 { 00016 #endif 00017 00018 00019 /// Version info /// 00020 00021 // Software library version 00022 // Major (top-nibble), incremented on backwards incompatible changes 00023 // Minor (bottom-nibble), incremented on feature additions 00024 #define LFS_VERSION 0x00010006 00025 #define LFS_VERSION_MAJOR (0xffff & (LFS_VERSION >> 16)) 00026 #define LFS_VERSION_MINOR (0xffff & (LFS_VERSION >> 0)) 00027 00028 // Version of On-disk data structures 00029 // Major (top-nibble), incremented on backwards incompatible changes 00030 // Minor (bottom-nibble), incremented on feature additions 00031 #define LFS_DISK_VERSION 0x00010001 00032 #define LFS_DISK_VERSION_MAJOR (0xffff & (LFS_DISK_VERSION >> 16)) 00033 #define LFS_DISK_VERSION_MINOR (0xffff & (LFS_DISK_VERSION >> 0)) 00034 00035 00036 /// Definitions /// 00037 00038 // Type definitions 00039 typedef uint32_t lfs_size_t; 00040 typedef uint32_t lfs_off_t; 00041 00042 typedef int32_t lfs_ssize_t; 00043 typedef int32_t lfs_soff_t; 00044 00045 typedef uint32_t lfs_block_t; 00046 00047 // Max name size in bytes 00048 #ifndef LFS_NAME_MAX 00049 #define LFS_NAME_MAX 255 00050 #endif 00051 00052 // Possible error codes, these are negative to allow 00053 // valid positive return values 00054 enum lfs_error { 00055 LFS_ERR_OK = 0, // No error 00056 LFS_ERR_IO = -5, // Error during device operation 00057 LFS_ERR_CORRUPT = -52, // Corrupted 00058 LFS_ERR_NOENT = -2, // No directory entry 00059 LFS_ERR_EXIST = -17, // Entry already exists 00060 LFS_ERR_NOTDIR = -20, // Entry is not a dir 00061 LFS_ERR_ISDIR = -21, // Entry is a dir 00062 LFS_ERR_NOTEMPTY = -39, // Dir is not empty 00063 LFS_ERR_BADF = -9, // Bad file number 00064 LFS_ERR_INVAL = -22, // Invalid parameter 00065 LFS_ERR_NOSPC = -28, // No space left on device 00066 LFS_ERR_NOMEM = -12, // No more memory available 00067 }; 00068 00069 // File types 00070 enum lfs_type { 00071 LFS_TYPE_REG = 0x11, 00072 LFS_TYPE_DIR = 0x22, 00073 LFS_TYPE_SUPERBLOCK = 0x2e, 00074 }; 00075 00076 // File open flags 00077 enum lfs_open_flags { 00078 // open flags 00079 LFS_O_RDONLY = 1, // Open a file as read only 00080 LFS_O_WRONLY = 2, // Open a file as write only 00081 LFS_O_RDWR = 3, // Open a file as read and write 00082 LFS_O_CREAT = 0x0100, // Create a file if it does not exist 00083 LFS_O_EXCL = 0x0200, // Fail if a file already exists 00084 LFS_O_TRUNC = 0x0400, // Truncate the existing file to zero size 00085 LFS_O_APPEND = 0x0800, // Move to end of file on every write 00086 00087 // internally used flags 00088 LFS_F_DIRTY = 0x10000, // File does not match storage 00089 LFS_F_WRITING = 0x20000, // File has been written since last flush 00090 LFS_F_READING = 0x40000, // File has been read since last flush 00091 LFS_F_ERRED = 0x80000, // An error occurred during write 00092 }; 00093 00094 // File seek flags 00095 enum lfs_whence_flags { 00096 LFS_SEEK_SET = 0, // Seek relative to an absolute position 00097 LFS_SEEK_CUR = 1, // Seek relative to the current file position 00098 LFS_SEEK_END = 2, // Seek relative to the end of the file 00099 }; 00100 00101 00102 // Configuration provided during initialization of the littlefs 00103 struct lfs_config { 00104 // Opaque user provided context that can be used to pass 00105 // information to the block device operations 00106 void *context; 00107 00108 // Read a region in a block. Negative error codes are propogated 00109 // to the user. 00110 int (*read)(const struct lfs_config *c, lfs_block_t block, 00111 lfs_off_t off, void *buffer, lfs_size_t size); 00112 00113 // Program a region in a block. The block must have previously 00114 // been erased. Negative error codes are propogated to the user. 00115 // May return LFS_ERR_CORRUPT if the block should be considered bad. 00116 int (*prog)(const struct lfs_config *c, lfs_block_t block, 00117 lfs_off_t off, const void *buffer, lfs_size_t size); 00118 00119 // Erase a block. A block must be erased before being programmed. 00120 // The state of an erased block is undefined. Negative error codes 00121 // are propogated to the user. 00122 // May return LFS_ERR_CORRUPT if the block should be considered bad. 00123 int (*erase)(const struct lfs_config *c, lfs_block_t block); 00124 00125 // Sync the state of the underlying block device. Negative error codes 00126 // are propogated to the user. 00127 int (*sync)(const struct lfs_config *c); 00128 00129 // Minimum size of a block read. This determines the size of read buffers. 00130 // This may be larger than the physical read size to improve performance 00131 // by caching more of the block device. 00132 lfs_size_t read_size; 00133 00134 // Minimum size of a block program. This determines the size of program 00135 // buffers. This may be larger than the physical program size to improve 00136 // performance by caching more of the block device. 00137 // Must be a multiple of the read size. 00138 lfs_size_t prog_size; 00139 00140 // Size of an erasable block. This does not impact ram consumption and 00141 // may be larger than the physical erase size. However, this should be 00142 // kept small as each file currently takes up an entire block. 00143 // Must be a multiple of the program size. 00144 lfs_size_t block_size; 00145 00146 // Number of erasable blocks on the device. 00147 lfs_size_t block_count; 00148 00149 // Number of blocks to lookahead during block allocation. A larger 00150 // lookahead reduces the number of passes required to allocate a block. 00151 // The lookahead buffer requires only 1 bit per block so it can be quite 00152 // large with little ram impact. Should be a multiple of 32. 00153 lfs_size_t lookahead; 00154 00155 // Optional, statically allocated read buffer. Must be read sized. 00156 void *read_buffer; 00157 00158 // Optional, statically allocated program buffer. Must be program sized. 00159 void *prog_buffer; 00160 00161 // Optional, statically allocated lookahead buffer. Must be 1 bit per 00162 // lookahead block. 00163 void *lookahead_buffer; 00164 00165 // Optional, statically allocated buffer for files. Must be program sized. 00166 // If enabled, only one file may be opened at a time. 00167 void *file_buffer; 00168 }; 00169 00170 // Optional configuration provided during lfs_file_opencfg 00171 struct lfs_file_config { 00172 // Optional, statically allocated buffer for files. Must be program sized. 00173 // If NULL, malloc will be used by default. 00174 void *buffer; 00175 }; 00176 00177 // File info structure 00178 struct lfs_info { 00179 // Type of the file, either LFS_TYPE_REG or LFS_TYPE_DIR 00180 uint8_t type; 00181 00182 // Size of the file, only valid for REG files 00183 lfs_size_t size; 00184 00185 // Name of the file stored as a null-terminated string 00186 char name[LFS_NAME_MAX+1]; 00187 }; 00188 00189 00190 /// littlefs data structures /// 00191 typedef struct lfs_entry { 00192 lfs_off_t off; 00193 00194 struct lfs_disk_entry { 00195 uint8_t type; 00196 uint8_t elen; 00197 uint8_t alen; 00198 uint8_t nlen; 00199 union { 00200 struct { 00201 lfs_block_t head; 00202 lfs_size_t size; 00203 } file; 00204 lfs_block_t dir[2]; 00205 } u; 00206 } d; 00207 } lfs_entry_t; 00208 00209 typedef struct lfs_cache { 00210 lfs_block_t block; 00211 lfs_off_t off; 00212 uint8_t *buffer; 00213 } lfs_cache_t; 00214 00215 typedef struct lfs_file { 00216 struct lfs_file *next; 00217 lfs_block_t pair[2]; 00218 lfs_off_t poff; 00219 00220 lfs_block_t head; 00221 lfs_size_t size; 00222 00223 const struct lfs_file_config *cfg; 00224 uint32_t flags; 00225 lfs_off_t pos; 00226 lfs_block_t block; 00227 lfs_off_t off; 00228 lfs_cache_t cache; 00229 } lfs_file_t; 00230 00231 typedef struct lfs_dir { 00232 struct lfs_dir *next; 00233 lfs_block_t pair[2]; 00234 lfs_off_t off; 00235 00236 lfs_block_t head[2]; 00237 lfs_off_t pos; 00238 00239 struct lfs_disk_dir { 00240 uint32_t rev; 00241 lfs_size_t size; 00242 lfs_block_t tail[2]; 00243 } d; 00244 } lfs_dir_t; 00245 00246 typedef struct lfs_superblock { 00247 lfs_off_t off; 00248 00249 struct lfs_disk_superblock { 00250 uint8_t type; 00251 uint8_t elen; 00252 uint8_t alen; 00253 uint8_t nlen; 00254 lfs_block_t root[2]; 00255 uint32_t block_size; 00256 uint32_t block_count; 00257 uint32_t version; 00258 char magic[8]; 00259 } d; 00260 } lfs_superblock_t; 00261 00262 typedef struct lfs_free { 00263 lfs_block_t off; 00264 lfs_block_t size; 00265 lfs_block_t i; 00266 lfs_block_t ack; 00267 uint32_t *buffer; 00268 } lfs_free_t; 00269 00270 // The littlefs type 00271 typedef struct lfs { 00272 const struct lfs_config *cfg; 00273 00274 lfs_block_t root[2]; 00275 lfs_file_t *files; 00276 lfs_dir_t *dirs; 00277 00278 lfs_cache_t rcache; 00279 lfs_cache_t pcache; 00280 00281 lfs_free_t free; 00282 bool deorphaned; 00283 } lfs_t; 00284 00285 00286 /// Filesystem functions /// 00287 00288 // Format a block device with the littlefs 00289 // 00290 // Requires a littlefs object and config struct. This clobbers the littlefs 00291 // object, and does not leave the filesystem mounted. The config struct must 00292 // be zeroed for defaults and backwards compatibility. 00293 // 00294 // Returns a negative error code on failure. 00295 int lfs_format(lfs_t *lfs, const struct lfs_config *config); 00296 00297 // Mounts a littlefs 00298 // 00299 // Requires a littlefs object and config struct. Multiple filesystems 00300 // may be mounted simultaneously with multiple littlefs objects. Both 00301 // lfs and config must be allocated while mounted. The config struct must 00302 // be zeroed for defaults and backwards compatibility. 00303 // 00304 // Returns a negative error code on failure. 00305 int lfs_mount(lfs_t *lfs, const struct lfs_config *config); 00306 00307 // Unmounts a littlefs 00308 // 00309 // Does nothing besides releasing any allocated resources. 00310 // Returns a negative error code on failure. 00311 int lfs_unmount(lfs_t *lfs); 00312 00313 /// General operations /// 00314 00315 // Removes a file or directory 00316 // 00317 // If removing a directory, the directory must be empty. 00318 // Returns a negative error code on failure. 00319 int lfs_remove(lfs_t *lfs, const char *path); 00320 00321 // Rename or move a file or directory 00322 // 00323 // If the destination exists, it must match the source in type. 00324 // If the destination is a directory, the directory must be empty. 00325 // 00326 // Returns a negative error code on failure. 00327 int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath); 00328 00329 // Find info about a file or directory 00330 // 00331 // Fills out the info structure, based on the specified file or directory. 00332 // Returns a negative error code on failure. 00333 int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info); 00334 00335 00336 /// File operations /// 00337 00338 // Open a file 00339 // 00340 // The mode that the file is opened in is determined by the flags, which 00341 // are values from the enum lfs_open_flags that are bitwise-ored together. 00342 // 00343 // Returns a negative error code on failure. 00344 int lfs_file_open(lfs_t *lfs, lfs_file_t *file, 00345 const char *path, int flags); 00346 00347 // Open a file with extra configuration 00348 // 00349 // The mode that the file is opened in is determined by the flags, which 00350 // are values from the enum lfs_open_flags that are bitwise-ored together. 00351 // 00352 // The config struct provides additional config options per file as described 00353 // above. The config struct must be allocated while the file is open, and the 00354 // config struct must be zeroed for defaults and backwards compatibility. 00355 // 00356 // Returns a negative error code on failure. 00357 int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file, 00358 const char *path, int flags, 00359 const struct lfs_file_config *config); 00360 00361 // Close a file 00362 // 00363 // Any pending writes are written out to storage as though 00364 // sync had been called and releases any allocated resources. 00365 // 00366 // Returns a negative error code on failure. 00367 int lfs_file_close(lfs_t *lfs, lfs_file_t *file); 00368 00369 // Synchronize a file on storage 00370 // 00371 // Any pending writes are written out to storage. 00372 // Returns a negative error code on failure. 00373 int lfs_file_sync(lfs_t *lfs, lfs_file_t *file); 00374 00375 // Read data from file 00376 // 00377 // Takes a buffer and size indicating where to store the read data. 00378 // Returns the number of bytes read, or a negative error code on failure. 00379 lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file, 00380 void *buffer, lfs_size_t size); 00381 00382 // Write data to file 00383 // 00384 // Takes a buffer and size indicating the data to write. The file will not 00385 // actually be updated on the storage until either sync or close is called. 00386 // 00387 // Returns the number of bytes written, or a negative error code on failure. 00388 lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file, 00389 const void *buffer, lfs_size_t size); 00390 00391 // Change the position of the file 00392 // 00393 // The change in position is determined by the offset and whence flag. 00394 // Returns the old position of the file, or a negative error code on failure. 00395 lfs_soff_t lfs_file_seek(lfs_t *lfs, lfs_file_t *file, 00396 lfs_soff_t off, int whence); 00397 00398 // Truncates the size of the file to the specified size 00399 // 00400 // Returns a negative error code on failure. 00401 int lfs_file_truncate(lfs_t *lfs, lfs_file_t *file, lfs_off_t size); 00402 00403 // Return the position of the file 00404 // 00405 // Equivalent to lfs_file_seek(lfs, file, 0, LFS_SEEK_CUR) 00406 // Returns the position of the file, or a negative error code on failure. 00407 lfs_soff_t lfs_file_tell(lfs_t *lfs, lfs_file_t *file); 00408 00409 // Change the position of the file to the beginning of the file 00410 // 00411 // Equivalent to lfs_file_seek(lfs, file, 0, LFS_SEEK_CUR) 00412 // Returns a negative error code on failure. 00413 int lfs_file_rewind(lfs_t *lfs, lfs_file_t *file); 00414 00415 // Return the size of the file 00416 // 00417 // Similar to lfs_file_seek(lfs, file, 0, LFS_SEEK_END) 00418 // Returns the size of the file, or a negative error code on failure. 00419 lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file); 00420 00421 00422 /// Directory operations /// 00423 00424 // Create a directory 00425 // 00426 // Returns a negative error code on failure. 00427 int lfs_mkdir(lfs_t *lfs, const char *path); 00428 00429 // Open a directory 00430 // 00431 // Once open a directory can be used with read to iterate over files. 00432 // Returns a negative error code on failure. 00433 int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path); 00434 00435 // Close a directory 00436 // 00437 // Releases any allocated resources. 00438 // Returns a negative error code on failure. 00439 int lfs_dir_close(lfs_t *lfs, lfs_dir_t *dir); 00440 00441 // Read an entry in the directory 00442 // 00443 // Fills out the info structure, based on the specified file or directory. 00444 // Returns a negative error code on failure. 00445 int lfs_dir_read(lfs_t *lfs, lfs_dir_t *dir, struct lfs_info *info); 00446 00447 // Change the position of the directory 00448 // 00449 // The new off must be a value previous returned from tell and specifies 00450 // an absolute offset in the directory seek. 00451 // 00452 // Returns a negative error code on failure. 00453 int lfs_dir_seek(lfs_t *lfs, lfs_dir_t *dir, lfs_off_t off); 00454 00455 // Return the position of the directory 00456 // 00457 // The returned offset is only meant to be consumed by seek and may not make 00458 // sense, but does indicate the current position in the directory iteration. 00459 // 00460 // Returns the position of the directory, or a negative error code on failure. 00461 lfs_soff_t lfs_dir_tell(lfs_t *lfs, lfs_dir_t *dir); 00462 00463 // Change the position of the directory to the beginning of the directory 00464 // 00465 // Returns a negative error code on failure. 00466 int lfs_dir_rewind(lfs_t *lfs, lfs_dir_t *dir); 00467 00468 00469 /// Miscellaneous littlefs specific operations /// 00470 00471 // Traverse through all blocks in use by the filesystem 00472 // 00473 // The provided callback will be called with each block address that is 00474 // currently in use by the filesystem. This can be used to determine which 00475 // blocks are in use or how much of the storage is available. 00476 // 00477 // Returns a negative error code on failure. 00478 int lfs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data); 00479 00480 // Prunes any recoverable errors that may have occurred in the filesystem 00481 // 00482 // Not needed to be called by user unless an operation is interrupted 00483 // but the filesystem is still mounted. This is already called on first 00484 // allocation. 00485 // 00486 // Returns a negative error code on failure. 00487 int lfs_deorphan(lfs_t *lfs); 00488 00489 00490 #ifdef __cplusplus 00491 } /* extern "C" */ 00492 #endif 00493 00494 #endif
Generated on Tue Aug 9 2022 00:37:09 by
1.7.2