Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers lfs.h Source File

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