Skip to content

Commit a711675

Browse files
committed
Added dir tests, test fixes, config
1 parent afa4ad8 commit a711675

File tree

7 files changed

+248
-60
lines changed

7 files changed

+248
-60
lines changed

Makefile

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ OBJ := $(SRC:.c=.o)
99
DEP := $(SRC:.c=.d)
1010
ASM := $(SRC:.c=.s)
1111

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

1414
ifdef DEBUG
1515
CFLAGS += -O0 -g3
@@ -30,8 +30,10 @@ asm: $(ASM)
3030
size: $(OBJ)
3131
$(SIZE) -t $^
3232

33-
test:
34-
for t in $(TEST) ; do ./$$t ; done
33+
.SUFFIXES:
34+
test: $(TEST)
35+
test_%: tests/test_%.sh
36+
./$<
3537

3638
-include $(DEP)
3739

lfs.c

Lines changed: 134 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ static int lfs_bd_cmp(lfs_t *lfs, lfs_block_t block,
3939
lfs_off_t off, lfs_size_t size, const void *buffer) {
4040
const uint8_t *data = buffer;
4141

42-
while (off < size) {
42+
for (lfs_off_t i = 0; i < size; i++) {
4343
uint8_t c;
44-
int err = lfs_bd_read(lfs, block, off, 1, &c);
44+
int err = lfs_bd_read(lfs, block, off+i, 1, &c);
4545
if (err) {
4646
return err;
4747
}
@@ -51,7 +51,6 @@ static int lfs_bd_cmp(lfs_t *lfs, lfs_block_t block,
5151
}
5252

5353
data += 1;
54-
off += 1;
5554
}
5655

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

331330
// Calculate total size
332-
dir->d.size = sizeof(dir->d);
333-
if (parent) {
334-
dir->d.size += sizeof(struct lfs_disk_entry);
335-
}
331+
dir->d.size = sizeof(dir->d) + 2*sizeof(struct lfs_disk_entry) + 3;
332+
dir->off = sizeof(dir->d);
336333

337334
// Other defaults
338-
dir->off = dir->d.size;
339335
dir->d.tail[0] = 0;
340336
dir->d.tail[1] = 0;
341337
dir->d.free = lfs->free;
342338

343339
// Write out to memory
344340
return lfs_pair_commit(lfs, dir->pair,
345-
1 + (parent ? 2 : 0), (struct lfs_commit_region[]){
341+
5, (struct lfs_commit_region[]){
346342
{0, sizeof(dir->d), &dir->d},
347343
{sizeof(dir->d), sizeof(struct lfs_disk_entry),
348344
&(struct lfs_disk_entry){
349345
.type = LFS_TYPE_DIR,
350-
.len = 12+2,
351-
.u.dir[0] = parent ? parent[0] : 0,
352-
.u.dir[1] = parent ? parent[1] : 0,
346+
.len = sizeof(struct lfs_disk_entry)+1,
347+
.u.dir[0] = dir->pair[0],
348+
.u.dir[1] = dir->pair[1],
349+
}},
350+
{sizeof(dir->d)+sizeof(struct lfs_disk_entry), 1, "."},
351+
{sizeof(dir->d)+sizeof(struct lfs_disk_entry)+1,
352+
sizeof(struct lfs_disk_entry),
353+
&(struct lfs_disk_entry){
354+
.type = LFS_TYPE_DIR,
355+
.len = sizeof(struct lfs_disk_entry)+2,
356+
.u.dir[0] = parent ? parent[0] : dir->pair[0],
357+
.u.dir[1] = parent ? parent[1] : dir->pair[1],
353358
}},
354-
{sizeof(dir->d)+sizeof(struct lfs_disk_entry), 2, ".."},
359+
{sizeof(dir->d)+2*sizeof(struct lfs_disk_entry)+1, 2, ".."},
355360
});
356361
}
357362

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

475480
int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path) {
476-
int err = lfs_dir_fetch(lfs, dir, lfs->cwd);
481+
if (path[0] == '/') {
482+
dir->pair[0] = lfs->root[0];
483+
dir->pair[1] = lfs->root[1];
484+
} else {
485+
dir->pair[0] = lfs->cwd[0];
486+
dir->pair[1] = lfs->cwd[1];
487+
}
488+
489+
int err = lfs_dir_fetch(lfs, dir, dir->pair);
477490
if (err) {
478491
return err;
492+
} else if (strcmp(path, "/") == 0) {
493+
return 0;
479494
}
480495

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

512+
int lfs_dir_read(lfs_t *lfs, lfs_dir_t *dir, struct lfs_info *info) {
513+
memset(info, 0, sizeof(*info));
514+
515+
lfs_entry_t entry;
516+
int err = lfs_dir_next(lfs, dir, &entry);
517+
if (err) {
518+
return (err == LFS_ERROR_NO_ENTRY) ? 0 : err;
519+
}
520+
521+
info->type = entry.d.type & 0xff;
522+
if (info->type == LFS_TYPE_REG) {
523+
info->size = entry.d.u.file.size;
524+
}
525+
526+
err = lfs_bd_read(lfs, entry.dir[0], entry.off + sizeof(entry.d),
527+
entry.d.len - sizeof(entry.d), info->name);
528+
if (err) {
529+
return err;
530+
}
531+
532+
return 1;
533+
}
534+
497535

498536
/// File operations ///
499537

@@ -548,6 +586,8 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
548586
file->entry.d.len-sizeof(file->entry.d),
549587
path}
550588
});
589+
} else if (file->entry.d.type == LFS_TYPE_DIR) {
590+
return LFS_ERROR_IS_DIR;
551591
} else {
552592
file->head = file->entry.d.u.file.head;
553593
file->size = file->entry.d.u.file.size;
@@ -675,21 +715,77 @@ lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file,
675715

676716

677717
/// Generic filesystem operations ///
678-
int lfs_format(lfs_t *lfs, lfs_bd_t *bd, const struct lfs_bd_ops *bd_ops) {
679-
lfs->bd = bd;
680-
lfs->bd_ops = bd_ops;
718+
static int lfs_configure(lfs_t *lfs, const struct lfs_config *config) {
719+
lfs->bd = config->bd;
720+
lfs->bd_ops = config->bd_ops;
681721

682722
struct lfs_bd_info info;
683723
int err = lfs_bd_info(lfs, &info);
684724
if (err) {
685725
return err;
686726
}
687727

688-
lfs->read_size = info.read_size;
689-
lfs->prog_size = info.prog_size;
690-
lfs->block_size = info.erase_size;
691-
lfs->block_count = info.total_size / info.erase_size;
692-
lfs->words = info.erase_size / sizeof(uint32_t);
728+
if (config->read_size) {
729+
if (config->read_size < info.read_size ||
730+
config->read_size % info.read_size != 0) {
731+
LFS_ERROR("Invalid read size %u, device has %u\n",
732+
config->read_size, info.read_size);
733+
return LFS_ERROR_INVALID;
734+
}
735+
736+
lfs->read_size = config->read_size;
737+
} else {
738+
lfs->read_size = info.read_size;
739+
}
740+
741+
if (config->prog_size) {
742+
if (config->prog_size < info.prog_size ||
743+
config->prog_size % info.prog_size != 0) {
744+
LFS_ERROR("Invalid prog size %u, device has %u\n",
745+
config->prog_size, info.prog_size);
746+
return LFS_ERROR_INVALID;
747+
}
748+
749+
lfs->prog_size = config->prog_size;
750+
} else {
751+
lfs->prog_size = info.prog_size;
752+
}
753+
754+
if (config->block_size) {
755+
if (config->block_size < info.erase_size ||
756+
config->block_size % info.erase_size != 0) {
757+
LFS_ERROR("Invalid block size %u, device has %u\n",
758+
config->prog_size, info.prog_size);
759+
return LFS_ERROR_INVALID;
760+
}
761+
762+
lfs->block_size = config->block_size;
763+
} else {
764+
lfs->block_size = lfs_min(512, info.erase_size);
765+
}
766+
767+
if (config->block_count) {
768+
if (config->block_count > info.total_size/info.erase_size) {
769+
LFS_ERROR("Invalid block size %u, device has %u\n",
770+
config->block_size,
771+
(uint32_t)(info.total_size/info.erase_size));
772+
return LFS_ERROR_INVALID;
773+
}
774+
775+
lfs->block_count = config->block_count;
776+
} else {
777+
lfs->block_count = info.total_size / info.erase_size;
778+
}
779+
780+
lfs->words = lfs->block_size / sizeof(uint32_t);
781+
return 0;
782+
}
783+
784+
int lfs_format(lfs_t *lfs, const struct lfs_config *config) {
785+
int err = lfs_configure(lfs, config);
786+
if (err) {
787+
return err;
788+
}
693789

694790
// Create free list
695791
lfs->free.begin = 2;
@@ -701,6 +797,8 @@ int lfs_format(lfs_t *lfs, lfs_bd_t *bd, const struct lfs_bd_ops *bd_ops) {
701797
if (err) {
702798
return err;
703799
}
800+
lfs->root[0] = root.pair[0];
801+
lfs->root[1] = root.pair[1];
704802
lfs->cwd[0] = root.pair[0];
705803
lfs->cwd[1] = root.pair[1];
706804

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

739-
int lfs_mount(lfs_t *lfs, lfs_bd_t *bd, const struct lfs_bd_ops *bd_ops) {
740-
lfs->bd = bd;
741-
lfs->bd_ops = bd_ops;
742-
743-
struct lfs_bd_info info;
744-
int err = lfs_bd_info(lfs, &info);
837+
int lfs_mount(lfs_t *lfs, const struct lfs_config *config) {
838+
int err = lfs_configure(lfs, config);
745839
if (err) {
746840
return err;
747841
}
748842

749-
lfs->read_size = info.read_size;
750-
lfs->prog_size = info.prog_size;
751-
lfs->block_size = info.erase_size;
752-
lfs->block_count = info.total_size / info.erase_size;
753-
lfs->words = info.erase_size / sizeof(uint32_t);
754-
755843
lfs_superblock_t superblock = {
756844
.pair = {0, 1},
757845
};
@@ -767,9 +855,21 @@ int lfs_mount(lfs_t *lfs, lfs_bd_t *bd, const struct lfs_bd_ops *bd_ops) {
767855
return LFS_ERROR_CORRUPT;
768856
}
769857

858+
lfs->root[0] = superblock.d.root[0];
859+
lfs->root[1] = superblock.d.root[1];
770860
lfs->cwd[0] = superblock.d.root[0];
771861
lfs->cwd[1] = superblock.d.root[1];
772862

863+
// TODO this is wrong, needs to check all dirs
864+
lfs_dir_t dir;
865+
err = lfs_dir_fetch(lfs, &dir, lfs->cwd);
866+
if (err) {
867+
return err;
868+
}
869+
870+
lfs->free.begin = dir.d.free.begin;
871+
lfs->free.end = dir.d.free.end;
872+
773873
return err;
774874
}
775875

lfs.h

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ enum lfs_error {
1818
LFS_ERROR_NO_ENTRY = -4,
1919
LFS_ERROR_EXISTS = -5,
2020
LFS_ERROR_NOT_DIR = -6,
21-
LFS_ERROR_INVALID = -7,
22-
LFS_ERROR_NO_SPACE = -8,
21+
LFS_ERROR_IS_DIR = -7,
22+
LFS_ERROR_INVALID = -8,
23+
LFS_ERROR_NO_SPACE = -9,
2324
};
2425

2526
enum lfs_type {
@@ -39,6 +40,22 @@ enum lfs_open_flags {
3940
};
4041

4142

43+
struct lfs_config {
44+
lfs_bd_t *bd;
45+
const struct lfs_bd_ops *bd_ops;
46+
47+
lfs_size_t read_size;
48+
lfs_size_t prog_size;
49+
50+
lfs_size_t block_size;
51+
lfs_size_t block_count;
52+
};
53+
54+
struct lfs_info {
55+
uint8_t type;
56+
lfs_size_t size;
57+
char name[LFS_NAME_MAX+1];
58+
};
4259

4360
typedef struct lfs_entry {
4461
lfs_block_t dir[2];
@@ -104,6 +121,7 @@ typedef struct lfs {
104121
lfs_bd_t *bd;
105122
const struct lfs_bd_ops *bd_ops;
106123

124+
lfs_block_t root[2];
107125
lfs_block_t cwd[2];
108126
struct lfs_disk_free free;
109127

@@ -115,11 +133,14 @@ typedef struct lfs {
115133
} lfs_t;
116134

117135
// Functions
118-
int lfs_format(lfs_t *lfs, lfs_bd_t *bd, const struct lfs_bd_ops *bd_ops);
119-
int lfs_mount(lfs_t *lfs, lfs_bd_t *bd, const struct lfs_bd_ops *bd_ops);
136+
int lfs_format(lfs_t *lfs, const struct lfs_config *config);
137+
int lfs_mount(lfs_t *lfs, const struct lfs_config *config);
120138
int lfs_unmount(lfs_t *lfs);
121139

122140
int lfs_mkdir(lfs_t *lfs, const char *path);
141+
int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path);
142+
int lfs_dir_close(lfs_t *lfs, lfs_dir_t *dir);
143+
int lfs_dir_read(lfs_t *lfs, lfs_dir_t *dir, struct lfs_info *info);
123144

124145
int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
125146
const char *path, int flags);

tests/stats.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ def main():
1818
os.path.getsize(os.path.join('blocks', f))
1919
for f in os.listdir('blocks') if re.match('\d+', f))
2020

21-
print 'runtime: %.3f' % (time.time() - os.stat('blocks').st_ctime)
22-
2321
with open('blocks/stats') as file:
2422
s = struct.unpack('<QQQ', file.read())
2523
print 'read_count: %d' % s[0]
2624
print 'prog_count: %d' % s[1]
2725
print 'erase_count: %d' % s[2]
2826

27+
print 'runtime: %.3f' % (time.time() - os.stat('blocks').st_ctime)
28+
2929
if __name__ == "__main__":
3030
main(*sys.argv[1:])

tests/template.fmt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ lfs_t lfs;
2323
lfs_emubd_t bd;
2424
lfs_file_t file[4];
2525
lfs_dir_t dir[4];
26-
struct lfs_bd_info info;
27-
struct lfs_bd_stats stats;
26+
struct lfs_bd_info bd_info;
27+
struct lfs_bd_stats bd_stats;
28+
struct lfs_info info;
2829

2930
uint8_t buffer[1024];
3031
uint8_t wbuffer[1024];
@@ -35,6 +36,11 @@ lfs_size_t rsize;
3536

3637
uintmax_t res;
3738

39+
const struct lfs_config config = {{
40+
.bd = &bd,
41+
.bd_ops = &lfs_emubd_ops,
42+
}};
43+
3844

3945
int main() {{
4046
lfs_emubd_create(&bd, "blocks");

0 commit comments

Comments
 (0)