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