Kenji Arai / TYBLE16_mbedlized_os5_several_examples_1st

Dependencies:   nRF51_Vdd TextLCD BME280

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 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