mirror of
				https://github.com/eledio-devices/thirdparty-littlefs.git
				synced 2025-10-31 00:32:38 +01:00 
			
		
		
		
	Added disk-backed limits on the name/attrs/inline sizes
Being a portable, microcontroller-scale embedded filesystem, littlefs is presented with a relatively unique challenge. The amount of RAM available is on completely different scales from machine to machine, and what is normally a reasonable RAM assumption may break completely on an embedded system. A great example of this is file names. On almost every PC these days, the limit for a file name is 255 bytes. It's a very convenient limit for a number of reasons. However, on microcontrollers, allocating 255 bytes of RAM to do a file search can be unreasonable. The simplest solution (and one that has existing in littlefs for a while), is to let this limit be redefined to a smaller value on devices that need to save RAM. However, this presents an interesting portability issue. If these devices are plugged into a PC with relatively infinite RAM, nothing stops the PC from writing files with full 255-byte file names, which can't be read on the small device. One solution here is to store this limit on the superblock during format time. When mounting a disk, the filesystem implementation is responsible for checking this limit in the superblock. If it's larger than what can be read, raise an error. If it's smaller, respect the limit on the superblock and raise an error if the user attempts to exceed it. In this commit, this strategy is adopted for file names, inline files, and the size of all attributes, since these could impact the memory consumption of the filesystem. (Recording the attribute's limit is iffy, but is the only other arbitrary limit and could be used for disabling support of custom attributes). Note! This changes makes it very important to configure littlefs correctly at format time. If littlefs is formatted on a PC without changing the limits appropriately, it will be rejected by a smaller device.
This commit is contained in:
		
							
								
								
									
										67
									
								
								lfs.h
									
									
									
									
									
								
							
							
						
						
									
										67
									
								
								lfs.h
									
									
									
									
									
								
							| @@ -50,30 +50,37 @@ typedef int32_t  lfs_soff_t; | ||||
|  | ||||
| typedef uint32_t lfs_block_t; | ||||
|  | ||||
| // Maximum inline file size in bytes | ||||
| #ifndef LFS_INLINE_MAX | ||||
| #define LFS_INLINE_MAX 255 | ||||
| #endif | ||||
|  | ||||
| // Maximum size of all attributes per file in bytes | ||||
| #ifndef LFS_ATTRS_MAX | ||||
| #define LFS_ATTRS_MAX 255 | ||||
| #endif | ||||
|  | ||||
| // Max name size in bytes | ||||
| #ifndef LFS_NAME_MAX | ||||
| #define LFS_NAME_MAX 255 | ||||
| #endif | ||||
|  | ||||
| #ifndef LFS_INLINE_MAX | ||||
| #define LFS_INLINE_MAX 255 | ||||
| #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 | ||||
| @@ -102,10 +109,10 @@ enum lfs_open_flags { | ||||
|     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 | ||||
| }; | ||||
|  | ||||
| @@ -183,6 +190,13 @@ 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, | ||||
|     lfs_size_t inline_size; | ||||
|     // Optional, | ||||
|     lfs_size_t attrs_size; | ||||
|     // Optional, | ||||
|     lfs_size_t name_size; | ||||
| }; | ||||
|  | ||||
|  | ||||
| @@ -258,9 +272,14 @@ typedef struct lfs_dir { | ||||
| typedef struct lfs_superblock { | ||||
|     struct lfs_disk_superblock { | ||||
|         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; | ||||
|  | ||||
|         lfs_size_t inline_size; | ||||
|         lfs_size_t attrs_size; | ||||
|         lfs_size_t name_size; | ||||
|     } d; | ||||
| } lfs_superblock_t; | ||||
|  | ||||
| @@ -285,6 +304,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; | ||||
|  | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user