Skip to content

Commit f3578e3

Browse files
committed
Removed clamping to block size in ctz linked-list
Initially, I was concerned that the number of pointers in the ctz linked-list could exceed the storage in a block. Long story short this isn't really possible outside of extremely small block sizes. Since clamping impacts the layout of files on disk, removing the block size removed quite a bit of logic and corner cases. Replaced with an assert on block size during initialization. --- Long story long, the minimum block size needed to store all ctz pointers in a filesystem can be found with this formula: B = (w/8)*log2(2^w / (B - 2*(w/8))) where: B = block size in bytes w = pointer width in bits It's not a very pretty formula, but does give us some useful info if we apply some math: min block size: 32 bit ctz linked-list = 104 bytes 64 bit ctz linked-list = 448 bytes For littlefs, 128 bytes is a perfectly reasonable minimum block size.
1 parent 83d4c61 commit f3578e3

File tree

1 file changed

+7
-6
lines changed

1 file changed

+7
-6
lines changed

lfs.c

+7-6
Original file line numberDiff line numberDiff line change
@@ -1005,12 +1005,11 @@ int lfs_dir_rewind(lfs_t *lfs, lfs_dir_t *dir) {
10051005
/// File index list operations ///
10061006
static int lfs_index(lfs_t *lfs, lfs_off_t *off) {
10071007
lfs_off_t i = 0;
1008-
lfs_size_t words = lfs->cfg->block_size / 4;
10091008

10101009
while (*off >= lfs->cfg->block_size) {
10111010
i += 1;
10121011
*off -= lfs->cfg->block_size;
1013-
*off += 4*lfs_min(lfs_ctz(i)+1, words-1);
1012+
*off += 4*(lfs_ctz(i) + 1);
10141013
}
10151014

10161015
return i;
@@ -1028,12 +1027,11 @@ static int lfs_index_find(lfs_t *lfs,
10281027

10291028
lfs_off_t current = lfs_index(lfs, &(lfs_off_t){size-1});
10301029
lfs_off_t target = lfs_index(lfs, &pos);
1031-
lfs_size_t words = lfs->cfg->block_size / 4;
10321030

10331031
while (current > target) {
10341032
lfs_size_t skip = lfs_min(
10351033
lfs_npw2(current-target+1) - 1,
1036-
lfs_min(lfs_ctz(current)+1, words-1) - 1);
1034+
lfs_ctz(current));
10371035

10381036
int err = lfs_cache_read(lfs, rcache, pcache, head, 4*skip, &head, 4);
10391037
if (err) {
@@ -1102,8 +1100,7 @@ static int lfs_index_extend(lfs_t *lfs,
11021100

11031101
// append block
11041102
index += 1;
1105-
lfs_size_t words = lfs->cfg->block_size / 4;
1106-
lfs_size_t skips = lfs_min(lfs_ctz(index)+1, words-1);
1103+
lfs_size_t skips = lfs_ctz(index) + 1;
11071104

11081105
for (lfs_off_t i = 0; i < skips; i++) {
11091106
int err = lfs_cache_prog(lfs, pcache, rcache,
@@ -1880,6 +1877,10 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
18801877
}
18811878
}
18821879

1880+
// check that the block size is large enough to fit ctz pointers
1881+
assert(4*lfs_npw2(0xffffffff / (lfs->cfg->block_size-2*4))
1882+
<= lfs->cfg->block_size);
1883+
18831884
// setup default state
18841885
lfs->root[0] = 0xffffffff;
18851886
lfs->root[1] = 0xffffffff;

0 commit comments

Comments
 (0)