Skip to content

Commit

Permalink
Extended entry tag to support attributes
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
geky committed Jul 18, 2017
1 parent 8795f0e commit c2283a2
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 33 deletions.
64 changes: 35 additions & 29 deletions lfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -560,20 +560,20 @@ 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);
}

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);
}

Expand All @@ -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;
Expand Down Expand Up @@ -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];
Expand All @@ -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);
}
}
Expand All @@ -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;
}

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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];

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
}
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
}
}
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -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);
Expand Down
10 changes: 6 additions & 4 deletions lfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit c2283a2

Please sign in to comment.