Adopted lfsr_data_from* pattern for internal data encoding

Taking advantage of the fact that these functions should never error,
changing the return type to lfsr_data_t allows all of the encoding
information to be passed around quite easily.

And, by giving each lfsr_data_from* function an LFSR_DATA_FROM* macro,
these functions can participate in our attr-list generating macros:

  LFSR_ATTR(-1, MTREE, 0, FROMBTREE(lfs, mtree, mtree_buf))

Though one thing to watch out for is the borrowed buffer that stores the
actual data. This might welcome use-after-free bugs since it's not super
clear the buffer remains borrowed. Will need to watch out for this.
This commit is contained in:
Christopher Haster
2023-09-14 13:17:27 -05:00
parent e4032de089
commit d0c5bf1210
2 changed files with 102 additions and 179 deletions
+98 -175
View File
@@ -1440,21 +1440,21 @@ typedef struct lfsr_ecksum {
// 1 leb128 + 1 crc32c => 9 bytes (worst case)
#define LFSR_ECKSUM_DSIZE (5+4)
static lfs_ssize_t lfsr_ecksum_todisk(lfs_t *lfs, const lfsr_ecksum_t *ecksum,
#define LFSR_DATA_FROMECKSUM(_lfs, _ecksum, _buffer) \
lfsr_data_fromecksum(_lfs, _ecksum, _buffer)
static lfsr_data_t lfsr_data_fromecksum(lfs_t *lfs, const lfsr_ecksum_t *ecksum,
uint8_t buffer[static LFSR_ECKSUM_DSIZE]) {
(void)lfs;
lfs_ssize_t d = 0;
lfs_ssize_t d_ = lfs_toleb128(ecksum->size, &buffer[d], 5);
if (d_ < 0) {
return d_;
}
LFS_ASSERT(d_ >= 0);
d += d_;
lfs_tole32_(ecksum->cksum, &buffer[d]);
d += 4;
return d;
return LFSR_DATA_BUF(buffer, d);
}
static int lfsr_data_readecksum(lfs_t *lfs, lfsr_data_t *data,
@@ -1625,7 +1625,26 @@ static inline void lfsr_grm_poprm(lfsr_grm_t *grm) {
grm->rms[1] = -1;
}
static int lfsr_grm_todisk(lfs_t *lfs, const lfsr_grm_t *grm,
static inline bool lfsr_grm_iszero(
const uint8_t gdelta[static LFSR_GRM_DSIZE]) {
return lfsr_gdelta_iszero(gdelta, LFSR_GRM_DSIZE);
}
static inline lfs_size_t lfsr_grm_size(
const uint8_t gdelta[static LFSR_GRM_DSIZE]) {
return lfsr_gdelta_size(gdelta, LFSR_GRM_DSIZE);
}
static inline int lfsr_grm_xor(lfs_t *lfs,
uint8_t gdelta[static LFSR_GRM_DSIZE],
lfsr_data_t xor) {
return lfsr_gdelta_xor(lfs, gdelta, LFSR_GRM_DSIZE, xor);
}
#define LFSR_DATA_FROMGRM(_lfs, _grm, _buffer) \
lfsr_data_fromgrm(_lfs, _grm, _buffer)
static lfsr_data_t lfsr_data_fromgrm(lfs_t *lfs, const lfsr_grm_t *grm,
uint8_t buffer[static LFSR_GRM_DSIZE]) {
(void)lfs;
// make sure to zero so we don't leak any info
@@ -1636,18 +1655,16 @@ static int lfsr_grm_todisk(lfs_t *lfs, const lfsr_grm_t *grm,
// encode no-rm as zero-size
uint8_t count = lfsr_grm_count(grm);
lfs_ssize_t d = 0;
buffer[d] = lfsr_grm_count(grm);
buffer[d] = count;
d += 1;
for (int i = 0; i < count; i++) {
lfs_ssize_t d_ = lfs_toleb128(grm->rms[i], &buffer[d], 5);
if (d_ < 0) {
return d_;
}
LFS_ASSERT(d_ >= 0);
d += d_;
}
return 0;
return LFSR_DATA_BUF(buffer, lfsr_grm_size(buffer));
}
// required by lfsr_grm_fromdisk
@@ -1682,20 +1699,6 @@ static int lfsr_data_readgrm(lfs_t *lfs, lfsr_data_t *data,
return 0;
}
static inline bool lfsr_grm_iszero(const uint8_t gdelta[LFSR_GRM_DSIZE]) {
return lfsr_gdelta_iszero(gdelta, LFSR_GRM_DSIZE);
}
static inline lfs_size_t lfsr_grm_size(const uint8_t gdelta[LFSR_GRM_DSIZE]) {
return lfsr_gdelta_size(gdelta, LFSR_GRM_DSIZE);
}
static inline int lfsr_grm_xor(lfs_t *lfs,
uint8_t gdelta[LFSR_GRM_DSIZE],
lfsr_data_t xor) {
return lfsr_gdelta_xor(lfs, gdelta, LFSR_GRM_DSIZE, xor);
}
/// Internal operations predeclared here ///
//#ifndef LFS_READONLY
@@ -2763,21 +2766,22 @@ static int lfsr_rbyd_appendcksum(lfs_t *lfs, lfsr_rbyd_t *rbyd) {
}
uint8_t ecksum_buf[LFSR_ECKSUM_DSIZE];
lfs_size_t ecksum_dsize = lfsr_ecksum_todisk(lfs, &ecksum, ecksum_buf);
lfsr_data_t ecksum_data = lfsr_data_fromecksum(lfs, &ecksum,
ecksum_buf);
lfs_ssize_t d = lfsr_bd_progtag(lfs, rbyd->block, rbyd->eoff,
LFSR_TAG_ECKSUM, 0, ecksum_dsize,
LFSR_TAG_ECKSUM, 0, lfsr_data_size(&ecksum_data),
&rbyd->cksum);
if (d < 0) {
return d;
}
rbyd->eoff += d;
err = lfsr_bd_prog(lfs, rbyd->block, rbyd->eoff,
ecksum_buf, ecksum_dsize, &rbyd->cksum);
err = lfsr_bd_progdata(lfs, rbyd->block, rbyd->eoff, ecksum_data,
&rbyd->cksum);
if (err) {
return err;
}
rbyd->eoff += ecksum_dsize;
rbyd->eoff += lfsr_data_size(&ecksum_data);
// at least space for a cksum?
} else if (rbyd->eoff + 2+1+5+4 <= lfs->cfg->block_size) {
@@ -3384,7 +3388,10 @@ static inline void lfsr_btree_unerase(lfsr_btree_t *btree) {
// 3 leb128 + 1 crc32c => 19 bytes (worst case)
#define LFSR_BTREE_DSIZE (5+5+5+4)
static lfs_ssize_t lfsr_btree_todisk(lfs_t *lfs, const lfsr_rbyd_t *btree,
#define LFSR_DATA_FROMBTREE(_lfs, _btree, _buffer) \
lfsr_data_frombtree(_lfs, _btree, _buffer)
static lfsr_data_t lfsr_data_frombtree(lfs_t *lfs, const lfsr_rbyd_t *btree,
uint8_t buffer[static LFSR_BTREE_DSIZE]) {
(void)lfs;
// upper layers must take care of encoding inlined btrees
@@ -3392,27 +3399,21 @@ static lfs_ssize_t lfsr_btree_todisk(lfs_t *lfs, const lfsr_rbyd_t *btree,
lfs_ssize_t d = 0;
lfs_ssize_t d_ = lfs_toleb128(btree->block, &buffer[d], 5);
if (d_ < 0) {
return d_;
}
LFS_ASSERT(d_ >= 0);
d += d_;
d_ = lfs_toleb128(btree->trunk, &buffer[d], 5);
if (d_ < 0) {
return d_;
}
LFS_ASSERT(d_ >= 0);
d += d_;
d_ = lfs_toleb128(btree->weight, &buffer[d], 5);
if (d_ < 0) {
return d_;
}
LFS_ASSERT(d_ >= 0);
d += d_;
lfs_tole32_(btree->cksum, &buffer[d]);
d += 4;
return d;
return LFSR_DATA_BUF(buffer, d);
}
static int lfsr_data_readbtreeinlined(lfs_t *lfs, lfsr_data_t *data,
@@ -3759,7 +3760,8 @@ static int lfsr_btree_commit(lfs_t *lfs, lfsr_btree_t *btree,
// we need some scratch space for tail-recursive attrs here
lfsr_attr_t scratch_attrs[4];
uint8_t scratch_buf[2*LFSR_BTREE_DSIZE];
uint8_t scratch_buf[LFSR_BTREE_DSIZE];
uint8_t scratch_buf_[LFSR_BTREE_DSIZE];
// tail-recursively commit to btree
while (true) {
@@ -4093,35 +4095,25 @@ static int lfsr_btree_commit(lfs_t *lfs, lfsr_btree_t *btree,
rbyd.weight = 0;
}
uint8_t *scratch1_buf = scratch_buf;
uint8_t *scratch2_buf = scratch_buf + LFSR_BTREE_DSIZE;
lfs_ssize_t scratch1_dsize = lfsr_btree_todisk(lfs, &rbyd_,
scratch1_buf);
if (scratch1_dsize < 0) {
return scratch1_dsize;
}
lfs_ssize_t scratch2_dsize = lfsr_btree_todisk(lfs, &sibling,
scratch2_buf);
if (scratch2_dsize < 0) {
return scratch2_dsize;
}
// prepare commit to parent, tail recursing upwards
bid -= rid - (rbyd.weight-1);
LFS_ASSERT(rbyd_.weight > 0);
LFS_ASSERT(sibling.weight > 0);
if (rbyd.weight == 0) {
scratch_attrs[0] = LFSR_ATTR(bid,
BTREE, +rbyd_.weight, BUF(scratch1_buf, scratch1_dsize));
BTREE, +rbyd_.weight, FROMBTREE(lfs, &rbyd_,
scratch_buf));
scratch_attrs[1] = LFSR_ATTR_NOOP;
} else {
scratch_attrs[0] = LFSR_ATTR(bid+rid,
BTREE, 0, BUF(scratch1_buf, scratch1_dsize));
BTREE, 0, FROMBTREE(lfs, &rbyd_,
scratch_buf));
scratch_attrs[1] = LFSR_ATTR(bid+rid,
GROW, -rbyd.weight + rbyd_.weight, NULL);
}
scratch_attrs[2] = LFSR_ATTR(bid+rid - rbyd.weight + rbyd_.weight + 1,
BTREE, +sibling.weight, BUF(scratch2_buf, scratch2_dsize));
BTREE, +sibling.weight, FROMBTREE(lfs, &sibling,
scratch_buf_));
if (lfsr_tag_suptype(split_tag) == LFSR_TAG_NAME) {
scratch_attrs[3] = LFSR_ATTR(
bid+rid - rbyd.weight + rbyd_.weight + sibling.weight,
@@ -4213,19 +4205,13 @@ static int lfsr_btree_commit(lfs_t *lfs, lfsr_btree_t *btree,
return 0;
}
lfs_ssize_t scratch_dsize = lfsr_btree_todisk(lfs, &rbyd_,
scratch_buf);
if (scratch_dsize < 0) {
return scratch_dsize;
}
// prepare commit to parent, tail recursing upwards
bid -= rid - (rbyd.weight-1);
LFS_ASSERT(rbyd_.weight > 0);
scratch_attrs[0] = LFSR_ATTR(bid+rid+sibling.weight,
RM, -sibling.weight, NULL);
scratch_attrs[1] = LFSR_ATTR(bid+rid,
BTREE, 0, BUF(scratch_buf, scratch_dsize));
BTREE, 0, FROMBTREE(lfs, &rbyd_, scratch_buf));
scratch_attrs[2] = LFSR_ATTR(bid+rid,
GROW, -rbyd.weight + rbyd_.weight, NULL);
attrs = scratch_attrs;
@@ -4249,12 +4235,6 @@ static int lfsr_btree_commit(lfs_t *lfs, lfsr_btree_t *btree,
return 0;
}
scratch_dsize = lfsr_btree_todisk(lfs, &rbyd_,
scratch_buf);
if (scratch_dsize < 0) {
return scratch_dsize;
}
// prepare commit to parent, tail recursing upwards
//
// note that since we defer merges to compaction time, we can
@@ -4267,7 +4247,7 @@ static int lfsr_btree_commit(lfs_t *lfs, lfsr_btree_t *btree,
attr_count = 1;
} else {
scratch_attrs[0] = LFSR_ATTR(bid+rid,
BTREE, 0, BUF(scratch_buf, scratch_dsize));
BTREE, 0, FROMBTREE(lfs, &rbyd_, scratch_buf));
scratch_attrs[1] = LFSR_ATTR(bid+rid,
GROW, -rbyd.weight + rbyd_.weight, NULL);
attrs = scratch_attrs;
@@ -4559,20 +4539,21 @@ static inline void lfsr_mdir_unerase(lfsr_mdir_t *mdir) {
// 2 leb128 => 10 bytes (worst case)
#define LFSR_MDIR_DSIZE (5+5)
static lfs_ssize_t lfsr_mblocks_todisk(lfs_t *lfs,
#define LFSR_DATA_FROMMBLOCKS(_lfs, _blocks, _buffer) \
lfsr_data_frommblocks(_lfs, _blocks, _buffer)
static lfsr_data_t lfsr_data_frommblocks(lfs_t *lfs,
const lfs_block_t blocks[static 2],
uint8_t buffer[static LFSR_MDIR_DSIZE]) {
(void)lfs;
lfs_ssize_t d = 0;
for (int i = 0; i < 2; i++) {
lfs_ssize_t d_ = lfs_toleb128(blocks[i], &buffer[d], 5);
if (d_ < 0) {
return d_;
}
LFS_ASSERT(d_ >= 0);
d += d_;
}
return d;
return LFSR_DATA_BUF(buffer, d);
}
static int lfsr_data_readmblocks(lfs_t *lfs, lfsr_data_t *data,
@@ -5173,16 +5154,12 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
for (lfs_size_t i = 0; i < attr_count; i++) {
if (attrs[i].tag == LFSR_TAG_GRM) {
// encode to disk
int err = lfsr_grm_todisk(lfs,
(lfsr_grm_t*)attrs[i].data.u.b.buffer,
lfs->dgrm);
if (err) {
return err;
}
lfsr_grm_t *grm = (lfsr_grm_t*)attrs[i].data.u.b.buffer;
lfsr_data_fromgrm(lfs, grm, lfs->dgrm);
// xor with our current gstate to find our initial gdelta
err = lfsr_grm_xor(lfs, lfs->dgrm, LFSR_DATA(
lfs->pgrm, LFSR_GRM_DSIZE));
int err = lfsr_grm_xor(lfs, lfs->dgrm,
LFSR_DATA(lfs->pgrm, LFSR_GRM_DSIZE));
if (err) {
return err;
}
@@ -5356,25 +5333,16 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
}
uint8_t mdir_buf[LFSR_MDIR_DSIZE];
lfs_ssize_t mdir_dsize = lfsr_mblocks_todisk(lfs,
mdir_.u.m.blocks, mdir_buf);
if (mdir_dsize < 0) {
return mdir_dsize;
}
uint8_t msibling_buf[LFSR_MDIR_DSIZE];
lfs_ssize_t msibling_dsize = lfsr_mblocks_todisk(lfs,
msibling_.u.m.blocks, msibling_buf);
if (msibling_dsize < 0) {
return msibling_dsize;
}
err = lfsr_btree_commit(lfs, &mtree_, LFSR_ATTRS(
LFSR_ATTR(mdir_.mid | lfsr_mridmask(lfs),
MDIR, 0, BUF(mdir_buf, mdir_dsize)),
MDIR, 0, FROMMBLOCKS(lfs, mdir_.u.m.blocks,
mdir_buf)),
LFSR_ATTR((mdir_.mid | lfsr_mridmask(lfs))+1,
BRANCH, +lfsr_mweight(lfs), DATA(split_data)),
LFSR_ATTR(msibling_.mid | lfsr_mridmask(lfs),
MDIR, 0, BUF(msibling_buf, msibling_dsize))));
MDIR, 0, FROMMBLOCKS(lfs, msibling_.u.m.blocks,
msibling_buf))));
if (err) {
return err;
}
@@ -5419,15 +5387,10 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
// update our mtree
uint8_t mdir_buf[LFSR_MDIR_DSIZE];
lfs_ssize_t mdir_dsize = lfsr_mblocks_todisk(lfs,
mdir_.u.m.blocks, mdir_buf);
if (mdir_dsize < 0) {
return mdir_dsize;
}
err = lfsr_btree_commit(lfs, &mtree_, LFSR_ATTRS(
LFSR_ATTR(mdir_.mid | lfsr_mridmask(lfs),
MDIR, 0, BUF(mdir_buf, mdir_dsize))));
MDIR, 0, FROMMBLOCKS(lfs, mdir_.u.m.blocks,
mdir_buf))));
if (err) {
return err;
}
@@ -5448,13 +5411,8 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
//
lfsr_grm_t *grm = (lfsr_grm_t*)attrs[i].data.u.b.buffer;
uint8_t grm_buf[LFSR_GRM_DSIZE];
err = lfsr_grm_todisk(lfs, grm, grm_buf);
if (err) {
return err;
}
err = lfsr_grm_xor(lfs, lfs->dgrm,
LFSR_DATA(grm_buf, LFSR_GRM_DSIZE));
lfsr_data_fromgrm(lfs, grm, grm_buf));
if (err) {
return err;
}
@@ -5478,13 +5436,8 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
}
// xor our fix into our gdelta
err = lfsr_grm_todisk(lfs, grm, grm_buf);
if (err) {
return err;
}
err = lfsr_grm_xor(lfs, lfs->dgrm,
LFSR_DATA(grm_buf, LFSR_GRM_DSIZE));
lfsr_data_fromgrm(lfs, grm, grm_buf));
if (err) {
return err;
}
@@ -5499,26 +5452,22 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
// commit mtree
lfsr_tag_t mtree_tag;
uint8_t mtree_buf[LFSR_MTREE_DSIZE];
lfs_ssize_t mtree_dsize;
lfsr_data_t mtree_data;
if (lfsr_btree_isnull(&mtree_)) {
mtree_tag = LFSR_TAG_RM(WIDE(STRUCT));
mtree_dsize = 0;
mtree_data = LFSR_DATA_BUF(mtree_buf, 0);
} else if (lfsr_btree_isinlined(&mtree_)) {
LFS_ASSERT(mtree_.u.i.tag == LFSR_TAG_MDIR);
mtree_tag = LFSR_TAG_WIDE(MDIR);
memcpy(mtree_buf, mtree_.u.i.buf, mtree_.u.i.size);
mtree_dsize = mtree_.u.i.size;
mtree_data = LFSR_DATA_BUF(mtree_buf, mtree_.u.i.size);
} else {
mtree_tag = LFSR_TAG_WIDE(MTREE);
mtree_dsize = lfsr_btree_todisk(lfs, &mtree_.u.r.rbyd, mtree_buf);
if (mtree_dsize < 0) {
return mtree_dsize;
}
mtree_data = lfsr_data_frombtree(lfs, &mtree_.u.r.rbyd, mtree_buf);
}
err = lfsr_mdir_commit_(lfs, &mroot_, -1, 0, NULL, LFSR_ATTRS(
LFSR_ATTR(-1,
TAG(mtree_tag), 0, BUF(mtree_buf, mtree_dsize))));
LFSR_ATTR(-1, TAG(mtree_tag), 0, DATA(mtree_data))));
if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE);
LFS_ASSERT(err != LFS_ERR_NOENT);
@@ -5545,18 +5494,14 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
mrootchild.u.m.blocks[0], mrootchild.u.m.blocks[1],
mrootchild_.u.m.blocks[0], mrootchild_.u.m.blocks[1]);
mrootchild = mrootparent_;
// commit mrootchild
uint8_t mrootchild_buf[LFSR_MDIR_DSIZE];
lfs_ssize_t mrootchild_dsize = lfsr_mblocks_todisk(lfs,
mrootchild_.u.m.blocks, mrootchild_buf);
if (mrootchild_dsize < 0) {
return mrootchild_dsize;
}
mrootchild = mrootparent_;
err = lfsr_mdir_commit_(lfs, &mrootparent_, -1, -1, NULL, LFSR_ATTRS(
LFSR_ATTR(-1,
MROOT, 0, BUF(mrootchild_buf, mrootchild_dsize))));
MROOT, 0, FROMMBLOCKS(lfs, mrootchild_.u.m.blocks,
mrootchild_buf))));
if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE);
LFS_ASSERT(err != LFS_ERR_NOENT);
@@ -5577,14 +5522,6 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
mrootchild.u.m.blocks[0], mrootchild.u.m.blocks[1],
mrootchild_.u.m.blocks[0], mrootchild_.u.m.blocks[1]);
// commit mrootchild
uint8_t mrootchild_buf[LFSR_MDIR_DSIZE];
lfs_ssize_t mrootchild_dsize = lfsr_mblocks_todisk(lfs,
mrootchild_.u.m.blocks, mrootchild_buf);
if (mrootchild_dsize < 0) {
return mrootchild_dsize;
}
// compact into mrootparent_, this should stay our mroot anchor
lfsr_mdir_t mrootparent_;
err = lfsr_mdir_swap(lfs, &mrootparent_, &mrootchild, -1);
@@ -5628,9 +5565,11 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
}
// and commit our new mroot
uint8_t mrootchild_buf[LFSR_MDIR_DSIZE];
err = lfsr_mdir_commit__(lfs, &mrootparent_, -1, -1, LFSR_ATTRS(
LFSR_ATTR(-1,
WIDE(MROOT), 0, BUF(mrootchild_buf, mrootchild_dsize))));
WIDE(MROOT), 0, FROMMBLOCKS(lfs, mrootchild_.u.m.blocks,
mrootchild_buf))));
if (err) {
LFS_ASSERT(err != LFS_ERR_NOENT);
return err;
@@ -5648,11 +5587,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
lfs->grm = *(lfsr_grm_t*)attrs[i].data.u.b.buffer;
// keep track of the exact encoding on-disk
err = lfsr_grm_todisk(lfs, &lfs->grm, lfs->pgrm);
if (err) {
LFS_ASSERT(!err);
return err;
}
lfsr_data_fromgrm(lfs, &lfs->grm, lfs->pgrm);
}
}
@@ -6270,7 +6205,10 @@ static int lfsr_mtree_traversal_next(lfs_t *lfs,
//
#define LFSR_SUPERCONFIG_DSIZE (1+1+1+1+5+5+1+5+5+5+5)
static lfs_ssize_t lfsr_superconfig_todisk(lfs_t *lfs,
#define LFSR_DATA_FROMSUPERCONFIG(_lfs, _buffer) \
lfsr_data_fromsuperconfig(_lfs, _buffer)
static lfsr_data_t lfsr_data_fromsuperconfig(lfs_t *lfs,
uint8_t buffer[static LFSR_SUPERCONFIG_DSIZE]) {
// TODO most of these should also be in the lfs_config/lfs_t structs
@@ -6289,16 +6227,12 @@ static lfs_ssize_t lfsr_superconfig_todisk(lfs_t *lfs,
// on-disk block size
lfs_ssize_t d = 4;
lfs_ssize_t d_ = lfs_toleb128(lfs->cfg->block_size, &buffer[d], 5);
if (d_ < 0) {
return d_;
}
LFS_ASSERT(d_ >= 0);
d += d_;
// on-disk block count
d_ = lfs_toleb128(lfs->cfg->block_count, &buffer[d], 5);
if (d_ < 0) {
return d_;
}
LFS_ASSERT(d_ >= 0);
d += d_;
// on-disk utag limit
@@ -6307,33 +6241,25 @@ static lfs_ssize_t lfsr_superconfig_todisk(lfs_t *lfs,
// on-disk mtree limit
d_ = lfs_toleb128(0x7fffffff, &buffer[d], 5);
if (d_ < 0) {
return d_;
}
LFS_ASSERT(d_ >= 0);
d += d_;
// on-disk attr limit
d_ = lfs_toleb128(0x7fffffff, &buffer[d], 5);
if (d_ < 0) {
return d_;
}
LFS_ASSERT(d_ >= 0);
d += d_;
// on-disk name limit
d_ = lfs_toleb128(0xff, &buffer[d], 5);
if (d_ < 0) {
return d_;
}
LFS_ASSERT(d_ >= 0);
d += d_;
// on-disk file limit
d_ = lfs_toleb128(0x7fffffff, &buffer[d], 5);
if (d_ < 0) {
return d_;
}
LFS_ASSERT(d_ >= 0);
d += d_;
return d;
return LFSR_DATA_BUF(buffer, d);
}
@@ -6638,12 +6564,10 @@ static int lfsr_mountinited(lfs_t *lfs) {
}
static int lfsr_formatinited(lfs_t *lfs) {
// create superconfig
uint8_t superconfig_buf[LFSR_SUPERCONFIG_DSIZE];
lfs_ssize_t superconfig_dsize = lfsr_superconfig_todisk(lfs,
lfsr_data_t superconfig_data = lfsr_data_fromsuperconfig(lfs,
superconfig_buf);
if (superconfig_dsize < 0) {
return superconfig_dsize;
}
for (int i = 0; i < 2; i++) {
// write superblock to both rbyds in the root mroot to hopefully
@@ -6669,8 +6593,7 @@ static int lfsr_formatinited(lfs_t *lfs) {
// - the root's bookmark tag, which reserves did = 0 for the root
err = lfsr_rbyd_commit(lfs, &rbyd, LFSR_ATTRS(
LFSR_ATTR(-1, SUPERMAGIC, 0, BUF("littlefs", 8)),
LFSR_ATTR(-1,
SUPERCONFIG, 0, BUF(superconfig_buf, superconfig_dsize)),
LFSR_ATTR(-1, SUPERCONFIG, 0, DATA(superconfig_data)),
LFSR_ATTR(0, BOOKMARK, +1, NAME(0, NULL, 0))));
if (err) {
return err;
+4 -4
View File
@@ -4243,11 +4243,11 @@ code = '''
lfsr_mount(&lfs, CFG) => 0;
lfs_alloc_ack(&lfs);
uint8_t buffer[LFSR_MDIR_DSIZE];
lfs_ssize_t d = lfsr_mblocks_todisk(&lfs, LFSR_MBLOCKS_MROOTANCHOR, buffer);
assert(d >= 0);
uint8_t buf[LFSR_MDIR_DSIZE];
lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_ATTRS(
LFSR_ATTR(-1, MROOT, 0, BUF(buffer, d)))) => 0;
LFSR_ATTR(-1,
MROOT, 0, FROMMBLOCKS(&lfs, LFSR_MBLOCKS_MROOTANCHOR,
buf)))) => 0;
// technically, cycle detection only needs to work when we're validating
lfsr_mtree_traversal_t traversal = LFSR_MTREE_TRAVERSAL(