Skip to content

Commit

Permalink
Added tests for resizable entries and custom attributes
Browse files Browse the repository at this point in the history
Also found some bugs. Should now have a good amount of confidence in
these features.
  • Loading branch information
geky committed Oct 10, 2018
1 parent ea4ded4 commit 61f454b
Show file tree
Hide file tree
Showing 6 changed files with 605 additions and 64 deletions.
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ size: $(OBJ)
$(SIZE) -t $^

.SUFFIXES:
test: test_format test_dirs test_files test_seek test_truncate \
test_interspersed test_alloc test_paths test_orphan test_move test_corrupt
test: test_format test_dirs test_files test_seek test_truncate test_entries \
test_interspersed test_alloc test_paths test_attrs \
test_orphan test_move test_corrupt
test_%: tests/test_%.sh
ifdef QUIET
@./$< | sed -n '/^[-=]/p'
Expand Down
132 changes: 71 additions & 61 deletions lfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1739,87 +1739,87 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
}

int lfs_file_close(lfs_t *lfs, lfs_file_t *file) {
int err = lfs_file_sync(lfs, file);
int err = lfs_file_sync(lfs, file);

// remove from list of files
for (lfs_file_t **p = &lfs->files; *p; p = &(*p)->next) {
if (*p == file) {
*p = file->next;
break;
}
// remove from list of files
for (lfs_file_t **p = &lfs->files; *p; p = &(*p)->next) {
if (*p == file) {
*p = file->next;
break;
}
}

// clean up memory
if (!lfs->cfg->file_buffer) {
lfs_free(file->cache.buffer);
}
// clean up memory
if (!lfs->cfg->file_buffer) {
lfs_free(file->cache.buffer);
}

return err;
}

static int lfs_file_relocate(lfs_t *lfs, lfs_file_t *file) {
relocate:;
// just relocate what exists into new block
lfs_block_t nblock;
int err = lfs_alloc(lfs, &nblock);
if (err) {
return err;
}

static int lfs_file_relocate(lfs_t *lfs, lfs_file_t *file) {
relocate:;
// just relocate what exists into new block
lfs_block_t nblock;
int err = lfs_alloc(lfs, &nblock);
err = lfs_bd_erase(lfs, nblock);
if (err) {
if (err == LFS_ERR_CORRUPT) {
goto relocate;
}
return err;
}

// either read from dirty cache or disk
for (lfs_off_t i = 0; i < file->off; i++) {
uint8_t data;
err = lfs_cache_read(lfs, &lfs->rcache, &file->cache,
file->block, i, &data, 1);
if (err) {
return err;
}

err = lfs_bd_erase(lfs, nblock);
err = lfs_cache_prog(lfs, &lfs->pcache, &lfs->rcache,
nblock, i, &data, 1);
if (err) {
if (err == LFS_ERR_CORRUPT) {
goto relocate;
}
return err;
}
}

// either read from dirty cache or disk
for (lfs_off_t i = 0; i < file->off; i++) {
uint8_t data;
err = lfs_cache_read(lfs, &lfs->rcache, &file->cache,
file->block, i, &data, 1);
if (err) {
return err;
}

err = lfs_cache_prog(lfs, &lfs->pcache, &lfs->rcache,
nblock, i, &data, 1);
if (err) {
if (err == LFS_ERR_CORRUPT) {
goto relocate;
}
return err;
}
}
// copy over new state of file
memcpy(file->cache.buffer, lfs->pcache.buffer, lfs->cfg->prog_size);
file->cache.block = lfs->pcache.block;
file->cache.off = lfs->pcache.off;
lfs->pcache.block = 0xffffffff;

// copy over new state of file
memcpy(file->cache.buffer, lfs->pcache.buffer, lfs->cfg->prog_size);
file->cache.block = lfs->pcache.block;
file->cache.off = lfs->pcache.off;
lfs->pcache.block = 0xffffffff;
file->block = nblock;
return 0;
}

file->block = nblock;
return 0;
static int lfs_file_flush(lfs_t *lfs, lfs_file_t *file) {
if (file->flags & LFS_F_READING) {
file->flags &= ~LFS_F_READING;
}

static int lfs_file_flush(lfs_t *lfs, lfs_file_t *file) {
if (file->flags & LFS_F_READING) {
file->flags &= ~LFS_F_READING;
}

if (file->flags & LFS_F_WRITING) {
lfs_off_t pos = file->pos;
if (file->flags & LFS_F_WRITING) {
lfs_off_t pos = file->pos;

if (!(file->flags & LFS_F_INLINE)) {
// copy over anything after current branch
lfs_file_t orig = {
.head = file->head,
.size = file->size,
.flags = LFS_O_RDONLY,
.pos = file->pos,
.cache = lfs->rcache,
};
if (!(file->flags & LFS_F_INLINE)) {
// copy over anything after current branch
lfs_file_t orig = {
.head = file->head,
.size = file->size,
.flags = LFS_O_RDONLY,
.pos = file->pos,
.cache = lfs->rcache,
};
lfs->rcache.block = 0xffffffff;

while (file->pos < file->size) {
Expand Down Expand Up @@ -2270,6 +2270,7 @@ int lfs_file_getattrs(lfs_t *lfs, lfs_file_t *file,
return LFS_ERR_RANGE;
}

memset(attrs[j].buffer, 0, attrs[j].size);
memcpy(attrs[j].buffer,
file->attrs[i].buffer, file->attrs[i].size);
}
Expand All @@ -2281,9 +2282,9 @@ int lfs_file_getattrs(lfs_t *lfs, lfs_file_t *file,

int lfs_file_setattrs(lfs_t *lfs, lfs_file_t *file,
const struct lfs_attr *attrs, int count) {
// just tack to the file, will be written at sync time
file->attrs = attrs;
file->attrcount = count;
if ((file->flags & 3) == LFS_O_RDONLY) {
return LFS_ERR_BADF;
}

// at least make sure attributes fit
if (!lfs_pairisnull(file->pair)) {
Expand All @@ -2306,6 +2307,11 @@ int lfs_file_setattrs(lfs_t *lfs, lfs_file_t *file,
}
}

// just tack to the file, will be written at sync time
file->attrs = attrs;
file->attrcount = count;
file->flags |= LFS_F_DIRTY;

return 0;
}

Expand Down Expand Up @@ -2432,6 +2438,10 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
return LFS_ERR_NAMETOOLONG;
}

if (oldentry.size - oldentry.d.nlen + nlen > lfs->cfg->block_size) {
return LFS_ERR_NOSPC;
}

// must have same type
if (prevexists && preventry.d.type != oldentry.d.type) {
return LFS_ERR_ISDIR;
Expand Down
2 changes: 1 addition & 1 deletion tests/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def generate(test):
template = file.read()

lines = []
for line in re.split('(?<=[;{}])\n', test.read()):
for line in re.split('(?<=(?:.;| [{}]))\n', test.read()):
match = re.match('(?: *\n)*( *)(.*)=>(.*);', line, re.DOTALL | re.MULTILINE)
if match:
tab, test, expect = match.groups()
Expand Down
Loading

0 comments on commit 61f454b

Please sign in to comment.