mirror of
				https://github.com/eledio-devices/thirdparty-littlefs.git
				synced 2025-10-31 16:14:16 +01:00 
			
		
		
		
	Compare commits
	
		
			25 Commits
		
	
	
		
			v2.4.1
			...
			inline-fil
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 21ef0b7169 | ||
|  | fec133dfba | ||
|  | 9b4530f8de | ||
|  | 3a12b40fff | ||
|  | 12aa4bde06 | ||
|  | 09c7df83db | ||
|  | 5387f52de5 | ||
|  | c5b11d2a62 | ||
|  | 66cdab8327 | ||
|  | 8aba03d25f | ||
|  | 9064fa6dbb | ||
|  | fcc5c764e4 | ||
|  | 37f799d8a2 | ||
|  | 04b1103de1 | ||
|  | 87df75d009 | ||
|  | 1ea3d04d9c | ||
|  | 126f6d334e | ||
|  | 385b74944d | ||
|  | 3a10f5c29b | ||
|  | 96cca2f5b6 | ||
|  | 32f43462ea | ||
|  | efc634f3ed | ||
|  | 2f7adc3461 | ||
|  | e934a22c3a | ||
|  | 5937fd79dd | 
							
								
								
									
										128
									
								
								lfs.h
									
									
									
									
									
								
							
							
						
						
									
										128
									
								
								lfs.h
									
									
									
									
									
								
							| @@ -27,14 +27,14 @@ | ||||
| // Software library version | ||||
| // Major (top-nibble), incremented on backwards incompatible changes | ||||
| // Minor (bottom-nibble), incremented on feature additions | ||||
| #define LFS_VERSION 0x00010003 | ||||
| #define LFS_VERSION 0x00010004 | ||||
| #define LFS_VERSION_MAJOR (0xffff & (LFS_VERSION >> 16)) | ||||
| #define LFS_VERSION_MINOR (0xffff & (LFS_VERSION >>  0)) | ||||
|  | ||||
| // Version of On-disk data structures | ||||
| // Major (top-nibble), incremented on backwards incompatible changes | ||||
| // Minor (bottom-nibble), incremented on feature additions | ||||
| #define LFS_DISK_VERSION 0x00010001 | ||||
| #define LFS_DISK_VERSION 0x00010002 | ||||
| #define LFS_DISK_VERSION_MAJOR (0xffff & (LFS_DISK_VERSION >> 16)) | ||||
| #define LFS_DISK_VERSION_MINOR (0xffff & (LFS_DISK_VERSION >>  0)) | ||||
|  | ||||
| @@ -50,51 +50,78 @@ typedef int32_t  lfs_soff_t; | ||||
|  | ||||
| typedef uint32_t lfs_block_t; | ||||
|  | ||||
| // Max name size in bytes | ||||
| // Maximum inline file size in bytes. Large inline files require a larger | ||||
| // read and prog cache, but if a file can be inline it does not need its own | ||||
| // data block. LFS_ATTRS_MAX + LFS_INLINE_MAX must be <= 0xffff. Stored in | ||||
| // superblock and must be respected by other littlefs drivers. | ||||
| #ifndef LFS_INLINE_MAX | ||||
| #define LFS_INLINE_MAX 0x3ff | ||||
| #endif | ||||
|  | ||||
| // Maximum size of all attributes per file in bytes, may be redefined but a | ||||
| // a smaller LFS_ATTRS_MAX has no benefit. LFS_ATTRS_MAX + LFS_INLINE_MAX | ||||
| // must be <= 0xffff. Stored in superblock and must be respected by other | ||||
| // littlefs drivers. | ||||
| #ifndef LFS_ATTRS_MAX | ||||
| #define LFS_ATTRS_MAX 0x3f | ||||
| #endif | ||||
|  | ||||
| // Max name size in bytes, may be redefined to reduce the size of the | ||||
| // info struct. Stored in superblock and must be respected by other | ||||
| // littlefs drivers. | ||||
| #ifndef LFS_NAME_MAX | ||||
| #define LFS_NAME_MAX 255 | ||||
| #define LFS_NAME_MAX 0xff | ||||
| #endif | ||||
|  | ||||
| // Possible error codes, these are negative to allow | ||||
| // valid positive return values | ||||
| enum lfs_error { | ||||
|     LFS_ERR_OK       = 0,    // No error | ||||
|     LFS_ERR_IO       = -5,   // Error during device operation | ||||
|     LFS_ERR_CORRUPT  = -52,  // Corrupted | ||||
|     LFS_ERR_NOENT    = -2,   // No directory entry | ||||
|     LFS_ERR_EXIST    = -17,  // Entry already exists | ||||
|     LFS_ERR_NOTDIR   = -20,  // Entry is not a dir | ||||
|     LFS_ERR_ISDIR    = -21,  // Entry is a dir | ||||
|     LFS_ERR_NOTEMPTY = -39,  // Dir is not empty | ||||
|     LFS_ERR_BADF     = -9,   // Bad file number | ||||
|     LFS_ERR_INVAL    = -22,  // Invalid parameter | ||||
|     LFS_ERR_NOSPC    = -28,  // No space left on device | ||||
|     LFS_ERR_NOMEM    = -12,  // No more memory available | ||||
|     LFS_ERR_OK          = 0,    // No error | ||||
|     LFS_ERR_IO          = -5,   // Error during device operation | ||||
|     LFS_ERR_CORRUPT     = -52,  // Corrupted | ||||
|     LFS_ERR_NOENT       = -2,   // No directory entry | ||||
|     LFS_ERR_EXIST       = -17,  // Entry already exists | ||||
|     LFS_ERR_NOTDIR      = -20,  // Entry is not a dir | ||||
|     LFS_ERR_ISDIR       = -21,  // Entry is a dir | ||||
|     LFS_ERR_NOTEMPTY    = -39,  // Dir is not empty | ||||
|     LFS_ERR_BADF        = -9,   // Bad file number | ||||
|     LFS_ERR_INVAL       = -22,  // Invalid parameter | ||||
|     LFS_ERR_NOSPC       = -28,  // No space left on device | ||||
|     LFS_ERR_NOMEM       = -12,  // No more memory available | ||||
|     LFS_ERR_NAMETOOLONG = -36,  // File name too long | ||||
| }; | ||||
|  | ||||
| // File types | ||||
| enum lfs_type { | ||||
|     LFS_TYPE_REG        = 0x11, | ||||
|     LFS_TYPE_DIR        = 0x22, | ||||
|     LFS_TYPE_SUPERBLOCK = 0x2e, | ||||
|     // file type | ||||
|     LFS_TYPE_REG        = 0x01, | ||||
|     LFS_TYPE_DIR        = 0x02, | ||||
|     LFS_TYPE_SUPERBLOCK = 0x0e, | ||||
|  | ||||
|     // on disk structure | ||||
|     LFS_STRUCT_CTZ      = 0x10, | ||||
|     LFS_STRUCT_DIR      = 0x20, | ||||
|     LFS_STRUCT_INLINE   = 0x30, | ||||
|     LFS_STRUCT_MOVED    = 0x80, | ||||
| }; | ||||
|  | ||||
| // File open flags | ||||
| enum lfs_open_flags { | ||||
|     // open flags | ||||
|     LFS_O_RDONLY = 1,        // Open a file as read only | ||||
|     LFS_O_WRONLY = 2,        // Open a file as write only | ||||
|     LFS_O_RDWR   = 3,        // Open a file as read and write | ||||
|     LFS_O_CREAT  = 0x0100,   // Create a file if it does not exist | ||||
|     LFS_O_EXCL   = 0x0200,   // Fail if a file already exists | ||||
|     LFS_O_TRUNC  = 0x0400,   // Truncate the existing file to zero size | ||||
|     LFS_O_APPEND = 0x0800,   // Move to end of file on every write | ||||
|     LFS_O_RDONLY = 1,         // Open a file as read only | ||||
|     LFS_O_WRONLY = 2,         // Open a file as write only | ||||
|     LFS_O_RDWR   = 3,         // Open a file as read and write | ||||
|     LFS_O_CREAT  = 0x0100,    // Create a file if it does not exist | ||||
|     LFS_O_EXCL   = 0x0200,    // Fail if a file already exists | ||||
|     LFS_O_TRUNC  = 0x0400,    // Truncate the existing file to zero size | ||||
|     LFS_O_APPEND = 0x0800,    // Move to end of file on every write | ||||
|  | ||||
|     // internally used flags | ||||
|     LFS_F_DIRTY   = 0x10000, // File does not match storage | ||||
|     LFS_F_WRITING = 0x20000, // File has been written since last flush | ||||
|     LFS_F_READING = 0x40000, // File has been read since last flush | ||||
|     LFS_F_ERRED   = 0x80000, // An error occured during write | ||||
|     LFS_F_DIRTY   = 0x010000, // File does not match storage | ||||
|     LFS_F_WRITING = 0x020000, // File has been written since last flush | ||||
|     LFS_F_READING = 0x040000, // File has been read since last flush | ||||
|     LFS_F_ERRED   = 0x080000, // An error occured during write | ||||
|     LFS_F_INLINE  = 0x100000, // Currently inlined in directory entry | ||||
| }; | ||||
|  | ||||
| // File seek flags | ||||
| @@ -171,6 +198,25 @@ struct lfs_config { | ||||
|     // Optional, statically allocated buffer for files. Must be program sized. | ||||
|     // If enabled, only one file may be opened at a time. | ||||
|     void *file_buffer; | ||||
|  | ||||
|     // Optional upper limit on inlined files in bytes. Large inline files | ||||
|     // require a larger read and prog cache, but if a file can be inlined it | ||||
|     // does not need its own data block. Must be smaller than the read size | ||||
|     // and prog size. Defaults to min(LFS_INLINE_MAX, read_size) when zero. | ||||
|     // Stored in superblock and must be respected by other littlefs drivers. | ||||
|     lfs_size_t inline_size; | ||||
|  | ||||
|     // Optional upper limit on attributes per file in bytes. No downside for | ||||
|     // larger attributes size but must be less than LFS_ATTRS_MAX. Defaults to | ||||
|     // LFS_ATTRS_MAX when zero.Stored in superblock and must be respected by | ||||
|     // other littlefs drivers. | ||||
|     lfs_size_t attrs_size; | ||||
|  | ||||
|     // Optional upper limit on length of file names in bytes. No downside for | ||||
|     // larger names except the size of the info struct which is controlled by | ||||
|     // the LFS_NAME_MAX define. Defaults to LFS_NAME_MAX when zero. Stored in | ||||
|     // superblock and must be respected by other littlefs drivers. | ||||
|     lfs_size_t name_size; | ||||
| }; | ||||
|  | ||||
|  | ||||
| @@ -190,6 +236,7 @@ struct lfs_info { | ||||
| /// littlefs data structures /// | ||||
| typedef struct lfs_entry { | ||||
|     lfs_off_t off; | ||||
|     lfs_size_t size; | ||||
|  | ||||
|     struct lfs_disk_entry { | ||||
|         uint8_t type; | ||||
| @@ -221,6 +268,7 @@ typedef struct lfs_file { | ||||
|     lfs_size_t size; | ||||
|  | ||||
|     uint32_t flags; | ||||
|     lfs_size_t inline_size; | ||||
|     lfs_off_t pos; | ||||
|     lfs_block_t block; | ||||
|     lfs_off_t off; | ||||
| @@ -243,18 +291,16 @@ typedef struct lfs_dir { | ||||
| } lfs_dir_t; | ||||
|  | ||||
| typedef struct lfs_superblock { | ||||
|     lfs_off_t off; | ||||
|  | ||||
|     struct lfs_disk_superblock { | ||||
|         uint8_t type; | ||||
|         uint8_t elen; | ||||
|         uint8_t alen; | ||||
|         uint8_t nlen; | ||||
|         lfs_block_t root[2]; | ||||
|         uint32_t block_size; | ||||
|         uint32_t block_count; | ||||
|  | ||||
|         lfs_size_t block_size; | ||||
|         lfs_size_t block_count; | ||||
|         uint32_t version; | ||||
|         char magic[8]; | ||||
|  | ||||
|         lfs_size_t inline_size; | ||||
|         lfs_size_t attrs_size; | ||||
|         lfs_size_t name_size; | ||||
|     } d; | ||||
| } lfs_superblock_t; | ||||
|  | ||||
| @@ -279,6 +325,10 @@ typedef struct lfs { | ||||
|  | ||||
|     lfs_free_t free; | ||||
|     bool deorphaned; | ||||
|  | ||||
|     lfs_size_t inline_size; | ||||
|     lfs_size_t attrs_size; | ||||
|     lfs_size_t name_size; | ||||
| } lfs_t; | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -274,9 +274,12 @@ TEST | ||||
| tests/test.py << TEST | ||||
|     lfs_mount(&lfs, &cfg) => 0; | ||||
|  | ||||
|     // create one block whole for half a directory | ||||
|     // create one block hole for half a directory | ||||
|     lfs_file_open(&lfs, &file[0], "bump", LFS_O_WRONLY | LFS_O_CREAT) => 0; | ||||
|     lfs_file_write(&lfs, &file[0], (void*)"hi", 2) => 2; | ||||
|     for (lfs_size_t i = 0; i < cfg.block_size; i += 2) { | ||||
|         memcpy(&buffer[i], "hi", 2); | ||||
|     } | ||||
|     lfs_file_write(&lfs, &file[0], buffer, cfg.block_size) => cfg.block_size; | ||||
|     lfs_file_close(&lfs, &file[0]) => 0; | ||||
|  | ||||
|     lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_WRONLY | LFS_O_CREAT); | ||||
| @@ -289,13 +292,16 @@ tests/test.py << TEST | ||||
|     } | ||||
|     lfs_file_close(&lfs, &file[0]) => 0; | ||||
|  | ||||
|     // open whole | ||||
|     // open hole | ||||
|     lfs_remove(&lfs, "bump") => 0; | ||||
|  | ||||
|     lfs_mkdir(&lfs, "splitdir") => 0; | ||||
|     lfs_file_open(&lfs, &file[0], "splitdir/bump", | ||||
|             LFS_O_WRONLY | LFS_O_CREAT) => 0; | ||||
|     lfs_file_write(&lfs, &file[0], buffer, size) => LFS_ERR_NOSPC; | ||||
|     for (lfs_size_t i = 0; i < cfg.block_size; i += 2) { | ||||
|         memcpy(&buffer[i], "hi", 2); | ||||
|     } | ||||
|     lfs_file_write(&lfs, &file[0], buffer, cfg.block_size) => LFS_ERR_NOSPC; | ||||
|     lfs_file_close(&lfs, &file[0]) => 0; | ||||
|  | ||||
|     lfs_unmount(&lfs) => 0; | ||||
|   | ||||
| @@ -73,7 +73,7 @@ lfs_mktree | ||||
| lfs_chktree | ||||
|  | ||||
| echo "--- Block corruption ---" | ||||
| for i in {0..33} | ||||
| for i in {2..33} | ||||
| do  | ||||
|     rm -rf blocks | ||||
|     mkdir blocks | ||||
| @@ -83,12 +83,12 @@ do | ||||
| done | ||||
|  | ||||
| echo "--- Block persistance ---" | ||||
| for i in {0..33} | ||||
| for i in {2..33} | ||||
| do  | ||||
|     rm -rf blocks | ||||
|     mkdir blocks | ||||
|     lfs_mktree | ||||
|     chmod a-w blocks/$(printf '%x' $i) | ||||
|     chmod a-w blocks/$(printf '%x' $i) || true | ||||
|     lfs_mktree | ||||
|     lfs_chktree | ||||
| done | ||||
|   | ||||
| @@ -30,20 +30,10 @@ echo "--- Invalid mount ---" | ||||
| tests/test.py << TEST | ||||
|     lfs_format(&lfs, &cfg) => 0; | ||||
| TEST | ||||
| rm blocks/0 blocks/1 | ||||
| rm -f blocks/0 blocks/1 | ||||
| tests/test.py << TEST | ||||
|     lfs_mount(&lfs, &cfg) => LFS_ERR_CORRUPT; | ||||
| TEST | ||||
|  | ||||
| echo "--- Valid corrupt mount ---" | ||||
| tests/test.py << TEST | ||||
|     lfs_format(&lfs, &cfg) => 0; | ||||
| TEST | ||||
| rm blocks/0 | ||||
| tests/test.py << TEST | ||||
|     lfs_mount(&lfs, &cfg) => 0; | ||||
|     lfs_unmount(&lfs) => 0; | ||||
| TEST | ||||
|  | ||||
| echo "--- Results ---" | ||||
| tests/stats.py | ||||
|   | ||||
		Reference in New Issue
	
	Block a user