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 00005 * 00006 * Licensed under the Apache License, Version 2.0 (the "License"); 00007 * you may not use this file except in compliance with the License. 00008 * You may obtain a copy of the License at 00009 * 00010 * http://www.apache.org/licenses/LICENSE-2.0 00011 * 00012 * Unless required by applicable law or agreed to in writing, software 00013 * distributed under the License is distributed on an "AS IS" BASIS, 00014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00015 * See the License for the specific language governing permissions and 00016 * limitations under the License. 00017 */ 00018 #ifndef LFS_H 00019 #define LFS_H 00020 00021 #include <stdint.h> 00022 #include <stdbool.h> 00023 00024 00025 /// Version info /// 00026 00027 // Software library version 00028 // Major (top-nibble), incremented on backwards incompatible changes 00029 // Minor (bottom-nibble), incremented on feature additions 00030 #define LFS_VERSION 0x00010003 00031 #define LFS_VERSION_MAJOR (0xffff & (LFS_VERSION >> 16)) 00032 #define LFS_VERSION_MINOR (0xffff & (LFS_VERSION >> 0)) 00033 00034 // Version of On-disk data structures 00035 // Major (top-nibble), incremented on backwards incompatible changes 00036 // Minor (bottom-nibble), incremented on feature additions 00037 #define LFS_DISK_VERSION 0x00010001 00038 #define LFS_DISK_VERSION_MAJOR (0xffff & (LFS_DISK_VERSION >> 16)) 00039 #define LFS_DISK_VERSION_MINOR (0xffff & (LFS_DISK_VERSION >> 0)) 00040 00041 00042 /// Definitions /// 00043 00044 // Type definitions 00045 typedef uint32_t lfs_size_t; 00046 typedef uint32_t lfs_off_t; 00047 00048 typedef int32_t lfs_ssize_t; 00049 typedef int32_t lfs_soff_t; 00050 00051 typedef uint32_t lfs_block_t; 00052 00053 // Max name size in bytes 00054 #ifndef LFS_NAME_MAX 00055 #define LFS_NAME_MAX 255 00056 #endif 00057 00058 // Possible error codes, these are negative to allow 00059 // valid positive return values 00060 enum lfs_error { 00061 LFS_ERR_OK = 0, // No error 00062 LFS_ERR_IO = -5, // Error during device operation 00063 LFS_ERR_CORRUPT = -52, // Corrupted 00064 LFS_ERR_NOENT = -2, // No directory entry 00065 LFS_ERR_EXIST = -17, // Entry already exists 00066 LFS_ERR_NOTDIR = -20, // Entry is not a dir 00067 LFS_ERR_ISDIR = -21, // Entry is a dir 00068 LFS_ERR_NOTEMPTY = -39, // Dir is not empty 00069 LFS_ERR_BADF = -9, // Bad file number 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 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 uint32_t flags; 00224 lfs_off_t pos; 00225 lfs_block_t block; 00226 lfs_off_t off; 00227 lfs_cache_t cache; 00228 } lfs_file_t; 00229 00230 typedef struct lfs_dir { 00231 struct lfs_dir *next; 00232 lfs_block_t pair[2]; 00233 lfs_off_t off; 00234 00235 lfs_block_t head[2]; 00236 lfs_off_t pos; 00237 00238 struct lfs_disk_dir { 00239 uint32_t rev; 00240 lfs_size_t size; 00241 lfs_block_t tail[2]; 00242 } d; 00243 } lfs_dir_t; 00244 00245 typedef struct lfs_superblock { 00246 lfs_off_t off; 00247 00248 struct lfs_disk_superblock { 00249 uint8_t type; 00250 uint8_t elen; 00251 uint8_t alen; 00252 uint8_t nlen; 00253 lfs_block_t root[2]; 00254 uint32_t block_size; 00255 uint32_t block_count; 00256 uint32_t version; 00257 char magic[8]; 00258 } d; 00259 } lfs_superblock_t; 00260 00261 typedef struct lfs_free { 00262 lfs_block_t begin; 00263 lfs_block_t size; 00264 lfs_block_t off; 00265 lfs_block_t ack; 00266 uint32_t *buffer; 00267 } lfs_free_t; 00268 00269 // The littlefs type 00270 typedef struct lfs { 00271 const struct lfs_config *cfg; 00272 00273 lfs_block_t root[2]; 00274 lfs_file_t *files; 00275 lfs_dir_t *dirs; 00276 00277 lfs_cache_t rcache; 00278 lfs_cache_t pcache; 00279 00280 lfs_free_t free; 00281 bool deorphaned; 00282 } lfs_t; 00283 00284 00285 /// Filesystem functions /// 00286 00287 // Format a block device with the littlefs 00288 // 00289 // Requires a littlefs object and config struct. This clobbers the littlefs 00290 // object, and does not leave the filesystem mounted. 00291 // 00292 // Returns a negative error code on failure. 00293 int lfs_format(lfs_t *lfs, const struct lfs_config *config); 00294 00295 // Mounts a littlefs 00296 // 00297 // Requires a littlefs object and config struct. Multiple filesystems 00298 // may be mounted simultaneously with multiple littlefs objects. Both 00299 // lfs and config must be allocated while mounted. 00300 // 00301 // Returns a negative error code on failure. 00302 int lfs_mount(lfs_t *lfs, const struct lfs_config *config); 00303 00304 // Unmounts a littlefs 00305 // 00306 // Does nothing besides releasing any allocated resources. 00307 // Returns a negative error code on failure. 00308 int lfs_unmount(lfs_t *lfs); 00309 00310 /// General operations /// 00311 00312 // Removes a file or directory 00313 // 00314 // If removing a directory, the directory must be empty. 00315 // Returns a negative error code on failure. 00316 int lfs_remove(lfs_t *lfs, const char *path); 00317 00318 // Rename or move a file or directory 00319 // 00320 // If the destination exists, it must match the source in type. 00321 // If the destination is a directory, the directory must be empty. 00322 // 00323 // Note: If power loss occurs, it is possible that the file or directory 00324 // will exist in both the oldpath and newpath simultaneously after the 00325 // next mount. 00326 // 00327 // Returns a negative error code on failure. 00328 int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath); 00329 00330 // Find info about a file or directory 00331 // 00332 // Fills out the info structure, based on the specified file or directory. 00333 // Returns a negative error code on failure. 00334 int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info); 00335 00336 00337 /// File operations /// 00338 00339 // Open a file 00340 // 00341 // The mode that the file is opened in is determined 00342 // by the flags, which are values from the enum lfs_open_flags 00343 // that are bitwise-ored together. 00344 // 00345 // Returns a negative error code on failure. 00346 int lfs_file_open(lfs_t *lfs, lfs_file_t *file, 00347 const char *path, int flags); 00348 00349 // Close a file 00350 // 00351 // Any pending writes are written out to storage as though 00352 // sync had been called and releases any allocated resources. 00353 // 00354 // Returns a negative error code on failure. 00355 int lfs_file_close(lfs_t *lfs, lfs_file_t *file); 00356 00357 // Synchronize a file on storage 00358 // 00359 // Any pending writes are written out to storage. 00360 // Returns a negative error code on failure. 00361 int lfs_file_sync(lfs_t *lfs, lfs_file_t *file); 00362 00363 // Read data from file 00364 // 00365 // Takes a buffer and size indicating where to store the read data. 00366 // Returns the number of bytes read, or a negative error code on failure. 00367 lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file, 00368 void *buffer, lfs_size_t size); 00369 00370 // Write data to file 00371 // 00372 // Takes a buffer and size indicating the data to write. The file will not 00373 // actually be updated on the storage until either sync or close is called. 00374 // 00375 // Returns the number of bytes written, or a negative error code on failure. 00376 lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file, 00377 const void *buffer, lfs_size_t size); 00378 00379 // Change the position of the file 00380 // 00381 // The change in position is determined by the offset and whence flag. 00382 // Returns the old position of the file, or a negative error code on failure. 00383 lfs_soff_t lfs_file_seek(lfs_t *lfs, lfs_file_t *file, 00384 lfs_soff_t off, int whence); 00385 00386 // Truncates the size of the file to the specified size 00387 // 00388 // Returns a negative error code on failure. 00389 int lfs_file_truncate(lfs_t *lfs, lfs_file_t *file, lfs_off_t size); 00390 00391 // Return the position of the file 00392 // 00393 // Equivalent to lfs_file_seek(lfs, file, 0, LFS_SEEK_CUR) 00394 // Returns the position of the file, or a negative error code on failure. 00395 lfs_soff_t lfs_file_tell(lfs_t *lfs, lfs_file_t *file); 00396 00397 // Change the position of the file to the beginning of the file 00398 // 00399 // Equivalent to lfs_file_seek(lfs, file, 0, LFS_SEEK_CUR) 00400 // Returns a negative error code on failure. 00401 int lfs_file_rewind(lfs_t *lfs, lfs_file_t *file); 00402 00403 // Return the size of the file 00404 // 00405 // Similar to lfs_file_seek(lfs, file, 0, LFS_SEEK_END) 00406 // Returns the size of the file, or a negative error code on failure. 00407 lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file); 00408 00409 00410 /// Directory operations /// 00411 00412 // Create a directory 00413 // 00414 // Returns a negative error code on failure. 00415 int lfs_mkdir(lfs_t *lfs, const char *path); 00416 00417 // Open a directory 00418 // 00419 // Once open a directory can be used with read to iterate over files. 00420 // Returns a negative error code on failure. 00421 int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path); 00422 00423 // Close a directory 00424 // 00425 // Releases any allocated resources. 00426 // Returns a negative error code on failure. 00427 int lfs_dir_close(lfs_t *lfs, lfs_dir_t *dir); 00428 00429 // Read an entry in the directory 00430 // 00431 // Fills out the info structure, based on the specified file or directory. 00432 // Returns a negative error code on failure. 00433 int lfs_dir_read(lfs_t *lfs, lfs_dir_t *dir, struct lfs_info *info); 00434 00435 // Change the position of the directory 00436 // 00437 // The new off must be a value previous returned from tell and specifies 00438 // an absolute offset in the directory seek. 00439 // 00440 // Returns a negative error code on failure. 00441 int lfs_dir_seek(lfs_t *lfs, lfs_dir_t *dir, lfs_off_t off); 00442 00443 // Return the position of the directory 00444 // 00445 // The returned offset is only meant to be consumed by seek and may not make 00446 // sense, but does indicate the current position in the directory iteration. 00447 // 00448 // Returns the position of the directory, or a negative error code on failure. 00449 lfs_soff_t lfs_dir_tell(lfs_t *lfs, lfs_dir_t *dir); 00450 00451 // Change the position of the directory to the beginning of the directory 00452 // 00453 // Returns a negative error code on failure. 00454 int lfs_dir_rewind(lfs_t *lfs, lfs_dir_t *dir); 00455 00456 00457 /// Miscellaneous littlefs specific operations /// 00458 00459 // Traverse through all blocks in use by the filesystem 00460 // 00461 // The provided callback will be called with each block address that is 00462 // currently in use by the filesystem. This can be used to determine which 00463 // blocks are in use or how much of the storage is available. 00464 // 00465 // Returns a negative error code on failure. 00466 int lfs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data); 00467 00468 // Prunes any recoverable errors that may have occurred in the filesystem 00469 // 00470 // Not needed to be called by user unless an operation is interrupted 00471 // but the filesystem is still mounted. This is already called on first 00472 // allocation. 00473 // 00474 // Returns a negative error code on failure. 00475 int lfs_deorphan(lfs_t *lfs); 00476 00477 00478 #endif
Generated on Tue Jul 12 2022 14:23:51 by
