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