mirror of
				https://github.com/eledio-devices/thirdparty-littlefs.git
				synced 2025-10-31 08:42:40 +01:00 
			
		
		
		
	Extended entry tag to support attributes
Zero attributes are actually supported at the moment, but this change will allow entry attribute to be added in a backwards compatible manner. Each dir entry is now prefixed with a 32 bit tag: 4b - entry type 4b - data structure 8b - entry len 8b - attribute len 8b - name len A full entry on disk looks a bit like this: [- 8 -|- 8 -|- 8 -|- 8 -|-- elen --|-- alen --|-- nlen --] [ type | elen | alen | nlen | entry | attrs | name ] The actually contents of the attributes section is a bit handwavey until the first attributes are implemented, but to put plans in place: Each attribute will be prefixed with only a byte that indicates the type of attribute. Attributes should be sorted based on portability, since unknown attributes will force attribute parsing to stop.
This commit is contained in:
		
							
								
								
									
										64
									
								
								lfs.c
									
									
									
									
									
								
							
							
						
						
									
										64
									
								
								lfs.c
									
									
									
									
									
								
							| @@ -560,8 +560,7 @@ static int lfs_dir_update(lfs_t *lfs, lfs_dir_t *dir, | ||||
|         const lfs_entry_t *entry, const void *data) { | ||||
|     return lfs_dir_commit(lfs, dir, (struct lfs_region[]){ | ||||
|             {entry->off, sizeof(entry->d), &entry->d, sizeof(entry->d)}, | ||||
|             {entry->off+sizeof(entry->d), entry->d.len-sizeof(entry->d), | ||||
|              data, entry->d.len-sizeof(entry->d)} | ||||
|             {entry->off+sizeof(entry->d), entry->d.nlen, data, entry->d.nlen} | ||||
|         }, data ? 2 : 1); | ||||
| } | ||||
|  | ||||
| @@ -569,11 +568,12 @@ static int lfs_dir_append(lfs_t *lfs, lfs_dir_t *dir, | ||||
|         lfs_entry_t *entry, const void *data) { | ||||
|     // check if we fit, if top bit is set we do not and move on | ||||
|     while (true) { | ||||
|         if (dir->d.size + entry->d.len <= lfs->cfg->block_size) { | ||||
|         if (dir->d.size + 4+entry->d.elen+entry->d.alen+entry->d.nlen | ||||
|                 <= lfs->cfg->block_size) { | ||||
|             entry->off = dir->d.size - 4; | ||||
|             return lfs_dir_commit(lfs, dir, (struct lfs_region[]){ | ||||
|                     {entry->off, 0, &entry->d, sizeof(entry->d)}, | ||||
|                     {entry->off, 0, data, entry->d.len - sizeof(entry->d)} | ||||
|                     {entry->off, 0, data, entry->d.nlen} | ||||
|                 }, 2); | ||||
|         } | ||||
|  | ||||
| @@ -590,7 +590,7 @@ static int lfs_dir_append(lfs_t *lfs, lfs_dir_t *dir, | ||||
|             entry->off = newdir.d.size - 4; | ||||
|             err = lfs_dir_commit(lfs, &newdir, (struct lfs_region[]){ | ||||
|                     {entry->off, 0, &entry->d, sizeof(entry->d)}, | ||||
|                     {entry->off, 0, data, entry->d.len - sizeof(entry->d)} | ||||
|                     {entry->off, 0, data, entry->d.nlen} | ||||
|                 }, 2); | ||||
|             if (err) { | ||||
|                 return err; | ||||
| @@ -620,7 +620,8 @@ static int lfs_dir_remove(lfs_t *lfs, lfs_dir_t *dir, lfs_entry_t *entry) { | ||||
|  | ||||
|         if (!(pdir.d.size & 0x80000000)) { | ||||
|             return lfs_dir_commit(lfs, dir, (struct lfs_region[]){ | ||||
|                 {entry->off, entry->d.len, NULL, 0}, | ||||
|                 {entry->off, 4+entry->d.elen+entry->d.alen+entry->d.nlen, | ||||
|                  NULL, 0}, | ||||
|             }, 1); | ||||
|         } else { | ||||
|             pdir.d.tail[0] = dir->d.tail[0]; | ||||
| @@ -629,7 +630,8 @@ static int lfs_dir_remove(lfs_t *lfs, lfs_dir_t *dir, lfs_entry_t *entry) { | ||||
|         } | ||||
|     } else { | ||||
|         return lfs_dir_commit(lfs, dir, (struct lfs_region[]){ | ||||
|             {entry->off, entry->d.len, NULL, 0}, | ||||
|             {entry->off, 4+entry->d.elen+entry->d.alen+entry->d.nlen, | ||||
|              NULL, 0}, | ||||
|         }, 1); | ||||
|     } | ||||
| } | ||||
| @@ -656,9 +658,9 @@ static int lfs_dir_next(lfs_t *lfs, lfs_dir_t *dir, lfs_entry_t *entry) { | ||||
|         return err; | ||||
|     } | ||||
|  | ||||
|     dir->off += entry->d.len; | ||||
|     dir->pos += entry->d.len; | ||||
|     entry->off = dir->off - entry->d.len; | ||||
|     entry->off = dir->off; | ||||
|     dir->off += 4+entry->d.elen+entry->d.alen+entry->d.nlen; | ||||
|     dir->pos += 4+entry->d.elen+entry->d.alen+entry->d.nlen; | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| @@ -713,12 +715,13 @@ static int lfs_dir_find(lfs_t *lfs, lfs_dir_t *dir, | ||||
|  | ||||
|             if ((entry->d.type != LFS_TYPE_REG && | ||||
|                  entry->d.type != LFS_TYPE_DIR) || | ||||
|                 entry->d.name != pathlen) { | ||||
|                 entry->d.nlen != pathlen) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             int res = lfs_bd_cmp(lfs, dir->pair[0], | ||||
|                     entry->off + sizeof(entry->d), pathname, pathlen); | ||||
|                     entry->off + 4+entry->d.elen+entry->d.alen, | ||||
|                     pathname, pathlen); | ||||
|             if (res < 0) { | ||||
|                 return res; | ||||
|             } | ||||
| @@ -784,8 +787,9 @@ int lfs_mkdir(lfs_t *lfs, const char *path) { | ||||
|     } | ||||
|  | ||||
|     entry.d.type = LFS_TYPE_DIR; | ||||
|     entry.d.name = strlen(path); | ||||
|     entry.d.len = sizeof(entry.d) + entry.d.name; | ||||
|     entry.d.elen = sizeof(entry.d) - 4; | ||||
|     entry.d.alen = 0; | ||||
|     entry.d.nlen = strlen(path); | ||||
|     entry.d.u.dir[0] = dir.pair[0]; | ||||
|     entry.d.u.dir[1] = dir.pair[1]; | ||||
|  | ||||
| @@ -880,8 +884,9 @@ int lfs_dir_read(lfs_t *lfs, lfs_dir_t *dir, struct lfs_info *info) { | ||||
|         info->size = entry.d.u.file.size; | ||||
|     } | ||||
|  | ||||
|     int err = lfs_bd_read(lfs, dir->pair[0], entry.off + sizeof(entry.d), | ||||
|             info->name, entry.d.name); | ||||
|     int err = lfs_bd_read(lfs, dir->pair[0], | ||||
|             entry.off + 4+entry.d.elen+entry.d.alen, | ||||
|             info->name, entry.d.nlen); | ||||
|     if (err) { | ||||
|         return err; | ||||
|     } | ||||
| @@ -1117,8 +1122,9 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file, | ||||
|  | ||||
|         // create entry to remember name | ||||
|         entry.d.type = LFS_TYPE_REG; | ||||
|         entry.d.name = strlen(path); | ||||
|         entry.d.len = sizeof(entry.d) + entry.d.name; | ||||
|         entry.d.elen = sizeof(entry.d) - 4; | ||||
|         entry.d.alen = 0; | ||||
|         entry.d.nlen = strlen(path); | ||||
|         entry.d.u.file.head = -1; | ||||
|         entry.d.u.file.size = 0; | ||||
|         err = lfs_dir_append(lfs, &cwd, &entry, path); | ||||
| @@ -1537,8 +1543,9 @@ int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info) { | ||||
|         info->size = entry.d.u.file.size; | ||||
|     } | ||||
|  | ||||
|     err = lfs_bd_read(lfs, cwd.pair[0], entry.off + sizeof(entry.d), | ||||
|             info->name, entry.d.name); | ||||
|     err = lfs_bd_read(lfs, cwd.pair[0], | ||||
|             entry.off + 4+entry.d.elen+entry.d.alen, | ||||
|             info->name, entry.d.nlen); | ||||
|     if (err) { | ||||
|         return err; | ||||
|     } | ||||
| @@ -1585,7 +1592,7 @@ int lfs_remove(lfs_t *lfs, const char *path) { | ||||
|                 f->pair[0] = 0xffffffff; | ||||
|                 f->pair[1] = 0xffffffff; | ||||
|             } else if (f->poff > entry.off) { | ||||
|                 f->poff -= entry.d.len; | ||||
|                 f->poff -= 4 + entry.d.elen + entry.d.alen + entry.d.nlen; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| @@ -1651,8 +1658,7 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) { | ||||
|     // move to new location | ||||
|     lfs_entry_t newentry = preventry; | ||||
|     newentry.d = oldentry.d; | ||||
|     newentry.d.name = strlen(newpath); | ||||
|     newentry.d.len = sizeof(newentry.d) + newentry.d.name; | ||||
|     newentry.d.nlen = strlen(newpath); | ||||
|  | ||||
|     if (prevexists) { | ||||
|         int err = lfs_dir_update(lfs, &newcwd, &newentry, newpath); | ||||
| @@ -1690,7 +1696,7 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) { | ||||
|                 f->pair[0] = 0xffffffff; | ||||
|                 f->pair[1] = 0xffffffff; | ||||
|             } else if (f->poff > oldentry.off) { | ||||
|                 f->poff -= oldentry.d.len; | ||||
|                 f->poff -= 4+oldentry.d.elen+oldentry.d.alen+oldentry.d.nlen; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| @@ -1809,8 +1815,8 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) { | ||||
|     lfs_superblock_t superblock = { | ||||
|         .off = sizeof(superdir.d), | ||||
|         .d.type = LFS_TYPE_SUPERBLOCK, | ||||
|         .d.name = sizeof(superblock.d.magic), | ||||
|         .d.len = sizeof(superblock.d), | ||||
|         .d.elen = sizeof(superblock.d) - sizeof(superblock.d.magic) - 4, | ||||
|         .d.nlen = sizeof(superblock.d.magic), | ||||
|         .d.version = 0x00010001, | ||||
|         .d.magic = {"littlefs"}, | ||||
|         .d.block_size  = lfs->cfg->block_size, | ||||
| @@ -1865,8 +1871,8 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) { | ||||
|     lfs_superblock_t superblock; | ||||
|     err = lfs_dir_fetch(lfs, &dir, (const lfs_block_t[2]){0, 1}); | ||||
|     if (!err) { | ||||
|         err = lfs_bd_read(lfs, dir.pair[0], | ||||
|                 sizeof(dir.d), &superblock.d, sizeof(superblock.d)); | ||||
|         err = lfs_bd_read(lfs, dir.pair[0], sizeof(dir.d), | ||||
|                 &superblock.d, sizeof(superblock.d)); | ||||
|  | ||||
|         lfs->root[0] = superblock.d.root[0]; | ||||
|         lfs->root[1] = superblock.d.root[1]; | ||||
| @@ -1925,7 +1931,7 @@ int lfs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data) { | ||||
|                 return err; | ||||
|             } | ||||
|  | ||||
|             dir.off += entry.d.len; | ||||
|             dir.off += 4+entry.d.elen+entry.d.alen+entry.d.nlen; | ||||
|             if ((0xf & entry.d.type) == (0xf & LFS_TYPE_REG)) { | ||||
|                 int err = lfs_index_traverse(lfs, &lfs->rcache, NULL, | ||||
|                         entry.d.u.file.head, entry.d.u.file.size, cb, data); | ||||
|   | ||||
							
								
								
									
										10
									
								
								lfs.h
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								lfs.h
									
									
									
									
									
								
							| @@ -160,8 +160,9 @@ typedef struct lfs_entry { | ||||
|  | ||||
|     struct lfs_disk_entry { | ||||
|         uint8_t type; | ||||
|         uint8_t name; | ||||
|         uint16_t len; | ||||
|         uint8_t elen; | ||||
|         uint8_t alen; | ||||
|         uint8_t nlen; | ||||
|         union { | ||||
|             struct { | ||||
|                 lfs_block_t head; | ||||
| @@ -212,8 +213,9 @@ typedef struct lfs_superblock { | ||||
|  | ||||
|     struct lfs_disk_superblock { | ||||
|         uint8_t type; | ||||
|         uint8_t name; | ||||
|         uint16_t len; | ||||
|         uint8_t elen; | ||||
|         uint8_t alen; | ||||
|         uint8_t nlen; | ||||
|         lfs_block_t root[2]; | ||||
|         uint32_t block_size; | ||||
|         uint32_t block_count; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user