mirror of
				https://github.com/eledio-devices/thirdparty-littlefs.git
				synced 2025-10-31 16:14:16 +01:00 
			
		
		
		
	Minor improvement to from-memory commits
Tweaked the commit callback to pass the arguments for from-memory commits explicitly, with non-from-memory commits still being able to hijack the opaque data pointer for additional state. The from-memory commits make up the vast majority of commits in littlefs, so this small change has a noticable impact.
This commit is contained in:
		
							
								
								
									
										90
									
								
								lfs.c
									
									
									
									
									
								
							
							
						
						
									
										90
									
								
								lfs.c
									
									
									
									
									
								
							| @@ -490,7 +490,8 @@ struct lfs_commit { | |||||||
|     lfs_off_t off; |     lfs_off_t off; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| static int lfs_commit(lfs_t *lfs, struct lfs_commit *c, const void *data, lfs_size_t size) { | static int lfs_commit(lfs_t *lfs, struct lfs_commit *c, | ||||||
|  |         const void *data, lfs_size_t size) { | ||||||
|     lfs_crc(&c->crc, data, size); |     lfs_crc(&c->crc, data, size); | ||||||
|     int err = lfs_bd_prog(lfs, c->block, c->off, data, size); |     int err = lfs_bd_prog(lfs, c->block, c->off, data, size); | ||||||
|     c->off += size; |     c->off += size; | ||||||
| @@ -500,46 +501,44 @@ static int lfs_commit(lfs_t *lfs, struct lfs_commit *c, const void *data, lfs_si | |||||||
| struct lfs_region { | struct lfs_region { | ||||||
|     lfs_off_t off; |     lfs_off_t off; | ||||||
|     lfs_ssize_t diff; |     lfs_ssize_t diff; | ||||||
|     int (*commit)(lfs_t *lfs, struct lfs_commit *c, const void *p); |  | ||||||
|  |     int (*commit)(lfs_t *lfs, struct lfs_commit *c, | ||||||
|  |             const void *data, lfs_size_t size); | ||||||
|     const void *data; |     const void *data; | ||||||
|  |     lfs_size_t size; | ||||||
|     struct lfs_region *next; |     struct lfs_region *next; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| struct lfs_commit_mem { | static int lfs_commit_mem(lfs_t *lfs, struct lfs_commit *c, | ||||||
|     const void *data; |         const void *data, lfs_size_t size) { | ||||||
|     lfs_size_t size; |     return lfs_commit(lfs, c, data, size); | ||||||
| }; |  | ||||||
|  |  | ||||||
| static int lfs_commit_mem(lfs_t *lfs, struct lfs_commit *c, const void *p) { |  | ||||||
|     const struct lfs_commit_mem *m = p; |  | ||||||
|     return lfs_commit(lfs, c, m->data, m->size); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| struct lfs_commit_disk { | struct lfs_commit_disk { | ||||||
|     lfs_block_t block; |     lfs_block_t block; | ||||||
|     lfs_off_t off; |     lfs_off_t off; | ||||||
|     lfs_size_t size; |  | ||||||
|     struct lfs_region *regions; |     struct lfs_region *regions; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| static int lfs_commit_disk(lfs_t *lfs, struct lfs_commit *c, const void *p) { | static int lfs_commit_disk(lfs_t *lfs, struct lfs_commit *c, | ||||||
|     const struct lfs_commit_disk *u = p; |         const void *p, lfs_size_t size) { | ||||||
|  |     const struct lfs_commit_disk *d = p; | ||||||
|  |  | ||||||
|     struct lfs_region *r = u->regions; |     struct lfs_region *r = d->regions; | ||||||
|     lfs_off_t off = 0; |     lfs_off_t off = 0; | ||||||
|     while (true) { |     while (true) { | ||||||
|         if (r && r->off == off) { |         if (r && r->off == off) { | ||||||
|             lfs_off_t orig = c->off; |             lfs_off_t orig = c->off; | ||||||
|             int err = r->commit(lfs, c, r->data); |             int err = r->commit(lfs, c, r->data, r->size); | ||||||
|             if (err) { |             if (err) { | ||||||
|                 return err; |                 return err; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             off += (c->off - orig) - r->diff; |             off += (c->off - orig) - r->diff; | ||||||
|             r = r->next; |             r = r->next; | ||||||
|         } else if (off < u->size) { |         } else if (off < size) { | ||||||
|             uint8_t data; |             uint8_t data; | ||||||
|             int err = lfs_bd_read(lfs, u->block, u->off + off, &data, 1); |             int err = lfs_bd_read(lfs, d->block, d->off + off, &data, 1); | ||||||
|             if (err) { |             if (err) { | ||||||
|                 return err; |                 return err; | ||||||
|             } |             } | ||||||
| @@ -590,12 +589,11 @@ static int lfs_dir_commit(lfs_t *lfs, lfs_dir_t *dir, | |||||||
|  |  | ||||||
|             lfs_dir_tole32(&dir->d); |             lfs_dir_tole32(&dir->d); | ||||||
|             err = lfs_commit_disk(lfs, &c, &(struct lfs_commit_disk){ |             err = lfs_commit_disk(lfs, &c, &(struct lfs_commit_disk){ | ||||||
|                     oldpair[1], 0, oldsize, |                     oldpair[1], 0, | ||||||
|                     &(struct lfs_region){ |                     &(struct lfs_region){ | ||||||
|                         0, 0, |                         0, 0, | ||||||
|                         lfs_commit_mem, &(struct lfs_commit_mem){ |                         lfs_commit_mem, &dir->d, sizeof(dir->d), | ||||||
|                             &dir->d, sizeof(dir->d)}, |                         regions}}, oldsize); | ||||||
|                         regions}}); |  | ||||||
|             lfs_dir_fromle32(&dir->d); |             lfs_dir_fromle32(&dir->d); | ||||||
|             if (err) { |             if (err) { | ||||||
|                 if (err == LFS_ERR_CORRUPT) { |                 if (err == LFS_ERR_CORRUPT) { | ||||||
| @@ -754,8 +752,7 @@ static int lfs_dir_update(lfs_t *lfs, lfs_dir_t *dir, | |||||||
|         int err = lfs_dir_commit(lfs, &olddir, |         int err = lfs_dir_commit(lfs, &olddir, | ||||||
|                 &(struct lfs_region){ |                 &(struct lfs_region){ | ||||||
|                     oldoff, 0, |                     oldoff, 0, | ||||||
|                     lfs_commit_mem, &(struct lfs_commit_mem){ |                     lfs_commit_mem, &entry->d.type, 1}); | ||||||
|                         &entry->d.type, 1}}); |  | ||||||
|         if (err) { |         if (err) { | ||||||
|             return err; |             return err; | ||||||
|         } |         } | ||||||
| @@ -766,7 +763,7 @@ static int lfs_dir_update(lfs_t *lfs, lfs_dir_t *dir, | |||||||
|                 &(struct lfs_region){ |                 &(struct lfs_region){ | ||||||
|                     0, +lfs_entry_size(entry), |                     0, +lfs_entry_size(entry), | ||||||
|                     lfs_commit_disk, &(struct lfs_commit_disk){ |                     lfs_commit_disk, &(struct lfs_commit_disk){ | ||||||
|                         olddir.pair[0], entry->off, oldsize, regions}}); |                         olddir.pair[0], entry->off, regions}, oldsize}); | ||||||
|         if (err) { |         if (err) { | ||||||
|             return err; |             return err; | ||||||
|         } |         } | ||||||
| @@ -775,8 +772,7 @@ static int lfs_dir_update(lfs_t *lfs, lfs_dir_t *dir, | |||||||
|         err = lfs_dir_commit(lfs, &olddir, |         err = lfs_dir_commit(lfs, &olddir, | ||||||
|                 &(struct lfs_region){ |                 &(struct lfs_region){ | ||||||
|                     oldoff, -oldsize, |                     oldoff, -oldsize, | ||||||
|                     lfs_commit_mem, &(struct lfs_commit_mem){ |                     lfs_commit_mem, NULL, 0}); | ||||||
|                         NULL, 0}}); |  | ||||||
|         if (err) { |         if (err) { | ||||||
|             return err; |             return err; | ||||||
|         } |         } | ||||||
| @@ -829,8 +825,7 @@ static int lfs_dir_remove(lfs_t *lfs, lfs_dir_t *dir, lfs_entry_t *entry) { | |||||||
|     int err = lfs_dir_commit(lfs, dir, |     int err = lfs_dir_commit(lfs, dir, | ||||||
|             &(struct lfs_region){ |             &(struct lfs_region){ | ||||||
|                 entry->off, -lfs_entry_size(entry), |                 entry->off, -lfs_entry_size(entry), | ||||||
|                 lfs_commit_mem, &(struct lfs_commit_mem){ |                 lfs_commit_mem, NULL, 0}); | ||||||
|                     NULL, 0}}); |  | ||||||
|     if (err) { |     if (err) { | ||||||
|         return err; |         return err; | ||||||
|     } |     } | ||||||
| @@ -1053,12 +1048,10 @@ int lfs_mkdir(lfs_t *lfs, const char *path) { | |||||||
|     err = lfs_dir_append(lfs, &cwd, &entry, |     err = lfs_dir_append(lfs, &cwd, &entry, | ||||||
|             &(struct lfs_region){ |             &(struct lfs_region){ | ||||||
|                 0, +sizeof(entry.d), |                 0, +sizeof(entry.d), | ||||||
|                 lfs_commit_mem, &(struct lfs_commit_mem){ |                 lfs_commit_mem, &entry.d, sizeof(entry.d), | ||||||
|                     &entry.d, sizeof(entry.d)}, |  | ||||||
|             &(struct lfs_region){ |             &(struct lfs_region){ | ||||||
|                 0, +entry.d.nlen, |                 0, +entry.d.nlen, | ||||||
|                 lfs_commit_mem, &(struct lfs_commit_mem){ |                 lfs_commit_mem, path, entry.d.nlen}}); | ||||||
|                     path, entry.d.nlen}}}); |  | ||||||
|     if (err) { |     if (err) { | ||||||
|         return err; |         return err; | ||||||
|     } |     } | ||||||
| @@ -1445,12 +1438,10 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file, | |||||||
|         err = lfs_dir_append(lfs, &cwd, &entry, |         err = lfs_dir_append(lfs, &cwd, &entry, | ||||||
|                 &(struct lfs_region){ |                 &(struct lfs_region){ | ||||||
|                     0, +sizeof(entry.d), |                     0, +sizeof(entry.d), | ||||||
|                     lfs_commit_mem, &(struct lfs_commit_mem){ |                     lfs_commit_mem, &entry.d, sizeof(entry.d), | ||||||
|                         &entry.d, sizeof(entry.d)}, |  | ||||||
|                 &(struct lfs_region){ |                 &(struct lfs_region){ | ||||||
|                     0, +entry.d.nlen, |                     0, +entry.d.nlen, | ||||||
|                     lfs_commit_mem, &(struct lfs_commit_mem){ |                     lfs_commit_mem, path, entry.d.nlen}}); | ||||||
|                         path, entry.d.nlen}}}); |  | ||||||
|         if (err) { |         if (err) { | ||||||
|             return err; |             return err; | ||||||
|         } |         } | ||||||
| @@ -1669,8 +1660,7 @@ int lfs_file_sync(lfs_t *lfs, lfs_file_t *file) { | |||||||
|         err = lfs_dir_update(lfs, &cwd, &entry, |         err = lfs_dir_update(lfs, &cwd, &entry, | ||||||
|             &(struct lfs_region){ |             &(struct lfs_region){ | ||||||
|                 0, 0, |                 0, 0, | ||||||
|                 lfs_commit_mem, &(struct lfs_commit_mem){ |                 lfs_commit_mem, &entry.d, sizeof(entry.d)}); | ||||||
|                     &entry.d, sizeof(entry.d)}}); |  | ||||||
|         if (err) { |         if (err) { | ||||||
|             return err; |             return err; | ||||||
|         } |         } | ||||||
| @@ -2095,8 +2085,7 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) { | |||||||
|     err = lfs_dir_update(lfs, &oldcwd, &oldentry, |     err = lfs_dir_update(lfs, &oldcwd, &oldentry, | ||||||
|             &(struct lfs_region){ |             &(struct lfs_region){ | ||||||
|                 0, 0, |                 0, 0, | ||||||
|                 lfs_commit_mem, &(struct lfs_commit_mem){ |                 lfs_commit_mem, &oldentry.d, sizeof(oldentry.d)}); | ||||||
|                     &oldentry.d, sizeof(oldentry.d)}}); |  | ||||||
|     if (err) { |     if (err) { | ||||||
|         return err; |         return err; | ||||||
|     } |     } | ||||||
| @@ -2116,12 +2105,10 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) { | |||||||
|         err = lfs_dir_update(lfs, &newcwd, &newentry, |         err = lfs_dir_update(lfs, &newcwd, &newentry, | ||||||
|                 &(struct lfs_region){ |                 &(struct lfs_region){ | ||||||
|                     0, 0, |                     0, 0, | ||||||
|                     lfs_commit_mem, &(struct lfs_commit_mem){ |                     lfs_commit_mem, &newentry.d, sizeof(newentry.d), | ||||||
|                         &newentry.d, sizeof(newentry.d)}, |  | ||||||
|                 &(struct lfs_region){ |                 &(struct lfs_region){ | ||||||
|                     sizeof(newentry.d), 0, |                     sizeof(newentry.d), 0, | ||||||
|                     lfs_commit_mem, &(struct lfs_commit_mem){ |                     lfs_commit_mem, newpath, newentry.d.nlen}}); | ||||||
|                         newpath, newentry.d.nlen}}}); |  | ||||||
|         if (err) { |         if (err) { | ||||||
|             return err; |             return err; | ||||||
|         } |         } | ||||||
| @@ -2129,12 +2116,10 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) { | |||||||
|         err = lfs_dir_append(lfs, &newcwd, &newentry, |         err = lfs_dir_append(lfs, &newcwd, &newentry, | ||||||
|                 &(struct lfs_region){ |                 &(struct lfs_region){ | ||||||
|                     0, +sizeof(newentry.d), |                     0, +sizeof(newentry.d), | ||||||
|                     lfs_commit_mem, &(struct lfs_commit_mem){ |                     lfs_commit_mem, &newentry.d, sizeof(newentry.d), | ||||||
|                         &newentry.d, sizeof(newentry.d)}, |  | ||||||
|                 &(struct lfs_region){ |                 &(struct lfs_region){ | ||||||
|                     0, +newentry.d.nlen, |                     0, +newentry.d.nlen, | ||||||
|                     lfs_commit_mem, &(struct lfs_commit_mem){ |                     lfs_commit_mem, newpath, newentry.d.nlen}}); | ||||||
|                         newpath, newentry.d.nlen}}}); |  | ||||||
|         if (err) { |         if (err) { | ||||||
|             return err; |             return err; | ||||||
|         } |         } | ||||||
| @@ -2302,8 +2287,7 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) { | |||||||
|     for (int i = 0; i < 2; i++) { |     for (int i = 0; i < 2; i++) { | ||||||
|         err = lfs_dir_commit(lfs, &superdir, &(struct lfs_region){ |         err = lfs_dir_commit(lfs, &superdir, &(struct lfs_region){ | ||||||
|                 sizeof(superdir.d), 0, |                 sizeof(superdir.d), 0, | ||||||
|                 lfs_commit_mem, &(struct lfs_commit_mem){ |                 lfs_commit_mem, &superblock.d, sizeof(superblock.d)}); | ||||||
|                     &superblock.d, sizeof(superblock.d)}}); |  | ||||||
|         if (err && err != LFS_ERR_CORRUPT) { |         if (err && err != LFS_ERR_CORRUPT) { | ||||||
|             return err; |             return err; | ||||||
|         } |         } | ||||||
| @@ -2570,8 +2554,7 @@ static int lfs_relocate(lfs_t *lfs, | |||||||
|         int err = lfs_dir_update(lfs, &parent, &entry, |         int err = lfs_dir_update(lfs, &parent, &entry, | ||||||
|                 &(struct lfs_region){ |                 &(struct lfs_region){ | ||||||
|                     0, 0, |                     0, 0, | ||||||
|                     lfs_commit_mem, &(struct lfs_commit_mem){ |                     lfs_commit_mem, &entry.d, sizeof(entry.d)}); | ||||||
|                         &entry.d, sizeof(entry.d)}}); |  | ||||||
|         if (err) { |         if (err) { | ||||||
|             return err; |             return err; | ||||||
|         } |         } | ||||||
| @@ -2698,8 +2681,7 @@ int lfs_deorphan(lfs_t *lfs) { | |||||||
|                     err = lfs_dir_update(lfs, &cwd, &entry, |                     err = lfs_dir_update(lfs, &cwd, &entry, | ||||||
|                             &(struct lfs_region){ |                             &(struct lfs_region){ | ||||||
|                                 0, 0, |                                 0, 0, | ||||||
|                                 lfs_commit_mem, &(struct lfs_commit_mem){ |                                 lfs_commit_mem, &entry.d, sizeof(entry.d)}); | ||||||
|                                     &entry.d, sizeof(entry.d)}}); |  | ||||||
|                     if (err) { |                     if (err) { | ||||||
|                         return err; |                         return err; | ||||||
|                     } |                     } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user