Skip to content

Commit

Permalink
Added file list for tracking in flight allocations
Browse files Browse the repository at this point in the history
Needed primarily for tracking block allocations, unfortunately
this prevents the freedom for the user to bitwise copy files.
  • Loading branch information
geky committed May 8, 2017
1 parent b55719b commit 210b487
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 6 deletions.
53 changes: 47 additions & 6 deletions lfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,13 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) {
}

// scan again or die trying
return lfs_alloc_scan(lfs, block);
err = lfs_alloc_scan(lfs, block);
if (err) {
LFS_WARN("No more free space%s", "");
return err;
}

return 0;
}


Expand Down Expand Up @@ -1010,11 +1016,25 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
file->size = 0;
}

// add to list of files
file->next = lfs->files;
lfs->files = file;

return 0;
}

int lfs_file_close(lfs_t *lfs, lfs_file_t *file) {
return 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;
}
}

return err;
}

static int lfs_file_flush(lfs_t *lfs, lfs_file_t *file) {
Expand Down Expand Up @@ -1453,6 +1473,9 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
}
}

// setup files as an empty list
lfs->files = NULL;

return 0;
}

Expand Down Expand Up @@ -1612,8 +1635,7 @@ int lfs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data) {
dir.off += entry.d.len;
if ((0xf & entry.d.type) == LFS_TYPE_REG) {
int err = lfs_index_traverse(lfs,
entry.d.u.file.head, entry.d.u.file.size,
cb, data);
entry.d.u.file.head, entry.d.u.file.size, cb, data);
if (err) {
return err;
}
Expand All @@ -1623,10 +1645,29 @@ int lfs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data) {
cwd[0] = dir.d.tail[0];
cwd[1] = dir.d.tail[1];

if (!cwd[0]) {
return 0;
if (lfs_pairisnull(cwd)) {
break;
}
}

// iterate over any open files
for (lfs_file_t *f = lfs->files; f; f = f->next) {
if (f->flags & LFS_O_DIRTY) {
int err = lfs_index_traverse(lfs, f->head, f->size, cb, data);
if (err) {
return err;
}
}

if (f->wblock) {
int err = lfs_index_traverse(lfs, f->wblock, f->pos, cb, data);
if (err) {
return err;
}
}
}

return 0;
}

static int lfs_parent(lfs_t *lfs, const lfs_block_t dir[2]) {
Expand Down
2 changes: 2 additions & 0 deletions lfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ typedef struct lfs_entry {
} lfs_entry_t;

typedef struct lfs_file {
struct lfs_file *next;
lfs_block_t pair[2];
lfs_off_t off;
lfs_block_t head;
Expand Down Expand Up @@ -194,6 +195,7 @@ typedef struct lfs {
lfs_size_t words; // number of 32-bit words that can fit in a block

lfs_block_t root[2];
lfs_file_t *files;

struct {
lfs_block_t block;
Expand Down
83 changes: 83 additions & 0 deletions tests/test_alloc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -110,5 +110,88 @@ lfs_alloc_singleproc multiprocreuse
lfs_verify multiprocreuse
lfs_verify singleprocreuse

echo "--- Cleanup ---"
lfs_remove multiprocreuse
lfs_remove singleprocreuse

echo "--- Exhaustion test ---"
tests/test.py << TEST
lfs_mount(&lfs, &cfg) => 0;
lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
size = strlen("exhaustion");
memcpy(buffer, "exhaustion", size);
lfs_file_write(&lfs, &file[0], buffer, size) => size;
size = strlen("blahblahblahblah");
memcpy(buffer, "blahblahblahblah", size);
lfs_ssize_t res;
while (true) {
res = lfs_file_write(&lfs, &file[0], buffer, size);
if (res < 0) {
break;
}
res => size;
}
res => LFS_ERR_NOSPC;
lfs_file_close(&lfs, &file[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
tests/test.py << TEST
lfs_mount(&lfs, &cfg) => 0;
lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_RDONLY);
size = strlen("exhaustion");
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "exhaustion", size) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST

echo "--- Exhaustion wraparound test ---"
tests/test.py << TEST
lfs_mount(&lfs, &cfg) => 0;
lfs_remove(&lfs, "exhaustion") => 0;
lfs_file_open(&lfs, &file[0], "padding", LFS_O_WRONLY | LFS_O_CREAT);
size = strlen("buffering");
memcpy(buffer, "buffering", size);
for (int i = 0; i < $SIZE; i++) {
lfs_file_write(&lfs, &file[0], buffer, size) => size;
}
lfs_file_close(&lfs, &file[0]) => 0;
lfs_remove(&lfs, "padding") => 0;
lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
size = strlen("exhaustion");
memcpy(buffer, "exhaustion", size);
lfs_file_write(&lfs, &file[0], buffer, size) => size;
size = strlen("blahblahblahblah");
memcpy(buffer, "blahblahblahblah", size);
lfs_ssize_t res;
while (true) {
res = lfs_file_write(&lfs, &file[0], buffer, size);
if (res < 0) {
break;
}
res => size;
}
res => LFS_ERR_NOSPC;
lfs_file_close(&lfs, &file[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
tests/test.py << TEST
lfs_mount(&lfs, &cfg) => 0;
lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_RDONLY);
size = strlen("exhaustion");
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "exhaustion", size) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST

echo "--- Results ---"
tests/stats.py

0 comments on commit 210b487

Please sign in to comment.