From 87df75d009c77c46261c1c5d49c808c16573b437 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Thu, 15 Mar 2018 20:58:29 -0500 Subject: [PATCH] WIP added entry size field --- lfs.c | 82 +++++++++++++++++++++++------------------------------------ lfs.h | 3 +-- 2 files changed, 33 insertions(+), 52 deletions(-) diff --git a/lfs.c b/lfs.c index ef5a978..c7b3fa1 100644 --- a/lfs.c +++ b/lfs.c @@ -387,10 +387,6 @@ static inline bool lfs_pairsync( (paira[0] == pairb[1] && paira[1] == pairb[0]); } -static inline lfs_size_t lfs_entry_size(const lfs_entry_t *entry) { - return 4 + entry->d.elen + entry->d.alen + entry->d.nlen; -} - static int lfs_dir_alloc(lfs_t *lfs, lfs_dir_t *dir) { // allocate pair of dir blocks for (int i = 0; i < 2; i++) { @@ -667,14 +663,14 @@ relocate: return 0; } -static int lfs_dir_append_(lfs_t *lfs, lfs_dir_t *dir, - lfs_off_t *off, lfs_size_t size, struct lfs_region *regions) { +static int lfs_dir_append(lfs_t *lfs, lfs_dir_t *dir, + lfs_entry_t *entry, struct lfs_region *regions) { // check if we fit, if top bit is set we do not and move on while (true) { - if ((0x7fffffff & dir->d.size) + size <= lfs->cfg->block_size) { - *off = dir->d.size - 4; + if ((0x7fffffff & dir->d.size) + entry->size <= lfs->cfg->block_size) { + entry->off = dir->d.size - 4; for (struct lfs_region *r = regions; r; r = r->next) { - r->off += *off; + r->off += entry->off; } return lfs_dir_commit(lfs, dir, regions); @@ -690,9 +686,9 @@ static int lfs_dir_append_(lfs_t *lfs, lfs_dir_t *dir, dir->d.tail[0] = olddir.d.tail[0]; dir->d.tail[1] = olddir.d.tail[1]; - *off = dir->d.size - 4; + entry->off = dir->d.size - 4; for (struct lfs_region *r = regions; r; r = r->next) { - r->off += *off; + r->off += entry->off; } err = lfs_dir_commit(lfs, dir, regions); @@ -713,10 +709,10 @@ static int lfs_dir_append_(lfs_t *lfs, lfs_dir_t *dir, } } -static int lfs_dir_remove_(lfs_t *lfs, lfs_dir_t *dir, - lfs_off_t off, lfs_size_t size) { +static int lfs_dir_remove(lfs_t *lfs, lfs_dir_t *dir, + const lfs_entry_t *entry) { // check if we should just drop the directory block - if ((dir->d.size & 0x7fffffff) == sizeof(dir->d)+4 + size) { + if ((dir->d.size & 0x7fffffff) == sizeof(dir->d)+4 + entry->size) { lfs_dir_t pdir; int res = lfs_pred(lfs, dir->pair, &pdir); if (res < 0) { @@ -734,7 +730,7 @@ static int lfs_dir_remove_(lfs_t *lfs, lfs_dir_t *dir, // shift out the entry int err = lfs_dir_commit(lfs, dir, &(struct lfs_region){ - off, -size, + entry->off, -entry->size, lfs_commit_mem, NULL, 0}); if (err) { return err; @@ -743,20 +739,20 @@ static int lfs_dir_remove_(lfs_t *lfs, lfs_dir_t *dir, // shift over any files/directories that are affected for (lfs_file_t *f = lfs->files; f; f = f->next) { if (lfs_paircmp(f->pair, dir->pair) == 0) { - if (f->poff == off) { + if (f->poff == entry->off) { f->pair[0] = 0xffffffff; f->pair[1] = 0xffffffff; - } else if (f->poff > off) { - f->poff -= size; + } else if (f->poff > entry->off) { + f->poff -= entry->size; } } } for (lfs_dir_t *d = lfs->dirs; d; d = d->next) { if (lfs_paircmp(d->pair, dir->pair) == 0) { - if (d->off > off) { - d->off -= size; - d->pos -= size; + if (d->off > entry->off) { + d->off -= entry->size; + d->pos -= entry->size; } } } @@ -764,17 +760,6 @@ static int lfs_dir_remove_(lfs_t *lfs, lfs_dir_t *dir, return 0; } -static int lfs_dir_append(lfs_t *lfs, lfs_dir_t *dir, - lfs_entry_t *entry, struct lfs_region *regions) { - return lfs_dir_append_(lfs, dir, - &entry->off, lfs_entry_size(entry), regions); -} - -static int lfs_dir_remove(lfs_t *lfs, lfs_dir_t *dir, lfs_entry_t *entry) { - return lfs_dir_remove_(lfs, dir, - entry->off, lfs_entry_size(entry)); -} - static int lfs_dir_update(lfs_t *lfs, lfs_dir_t *dir, lfs_entry_t *entry, struct lfs_region *regions) { lfs_ssize_t diff = 0; @@ -813,7 +798,7 @@ static int lfs_dir_update(lfs_t *lfs, lfs_dir_t *dir, } else { lfs_dir_t olddir = *dir; lfs_off_t oldoff = entry->off; - lfs_size_t oldsize = lfs_entry_size(entry) - diff; + lfs_size_t oldsize = entry->size - diff; // mark as moving entry->d.type |= LFS_STRUCT_MOVED; @@ -829,7 +814,7 @@ static int lfs_dir_update(lfs_t *lfs, lfs_dir_t *dir, // append updated entry err = lfs_dir_append(lfs, dir, entry, &(struct lfs_region){ - 0, +lfs_entry_size(entry), + 0, +entry->size, lfs_commit_disk, &(struct lfs_commit_disk){ olddir.pair[0], entry->off, regions}, oldsize}); if (err) { @@ -837,13 +822,10 @@ static int lfs_dir_update(lfs_t *lfs, lfs_dir_t *dir, } // remove old entry - err = lfs_dir_remove_(lfs, dir, oldoff, oldsize); + err = lfs_dir_remove(lfs, dir, &(lfs_entry_t){oldoff, oldsize}); if (err) { return err; } - - // TODO remove file under file? - // TODO need to shift entries? } return 0; @@ -873,8 +855,9 @@ static int lfs_dir_next(lfs_t *lfs, lfs_dir_t *dir, lfs_entry_t *entry) { } entry->off = dir->off; - dir->off += lfs_entry_size(entry); - dir->pos += lfs_entry_size(entry); + entry->size = 4 + entry->d.elen + entry->d.alen + entry->d.nlen; + dir->off += entry->size; + dir->pos += entry->size; return 0; } @@ -893,9 +876,6 @@ static int lfs_dir_find(lfs_t *lfs, lfs_dir_t *dir, if (pathname[0] == '\0') { *entry = (lfs_entry_t){ .d.type = LFS_STRUCT_DIR | LFS_TYPE_DIR, - .d.elen = sizeof(entry->d) - 4, - .d.alen = 0, - .d.nlen = 0, .d.u.dir[0] = lfs->root[0], .d.u.dir[1] = lfs->root[1], }; @@ -950,7 +930,7 @@ static int lfs_dir_find(lfs_t *lfs, lfs_dir_t *dir, } int res = lfs_bd_cmp(lfs, dir->pair[0], - entry->off + 4+entry->d.elen+entry->d.alen, + entry->off + entry->size - pathlen, pathname, pathlen); if (res < 0) { return res; @@ -1036,6 +1016,7 @@ int lfs_mkdir(lfs_t *lfs, const char *path) { entry.d.nlen = strlen(path); entry.d.u.dir[0] = dir.pair[0]; entry.d.u.dir[1] = dir.pair[1]; + entry.size = 4 + entry.d.elen + entry.d.alen + entry.d.nlen; cwd.d.tail[0] = dir.pair[0]; cwd.d.tail[1] = dir.pair[1]; @@ -1154,7 +1135,7 @@ int lfs_dir_read(lfs_t *lfs, lfs_dir_t *dir, struct lfs_info *info) { } int err = lfs_bd_read(lfs, dir->pair[0], - entry.off + 4+entry.d.elen+entry.d.alen, + entry.off + entry.size - entry.d.nlen, info->name, entry.d.nlen); if (err) { return err; @@ -1430,6 +1411,8 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file, entry.d.nlen = strlen(path); entry.d.u.file.head = 0xffffffff; entry.d.u.file.size = 0; + entry.size = 4 + entry.d.elen + entry.d.alen + entry.d.nlen; + err = lfs_dir_append(lfs, &cwd, &entry, &(struct lfs_region){ 0, +sizeof(entry.d), @@ -1949,7 +1932,7 @@ int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info) { strcpy(info->name, "/"); } else { err = lfs_bd_read(lfs, cwd.pair[0], - entry.off + 4+entry.d.elen+entry.d.alen, + entry.off + entry.size - entry.d.nlen, info->name, entry.d.nlen); if (err) { return err; @@ -2262,7 +2245,6 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) { // write superblocks lfs_superblock_t superblock = { - .off = sizeof(superdir.d), .d.type = LFS_STRUCT_DIR | LFS_TYPE_SUPERBLOCK, .d.elen = sizeof(superblock.d) - sizeof(superblock.d.magic) - 4, .d.nlen = sizeof(superblock.d.magic), @@ -2364,8 +2346,6 @@ int lfs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data) { } // iterate over metadata pairs - lfs_dir_t dir; - lfs_entry_t entry; lfs_block_t cwd[2] = {0, 1}; while (true) { @@ -2376,12 +2356,14 @@ int lfs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data) { } } + lfs_dir_t dir; int err = lfs_dir_fetch(lfs, &dir, cwd); if (err) { return err; } // iterate over contents + lfs_entry_t entry; while (dir.off + sizeof(entry.d) <= (0x7fffffff & dir.d.size)-4) { err = lfs_bd_read(lfs, dir.pair[0], dir.off, &entry.d, sizeof(entry.d)); @@ -2390,7 +2372,7 @@ int lfs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data) { return err; } - dir.off += lfs_entry_size(&entry); + dir.off += 4 + entry.d.elen + entry.d.alen + entry.d.nlen; if ((0x70 & entry.d.type) == LFS_STRUCT_CTZ) { err = lfs_ctz_traverse(lfs, &lfs->rcache, NULL, entry.d.u.file.head, entry.d.u.file.size, cb, data); diff --git a/lfs.h b/lfs.h index bbdcde6..91e7232 100644 --- a/lfs.h +++ b/lfs.h @@ -196,6 +196,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; @@ -249,8 +250,6 @@ 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;