Gleb Klochkov / Mbed OS Climatcontroll_Main

Dependencies:   esp8266-driver

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