Skip to content

Commit 210b487

Browse files
committed
Added file list for tracking in flight allocations
Needed primarily for tracking block allocations, unfortunately this prevents the freedom for the user to bitwise copy files.
1 parent b55719b commit 210b487

File tree

3 files changed

+132
-6
lines changed

3 files changed

+132
-6
lines changed

lfs.c

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,13 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) {
232232
}
233233

234234
// scan again or die trying
235-
return lfs_alloc_scan(lfs, block);
235+
err = lfs_alloc_scan(lfs, block);
236+
if (err) {
237+
LFS_WARN("No more free space%s", "");
238+
return err;
239+
}
240+
241+
return 0;
236242
}
237243

238244

@@ -1010,11 +1016,25 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
10101016
file->size = 0;
10111017
}
10121018

1019+
// add to list of files
1020+
file->next = lfs->files;
1021+
lfs->files = file;
1022+
10131023
return 0;
10141024
}
10151025

10161026
int lfs_file_close(lfs_t *lfs, lfs_file_t *file) {
1017-
return lfs_file_sync(lfs, file);
1027+
int err = lfs_file_sync(lfs, file);
1028+
1029+
// remove from list of files
1030+
for (lfs_file_t **p = &lfs->files; *p; p = &(*p)->next) {
1031+
if (*p == file) {
1032+
*p = file->next;
1033+
break;
1034+
}
1035+
}
1036+
1037+
return err;
10181038
}
10191039

10201040
static int lfs_file_flush(lfs_t *lfs, lfs_file_t *file) {
@@ -1453,6 +1473,9 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
14531473
}
14541474
}
14551475

1476+
// setup files as an empty list
1477+
lfs->files = NULL;
1478+
14561479
return 0;
14571480
}
14581481

@@ -1612,8 +1635,7 @@ int lfs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data) {
16121635
dir.off += entry.d.len;
16131636
if ((0xf & entry.d.type) == LFS_TYPE_REG) {
16141637
int err = lfs_index_traverse(lfs,
1615-
entry.d.u.file.head, entry.d.u.file.size,
1616-
cb, data);
1638+
entry.d.u.file.head, entry.d.u.file.size, cb, data);
16171639
if (err) {
16181640
return err;
16191641
}
@@ -1623,10 +1645,29 @@ int lfs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data) {
16231645
cwd[0] = dir.d.tail[0];
16241646
cwd[1] = dir.d.tail[1];
16251647

1626-
if (!cwd[0]) {
1627-
return 0;
1648+
if (lfs_pairisnull(cwd)) {
1649+
break;
16281650
}
16291651
}
1652+
1653+
// iterate over any open files
1654+
for (lfs_file_t *f = lfs->files; f; f = f->next) {
1655+
if (f->flags & LFS_O_DIRTY) {
1656+
int err = lfs_index_traverse(lfs, f->head, f->size, cb, data);
1657+
if (err) {
1658+
return err;
1659+
}
1660+
}
1661+
1662+
if (f->wblock) {
1663+
int err = lfs_index_traverse(lfs, f->wblock, f->pos, cb, data);
1664+
if (err) {
1665+
return err;
1666+
}
1667+
}
1668+
}
1669+
1670+
return 0;
16301671
}
16311672

16321673
static int lfs_parent(lfs_t *lfs, const lfs_block_t dir[2]) {

lfs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ typedef struct lfs_entry {
145145
} lfs_entry_t;
146146

147147
typedef struct lfs_file {
148+
struct lfs_file *next;
148149
lfs_block_t pair[2];
149150
lfs_off_t off;
150151
lfs_block_t head;
@@ -194,6 +195,7 @@ typedef struct lfs {
194195
lfs_size_t words; // number of 32-bit words that can fit in a block
195196

196197
lfs_block_t root[2];
198+
lfs_file_t *files;
197199

198200
struct {
199201
lfs_block_t block;

tests/test_alloc.sh

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,5 +110,88 @@ lfs_alloc_singleproc multiprocreuse
110110
lfs_verify multiprocreuse
111111
lfs_verify singleprocreuse
112112

113+
echo "--- Cleanup ---"
114+
lfs_remove multiprocreuse
115+
lfs_remove singleprocreuse
116+
117+
echo "--- Exhaustion test ---"
118+
tests/test.py << TEST
119+
lfs_mount(&lfs, &cfg) => 0;
120+
lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
121+
size = strlen("exhaustion");
122+
memcpy(buffer, "exhaustion", size);
123+
lfs_file_write(&lfs, &file[0], buffer, size) => size;
124+
125+
size = strlen("blahblahblahblah");
126+
memcpy(buffer, "blahblahblahblah", size);
127+
lfs_ssize_t res;
128+
while (true) {
129+
res = lfs_file_write(&lfs, &file[0], buffer, size);
130+
if (res < 0) {
131+
break;
132+
}
133+
134+
res => size;
135+
}
136+
res => LFS_ERR_NOSPC;
137+
138+
lfs_file_close(&lfs, &file[0]) => 0;
139+
lfs_unmount(&lfs) => 0;
140+
TEST
141+
tests/test.py << TEST
142+
lfs_mount(&lfs, &cfg) => 0;
143+
lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_RDONLY);
144+
size = strlen("exhaustion");
145+
lfs_file_read(&lfs, &file[0], buffer, size) => size;
146+
memcmp(buffer, "exhaustion", size) => 0;
147+
lfs_file_close(&lfs, &file[0]) => 0;
148+
lfs_unmount(&lfs) => 0;
149+
TEST
150+
151+
echo "--- Exhaustion wraparound test ---"
152+
tests/test.py << TEST
153+
lfs_mount(&lfs, &cfg) => 0;
154+
lfs_remove(&lfs, "exhaustion") => 0;
155+
156+
lfs_file_open(&lfs, &file[0], "padding", LFS_O_WRONLY | LFS_O_CREAT);
157+
size = strlen("buffering");
158+
memcpy(buffer, "buffering", size);
159+
for (int i = 0; i < $SIZE; i++) {
160+
lfs_file_write(&lfs, &file[0], buffer, size) => size;
161+
}
162+
lfs_file_close(&lfs, &file[0]) => 0;
163+
lfs_remove(&lfs, "padding") => 0;
164+
165+
lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
166+
size = strlen("exhaustion");
167+
memcpy(buffer, "exhaustion", size);
168+
lfs_file_write(&lfs, &file[0], buffer, size) => size;
169+
170+
size = strlen("blahblahblahblah");
171+
memcpy(buffer, "blahblahblahblah", size);
172+
lfs_ssize_t res;
173+
while (true) {
174+
res = lfs_file_write(&lfs, &file[0], buffer, size);
175+
if (res < 0) {
176+
break;
177+
}
178+
179+
res => size;
180+
}
181+
res => LFS_ERR_NOSPC;
182+
183+
lfs_file_close(&lfs, &file[0]) => 0;
184+
lfs_unmount(&lfs) => 0;
185+
TEST
186+
tests/test.py << TEST
187+
lfs_mount(&lfs, &cfg) => 0;
188+
lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_RDONLY);
189+
size = strlen("exhaustion");
190+
lfs_file_read(&lfs, &file[0], buffer, size) => size;
191+
memcmp(buffer, "exhaustion", size) => 0;
192+
lfs_file_close(&lfs, &file[0]) => 0;
193+
lfs_unmount(&lfs) => 0;
194+
TEST
195+
113196
echo "--- Results ---"
114197
tests/stats.py

0 commit comments

Comments
 (0)