Skip to content

Commit

Permalink
Added dir tests, test fixes, config
Browse files Browse the repository at this point in the history
  • Loading branch information
geky committed Mar 26, 2017
1 parent afa4ad8 commit a711675
Show file tree
Hide file tree
Showing 7 changed files with 248 additions and 60 deletions.
8 changes: 5 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ OBJ := $(SRC:.c=.o)
DEP := $(SRC:.c=.d)
ASM := $(SRC:.c=.s)

TEST := $(wildcard tests/test_*)
TEST := $(patsubst tests/%.sh,%,$(wildcard tests/test_*))

ifdef DEBUG
CFLAGS += -O0 -g3
Expand All @@ -30,8 +30,10 @@ asm: $(ASM)
size: $(OBJ)
$(SIZE) -t $^

test:
for t in $(TEST) ; do ./$$t ; done
.SUFFIXES:
test: $(TEST)
test_%: tests/test_%.sh
./$<

-include $(DEP)

Expand Down
168 changes: 134 additions & 34 deletions lfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ static int lfs_bd_cmp(lfs_t *lfs, lfs_block_t block,
lfs_off_t off, lfs_size_t size, const void *buffer) {
const uint8_t *data = buffer;

while (off < size) {
for (lfs_off_t i = 0; i < size; i++) {
uint8_t c;
int err = lfs_bd_read(lfs, block, off, 1, &c);
int err = lfs_bd_read(lfs, block, off+i, 1, &c);
if (err) {
return err;
}
Expand All @@ -51,7 +51,6 @@ static int lfs_bd_cmp(lfs_t *lfs, lfs_block_t block,
}

data += 1;
off += 1;
}

return true;
Expand Down Expand Up @@ -329,29 +328,35 @@ static int lfs_dir_create(lfs_t *lfs, lfs_dir_t *dir, lfs_block_t parent[2]) {
dir->d.rev += 1;

// Calculate total size
dir->d.size = sizeof(dir->d);
if (parent) {
dir->d.size += sizeof(struct lfs_disk_entry);
}
dir->d.size = sizeof(dir->d) + 2*sizeof(struct lfs_disk_entry) + 3;
dir->off = sizeof(dir->d);

// Other defaults
dir->off = dir->d.size;
dir->d.tail[0] = 0;
dir->d.tail[1] = 0;
dir->d.free = lfs->free;

// Write out to memory
return lfs_pair_commit(lfs, dir->pair,
1 + (parent ? 2 : 0), (struct lfs_commit_region[]){
5, (struct lfs_commit_region[]){
{0, sizeof(dir->d), &dir->d},
{sizeof(dir->d), sizeof(struct lfs_disk_entry),
&(struct lfs_disk_entry){
.type = LFS_TYPE_DIR,
.len = 12+2,
.u.dir[0] = parent ? parent[0] : 0,
.u.dir[1] = parent ? parent[1] : 0,
.len = sizeof(struct lfs_disk_entry)+1,
.u.dir[0] = dir->pair[0],
.u.dir[1] = dir->pair[1],
}},
{sizeof(dir->d)+sizeof(struct lfs_disk_entry), 1, "."},
{sizeof(dir->d)+sizeof(struct lfs_disk_entry)+1,
sizeof(struct lfs_disk_entry),
&(struct lfs_disk_entry){
.type = LFS_TYPE_DIR,
.len = sizeof(struct lfs_disk_entry)+2,
.u.dir[0] = parent ? parent[0] : dir->pair[0],
.u.dir[1] = parent ? parent[1] : dir->pair[1],
}},
{sizeof(dir->d)+sizeof(struct lfs_disk_entry), 2, ".."},
{sizeof(dir->d)+2*sizeof(struct lfs_disk_entry)+1, 2, ".."},
});
}

Expand Down Expand Up @@ -473,9 +478,19 @@ int lfs_mkdir(lfs_t *lfs, const char *path) {
}

int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path) {
int err = lfs_dir_fetch(lfs, dir, lfs->cwd);
if (path[0] == '/') {
dir->pair[0] = lfs->root[0];
dir->pair[1] = lfs->root[1];
} else {
dir->pair[0] = lfs->cwd[0];
dir->pair[1] = lfs->cwd[1];
}

int err = lfs_dir_fetch(lfs, dir, dir->pair);
if (err) {
return err;
} else if (strcmp(path, "/") == 0) {
return 0;
}

lfs_entry_t entry;
Expand All @@ -494,6 +509,29 @@ int lfs_dir_close(lfs_t *lfs, lfs_dir_t *dir) {
return 0;
}

int lfs_dir_read(lfs_t *lfs, lfs_dir_t *dir, struct lfs_info *info) {
memset(info, 0, sizeof(*info));

lfs_entry_t entry;
int err = lfs_dir_next(lfs, dir, &entry);
if (err) {
return (err == LFS_ERROR_NO_ENTRY) ? 0 : err;
}

info->type = entry.d.type & 0xff;
if (info->type == LFS_TYPE_REG) {
info->size = entry.d.u.file.size;
}

err = lfs_bd_read(lfs, entry.dir[0], entry.off + sizeof(entry.d),
entry.d.len - sizeof(entry.d), info->name);
if (err) {
return err;
}

return 1;
}


/// File operations ///

Expand Down Expand Up @@ -548,6 +586,8 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
file->entry.d.len-sizeof(file->entry.d),
path}
});
} else if (file->entry.d.type == LFS_TYPE_DIR) {
return LFS_ERROR_IS_DIR;
} else {
file->head = file->entry.d.u.file.head;
file->size = file->entry.d.u.file.size;
Expand Down Expand Up @@ -675,21 +715,77 @@ lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file,


/// Generic filesystem operations ///
int lfs_format(lfs_t *lfs, lfs_bd_t *bd, const struct lfs_bd_ops *bd_ops) {
lfs->bd = bd;
lfs->bd_ops = bd_ops;
static int lfs_configure(lfs_t *lfs, const struct lfs_config *config) {
lfs->bd = config->bd;
lfs->bd_ops = config->bd_ops;

struct lfs_bd_info info;
int err = lfs_bd_info(lfs, &info);
if (err) {
return err;
}

lfs->read_size = info.read_size;
lfs->prog_size = info.prog_size;
lfs->block_size = info.erase_size;
lfs->block_count = info.total_size / info.erase_size;
lfs->words = info.erase_size / sizeof(uint32_t);
if (config->read_size) {
if (config->read_size < info.read_size ||
config->read_size % info.read_size != 0) {
LFS_ERROR("Invalid read size %u, device has %u\n",
config->read_size, info.read_size);
return LFS_ERROR_INVALID;
}

lfs->read_size = config->read_size;
} else {
lfs->read_size = info.read_size;
}

if (config->prog_size) {
if (config->prog_size < info.prog_size ||
config->prog_size % info.prog_size != 0) {
LFS_ERROR("Invalid prog size %u, device has %u\n",
config->prog_size, info.prog_size);
return LFS_ERROR_INVALID;
}

lfs->prog_size = config->prog_size;
} else {
lfs->prog_size = info.prog_size;
}

if (config->block_size) {
if (config->block_size < info.erase_size ||
config->block_size % info.erase_size != 0) {
LFS_ERROR("Invalid block size %u, device has %u\n",
config->prog_size, info.prog_size);
return LFS_ERROR_INVALID;
}

lfs->block_size = config->block_size;
} else {
lfs->block_size = lfs_min(512, info.erase_size);
}

if (config->block_count) {
if (config->block_count > info.total_size/info.erase_size) {
LFS_ERROR("Invalid block size %u, device has %u\n",
config->block_size,
(uint32_t)(info.total_size/info.erase_size));
return LFS_ERROR_INVALID;
}

lfs->block_count = config->block_count;
} else {
lfs->block_count = info.total_size / info.erase_size;
}

lfs->words = lfs->block_size / sizeof(uint32_t);
return 0;
}

int lfs_format(lfs_t *lfs, const struct lfs_config *config) {
int err = lfs_configure(lfs, config);
if (err) {
return err;
}

// Create free list
lfs->free.begin = 2;
Expand All @@ -701,6 +797,8 @@ int lfs_format(lfs_t *lfs, lfs_bd_t *bd, const struct lfs_bd_ops *bd_ops) {
if (err) {
return err;
}
lfs->root[0] = root.pair[0];
lfs->root[1] = root.pair[1];
lfs->cwd[0] = root.pair[0];
lfs->cwd[1] = root.pair[1];

Expand Down Expand Up @@ -736,22 +834,12 @@ int lfs_format(lfs_t *lfs, lfs_bd_t *bd, const struct lfs_bd_ops *bd_ops) {
return 0;
}

int lfs_mount(lfs_t *lfs, lfs_bd_t *bd, const struct lfs_bd_ops *bd_ops) {
lfs->bd = bd;
lfs->bd_ops = bd_ops;

struct lfs_bd_info info;
int err = lfs_bd_info(lfs, &info);
int lfs_mount(lfs_t *lfs, const struct lfs_config *config) {
int err = lfs_configure(lfs, config);
if (err) {
return err;
}

lfs->read_size = info.read_size;
lfs->prog_size = info.prog_size;
lfs->block_size = info.erase_size;
lfs->block_count = info.total_size / info.erase_size;
lfs->words = info.erase_size / sizeof(uint32_t);

lfs_superblock_t superblock = {
.pair = {0, 1},
};
Expand All @@ -767,9 +855,21 @@ int lfs_mount(lfs_t *lfs, lfs_bd_t *bd, const struct lfs_bd_ops *bd_ops) {
return LFS_ERROR_CORRUPT;
}

lfs->root[0] = superblock.d.root[0];
lfs->root[1] = superblock.d.root[1];
lfs->cwd[0] = superblock.d.root[0];
lfs->cwd[1] = superblock.d.root[1];

// TODO this is wrong, needs to check all dirs
lfs_dir_t dir;
err = lfs_dir_fetch(lfs, &dir, lfs->cwd);
if (err) {
return err;
}

lfs->free.begin = dir.d.free.begin;
lfs->free.end = dir.d.free.end;

return err;
}

Expand Down
29 changes: 25 additions & 4 deletions lfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ enum lfs_error {
LFS_ERROR_NO_ENTRY = -4,
LFS_ERROR_EXISTS = -5,
LFS_ERROR_NOT_DIR = -6,
LFS_ERROR_INVALID = -7,
LFS_ERROR_NO_SPACE = -8,
LFS_ERROR_IS_DIR = -7,
LFS_ERROR_INVALID = -8,
LFS_ERROR_NO_SPACE = -9,
};

enum lfs_type {
Expand All @@ -39,6 +40,22 @@ enum lfs_open_flags {
};


struct lfs_config {
lfs_bd_t *bd;
const struct lfs_bd_ops *bd_ops;

lfs_size_t read_size;
lfs_size_t prog_size;

lfs_size_t block_size;
lfs_size_t block_count;
};

struct lfs_info {
uint8_t type;
lfs_size_t size;
char name[LFS_NAME_MAX+1];
};

typedef struct lfs_entry {
lfs_block_t dir[2];
Expand Down Expand Up @@ -104,6 +121,7 @@ typedef struct lfs {
lfs_bd_t *bd;
const struct lfs_bd_ops *bd_ops;

lfs_block_t root[2];
lfs_block_t cwd[2];
struct lfs_disk_free free;

Expand All @@ -115,11 +133,14 @@ typedef struct lfs {
} lfs_t;

// Functions
int lfs_format(lfs_t *lfs, lfs_bd_t *bd, const struct lfs_bd_ops *bd_ops);
int lfs_mount(lfs_t *lfs, lfs_bd_t *bd, const struct lfs_bd_ops *bd_ops);
int lfs_format(lfs_t *lfs, const struct lfs_config *config);
int lfs_mount(lfs_t *lfs, const struct lfs_config *config);
int lfs_unmount(lfs_t *lfs);

int lfs_mkdir(lfs_t *lfs, const char *path);
int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path);
int lfs_dir_close(lfs_t *lfs, lfs_dir_t *dir);
int lfs_dir_read(lfs_t *lfs, lfs_dir_t *dir, struct lfs_info *info);

int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
const char *path, int flags);
Expand Down
4 changes: 2 additions & 2 deletions tests/stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ def main():
os.path.getsize(os.path.join('blocks', f))
for f in os.listdir('blocks') if re.match('\d+', f))

print 'runtime: %.3f' % (time.time() - os.stat('blocks').st_ctime)

with open('blocks/stats') as file:
s = struct.unpack('<QQQ', file.read())
print 'read_count: %d' % s[0]
print 'prog_count: %d' % s[1]
print 'erase_count: %d' % s[2]

print 'runtime: %.3f' % (time.time() - os.stat('blocks').st_ctime)

if __name__ == "__main__":
main(*sys.argv[1:])
10 changes: 8 additions & 2 deletions tests/template.fmt
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ lfs_t lfs;
lfs_emubd_t bd;
lfs_file_t file[4];
lfs_dir_t dir[4];
struct lfs_bd_info info;
struct lfs_bd_stats stats;
struct lfs_bd_info bd_info;
struct lfs_bd_stats bd_stats;
struct lfs_info info;

uint8_t buffer[1024];
uint8_t wbuffer[1024];
Expand All @@ -35,6 +36,11 @@ lfs_size_t rsize;

uintmax_t res;

const struct lfs_config config = {{
.bd = &bd,
.bd_ops = &lfs_emubd_ops,
}};


int main() {{
lfs_emubd_create(&bd, "blocks");
Expand Down
Loading

0 comments on commit a711675

Please sign in to comment.