Restricted lfsr_ftree_t to ftree related things

Note, I think if we ever add file snapshots for idempotent errors again,
I don't think adding mdir/next back into the ftree is the best way to
structure this.

Instead, adding a separate linked-list for tracking bshrubs would work
without adding redundant mdir copies to the ftree struct.

Fortunately, in our current version, we don't need to track on-stack
ftrees. Actually, we don't make on-stack ftree copies at all...
This commit is contained in:
Christopher Haster
2024-01-07 19:15:29 -06:00
parent 07e9bbf5b7
commit 34d522a71e
2 changed files with 168 additions and 149 deletions
+166 -147
View File
@@ -5055,10 +5055,14 @@ static int lfsr_mtree_seek(lfs_t *lfs, lfsr_mdir_t *mdir, lfs_off_t off) {
// needed in lfsr_mdir_commit/estimate/compact/etc // needed in lfsr_mdir_commit/estimate/compact/etc
static inline bool lfsr_ftree_isnull(const lfsr_ftree_t *ftree); static inline bool lfsr_ftree_isnull(const lfsr_ftree_t *ftree);
static inline bool lfsr_ftree_isbsprout(const lfsr_ftree_t *ftree); static inline bool lfsr_ftree_isbsprout(
static inline bool lfsr_ftree_isbleaf(const lfsr_ftree_t *ftree); const lfsr_mdir_t *mdir, const lfsr_ftree_t *ftree);
static inline bool lfsr_ftree_isbshrub(const lfsr_ftree_t *ftree); static inline bool lfsr_ftree_isbleaf(
static inline bool lfsr_ftree_isbtree(const lfsr_ftree_t *ftree); const lfsr_mdir_t *mdir, const lfsr_ftree_t *ftree);
static inline bool lfsr_ftree_isbshrub(
const lfsr_mdir_t *mdir, const lfsr_ftree_t *ftree);
static inline bool lfsr_ftree_isbtree(
const lfsr_mdir_t *mdir, const lfsr_ftree_t *ftree);
static inline bool lfsr_ftree_isbshruborbtree(const lfsr_ftree_t *ftree); static inline bool lfsr_ftree_isbshruborbtree(const lfsr_ftree_t *ftree);
static int lfsr_bshrub_commit__(lfs_t *lfs, lfsr_rbyd_t *rbyd_, static int lfsr_bshrub_commit__(lfs_t *lfs, lfsr_rbyd_t *rbyd_,
const lfsr_bshrub_t *bshrub, const lfsr_bshrub_t *bshrub,
@@ -5474,26 +5478,26 @@ static lfs_ssize_t lfsr_mdir_estimate__(lfs_t *lfs, const lfsr_mdir_t *mdir,
LFS_TYPE_REG-LFS_TYPE_REG]; LFS_TYPE_REG-LFS_TYPE_REG];
opened; opened;
opened = opened->next) { opened = opened->next) {
lfsr_ftree_t *ftree = (lfsr_ftree_t*)opened; lfsr_file_t *file = (lfsr_file_t*)opened;
// belongs to our mdir + rid? // belongs to our mdir + rid?
if (lfsr_mdir_cmp(&ftree->mdir, mdir) != 0 if (lfsr_mdir_cmp(&file->mdir, mdir) != 0
|| lfsr_mdir_rid(lfs, &ftree->mdir) != rid) { || lfsr_mdir_rid(lfs, &file->mdir) != rid) {
continue; continue;
} }
// inlined sprout? // inlined sprout?
if (lfsr_ftree_isbsprout(ftree)) { if (lfsr_ftree_isbsprout(&file->mdir, &file->ftree)) {
lfs_ssize_t dsize__ = lfsr_bsprout_estimate__(lfs, lfs_ssize_t dsize__ = lfsr_bsprout_estimate__(lfs,
&ftree->u.bsprout); &file->ftree.u.bsprout);
if (dsize__ < 0) { if (dsize__ < 0) {
return dsize__; return dsize__;
} }
dsize_ += dsize__; dsize_ += dsize__;
// inlined shrub? // inlined shrub?
} else if (lfsr_ftree_isbshrub(ftree)) { } else if (lfsr_ftree_isbshrub(&file->mdir, &file->ftree)) {
lfs_ssize_t dsize__ = lfsr_bshrub_estimate__(lfs, lfs_ssize_t dsize__ = lfsr_bshrub_estimate__(lfs,
&ftree->u.bshrub); &file->ftree.u.bshrub);
if (dsize__ < 0) { if (dsize__ < 0) {
return dsize__; return dsize__;
} }
@@ -5618,28 +5622,28 @@ static int lfsr_mdir_compact__(lfs_t *lfs, lfsr_mdir_t *mdir_,
LFS_TYPE_REG-LFS_TYPE_REG]; LFS_TYPE_REG-LFS_TYPE_REG];
opened; opened;
opened = opened->next) { opened = opened->next) {
lfsr_ftree_t *ftree = (lfsr_ftree_t*)opened; lfsr_file_t *file = (lfsr_file_t*)opened;
// belongs to our mdir? // belongs to our mdir?
if (lfsr_mdir_cmp(&ftree->mdir, mdir) != 0 if (lfsr_mdir_cmp(&file->mdir, mdir) != 0
|| lfsr_mdir_rid(lfs, &ftree->mdir) < start_rid || lfsr_mdir_rid(lfs, &file->mdir) < start_rid
|| (lfsr_rid_t)lfsr_mdir_rid(lfs, &ftree->mdir) || (lfsr_rid_t)lfsr_mdir_rid(lfs, &file->mdir)
>= (lfsr_rid_t)end_rid) { >= (lfsr_rid_t)end_rid) {
continue; continue;
} }
// inlined sprout? // inlined sprout?
if (lfsr_ftree_isbsprout(ftree)) { if (lfsr_ftree_isbsprout(&file->mdir, &file->ftree)) {
err = lfsr_bsprout_compact__(lfs, &mdir_->rbyd, err = lfsr_bsprout_compact__(lfs, &mdir_->rbyd,
&ftree->u.bsprout, true); &file->ftree.u.bsprout, true);
if (err) { if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE); LFS_ASSERT(err != LFS_ERR_RANGE);
return err; return err;
} }
// inlined shrub? // inlined shrub?
} else if (lfsr_ftree_isbshrub(ftree)) { } else if (lfsr_ftree_isbshrub(&file->mdir, &file->ftree)) {
err = lfsr_bshrub_compact__(lfs, &mdir_->rbyd, err = lfsr_bshrub_compact__(lfs, &mdir_->rbyd,
&ftree->u.bshrub, true, &file->ftree.u.bshrub, true,
NULL, NULL); NULL, NULL);
if (err) { if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE); LFS_ASSERT(err != LFS_ERR_RANGE);
@@ -5896,11 +5900,13 @@ static int lfsr_mroot_commit(lfs_t *lfs,
// update any bsprouts/bshrubs, note this must happen // update any bsprouts/bshrubs, note this must happen
// before we update the mdir // before we update the mdir
if (type == LFS_TYPE_REG) { if (type == LFS_TYPE_REG) {
lfsr_ftree_t *ftree = (lfsr_ftree_t*)opened; lfsr_file_t *file = (lfsr_file_t*)opened;
if (lfsr_ftree_isbsprout(ftree)) { if (lfsr_ftree_isbsprout(&file->mdir, &file->ftree)) {
ftree->u.bsprout.data = ftree->u.bsprout.data_; file->ftree.u.bsprout.data
} else if (lfsr_ftree_isbshrub(ftree)) { = file->ftree.u.bsprout.data_;
ftree->u.bshrub.rbyd = ftree->u.bshrub.rbyd_; } else if (lfsr_ftree_isbshrub(&file->mdir, &file->ftree)) {
file->ftree.u.bshrub.rbyd
= file->ftree.u.bshrub.rbyd_;
} }
} }
@@ -6111,11 +6117,11 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
// stage any bsprouts/bshrubs // stage any bsprouts/bshrubs
if (type == LFS_TYPE_REG) { if (type == LFS_TYPE_REG) {
lfsr_ftree_t *ftree = (lfsr_ftree_t*)opened; lfsr_file_t *file = (lfsr_file_t*)opened;
if (lfsr_ftree_isbsprout(ftree)) { if (lfsr_ftree_isbsprout(&file->mdir, &file->ftree)) {
ftree->u.bsprout.data_ = ftree->u.bsprout.data; file->ftree.u.bsprout.data_ = file->ftree.u.bsprout.data;
} else if (lfsr_ftree_isbshrub(ftree)) { } else if (lfsr_ftree_isbshrub(&file->mdir, &file->ftree)) {
ftree->u.bshrub.rbyd_ = ftree->u.bshrub.rbyd; file->ftree.u.bshrub.rbyd_ = file->ftree.u.bshrub.rbyd;
} }
} }
} }
@@ -6389,11 +6395,11 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
// update any bsprouts/bshrubs, note this must happen // update any bsprouts/bshrubs, note this must happen
// before we update the mdir // before we update the mdir
if (type == LFS_TYPE_REG) { if (type == LFS_TYPE_REG) {
lfsr_ftree_t *ftree = (lfsr_ftree_t*)opened; lfsr_file_t *file = (lfsr_file_t*)opened;
if (lfsr_ftree_isbsprout(ftree)) { if (lfsr_ftree_isbsprout(&file->mdir, &file->ftree)) {
ftree->u.bsprout.data = ftree->u.bsprout.data_; file->ftree.u.bsprout.data = file->ftree.u.bsprout.data_;
} else if (lfsr_ftree_isbshrub(ftree)) { } else if (lfsr_ftree_isbshrub(&file->mdir, &file->ftree)) {
ftree->u.bshrub.rbyd = ftree->u.bshrub.rbyd_; file->ftree.u.bshrub.rbyd = file->ftree.u.bshrub.rbyd_;
} }
} }
@@ -6823,10 +6829,10 @@ static lfs_ssize_t lfsr_bsprout_estimate__(lfs_t *lfs,
LFS_TYPE_REG-LFS_TYPE_REG]; LFS_TYPE_REG-LFS_TYPE_REG];
opened; opened;
opened = opened->next) { opened = opened->next) {
lfsr_ftree_t *ftree = (lfsr_ftree_t*)opened; lfsr_file_t *file = (lfsr_file_t*)opened;
if (lfsr_ftree_isbsprout(ftree) if (lfsr_ftree_isbsprout(&file->mdir, &file->ftree)
&& lfsr_bsprout_cmp(&ftree->u.bsprout, bsprout) == 0) { && lfsr_bsprout_cmp(&file->ftree.u.bsprout, bsprout) == 0) {
last = &ftree->u.bsprout; last = &file->ftree.u.bsprout;
} }
} }
if (last && bsprout != last) { if (last && bsprout != last) {
@@ -6857,12 +6863,12 @@ static int lfsr_bsprout_compact__(lfs_t *lfs, lfsr_rbyd_t *rbyd_,
LFS_TYPE_REG-LFS_TYPE_REG]; LFS_TYPE_REG-LFS_TYPE_REG];
opened; opened;
opened = opened->next) { opened = opened->next) {
lfsr_ftree_t *ftree = (lfsr_ftree_t*)opened; lfsr_file_t *file = (lfsr_file_t*)opened;
if (lfsr_ftree_isbsprout(ftree) if (lfsr_ftree_isbsprout(&file->mdir, &file->ftree)
&& lfsr_bsprout_cmp(&ftree->u.bsprout, bsprout) == 0) { && lfsr_bsprout_cmp(&file->ftree.u.bsprout, bsprout) == 0) {
// this is a bit tricky since we don't know the tag size, // this is a bit tricky since we don't know the tag size,
// but we have just enough info // but we have just enough info
ftree->u.bsprout.data_ = LFSR_DATA_DISK( file->ftree.u.bsprout.data_ = LFSR_DATA_DISK(
rbyd_->blocks[0], rbyd_->blocks[0],
rbyd_->eoff - lfsr_bsprout_size(bsprout), rbyd_->eoff - lfsr_bsprout_size(bsprout),
lfsr_bsprout_size(bsprout)); lfsr_bsprout_size(bsprout));
@@ -6943,10 +6949,10 @@ static lfs_ssize_t lfsr_bshrub_estimate__(lfs_t *lfs,
LFS_TYPE_REG-LFS_TYPE_REG]; LFS_TYPE_REG-LFS_TYPE_REG];
opened; opened;
opened = opened->next) { opened = opened->next) {
lfsr_ftree_t *ftree = (lfsr_ftree_t*)opened; lfsr_file_t *file = (lfsr_file_t*)opened;
if (lfsr_ftree_isbshrub(ftree) if (lfsr_ftree_isbshrub(&file->mdir, &file->ftree)
&& lfsr_bshrub_cmp(&ftree->u.bshrub, bshrub) == 0) { && lfsr_bshrub_cmp(&file->ftree.u.bshrub, bshrub) == 0) {
last = &ftree->u.bshrub; last = &file->ftree.u.bshrub;
} }
} }
if (last && bshrub != last) { if (last && bshrub != last) {
@@ -6984,10 +6990,10 @@ static int lfsr_bshrub_compact__(lfs_t *lfs, lfsr_rbyd_t *rbyd_,
LFS_TYPE_REG-LFS_TYPE_REG]; LFS_TYPE_REG-LFS_TYPE_REG];
opened; opened;
opened = opened->next) { opened = opened->next) {
lfsr_ftree_t *ftree = (lfsr_ftree_t*)opened; lfsr_file_t *file = (lfsr_file_t*)opened;
if (lfsr_ftree_isbshrub(ftree) if (lfsr_ftree_isbshrub(&file->mdir, &file->ftree)
&& lfsr_bshrub_cmp(&ftree->u.bshrub, bshrub) == 0) { && lfsr_bshrub_cmp(&file->ftree.u.bshrub, bshrub) == 0) {
ftree->u.bshrub.rbyd_ = *rbyd_; file->ftree.u.bshrub.rbyd_ = *rbyd_;
} }
} }
@@ -7078,19 +7084,19 @@ static lfs_ssize_t lfsr_bshrub_estimate(lfs_t *lfs, lfsr_mdir_t *mdir) {
LFS_TYPE_REG-LFS_TYPE_REG]; LFS_TYPE_REG-LFS_TYPE_REG];
opened; opened;
opened = opened->next) { opened = opened->next) {
lfsr_ftree_t *ftree = (lfsr_ftree_t*)opened; lfsr_file_t *file = (lfsr_file_t*)opened;
if (ftree->mdir.mid == mdir->mid) { if (file->mdir.mid == mdir->mid) {
if (lfsr_ftree_isbsprout(ftree)) { if (lfsr_ftree_isbsprout(&file->mdir, &file->ftree)) {
lfs_ssize_t dsize = lfsr_bsprout_estimate__(lfs, lfs_ssize_t dsize = lfsr_bsprout_estimate__(lfs,
&ftree->u.bsprout); &file->ftree.u.bsprout);
if (dsize < 0) { if (dsize < 0) {
return dsize; return dsize;
} }
estimate += dsize; estimate += dsize;
} else if (lfsr_ftree_isbshrub(ftree)) { } else if (lfsr_ftree_isbshrub(&file->mdir, &file->ftree)) {
lfs_ssize_t dsize = lfsr_bshrub_estimate__(lfs, lfs_ssize_t dsize = lfsr_bshrub_estimate__(lfs,
&ftree->u.bshrub); &file->ftree.u.bshrub);
if (dsize < 0) { if (dsize < 0) {
return dsize; return dsize;
} }
@@ -7190,10 +7196,10 @@ static int lfsr_bshrub_commit(lfs_t *lfs,
LFS_TYPE_REG-LFS_TYPE_REG]; LFS_TYPE_REG-LFS_TYPE_REG];
opened; opened;
opened = opened->next) { opened = opened->next) {
lfsr_ftree_t *ftree = (lfsr_ftree_t*)opened; lfsr_file_t *file = (lfsr_file_t*)opened;
if (ftree->mdir.mid == mdir->mid) { if (file->mdir.mid == mdir->mid) {
if (lfsr_ftree_isbshrub(ftree)) { if (lfsr_ftree_isbshrub(&file->mdir, &file->ftree)) {
ftree->u.bshrub.estimate = estimate; file->ftree.u.bshrub.estimate = estimate;
} }
} }
} }
@@ -7618,32 +7624,32 @@ static int lfsr_traversal_read(lfs_t *lfs, lfsr_traversal_t *traversal,
continue; continue;
} }
const lfsr_ftree_t *ftree const lfsr_file_t *file
= (const lfsr_ftree_t*)traversal->u.opened; = (const lfsr_file_t*)traversal->u.opened;
// found a direct block? // found a direct block?
if (lfsr_ftree_isbleaf(ftree)) { if (lfsr_ftree_isbleaf(&file->mdir, &file->ftree)) {
tinfo->u.bptr = ftree->u.bptr; tinfo->u.bptr = file->ftree.u.bptr;
// TODO validate? // TODO validate?
// transition to next ftree // transition to next file
traversal->u.opened = ftree->next; traversal->u.opened = file->next;
tinfo->tag = LFSR_TAG_BLOCK; tinfo->tag = LFSR_TAG_BLOCK;
return 0; return 0;
// found a bshrub/btree? // found a bshrub/btree?
} else if (lfsr_ftree_isbshruborbtree(ftree)) { } else if (lfsr_ftree_isbshruborbtree(&file->ftree)) {
// start traversing // start traversing
traversal->mdir = ftree->mdir; traversal->mdir = file->mdir;
traversal->bshrub = ftree->u.bshrub; traversal->bshrub = file->ftree.u.bshrub;
traversal->btraversal = LFSR_BTRAVERSAL(); traversal->btraversal = LFSR_BTRAVERSAL();
traversal->state = LFSR_TRAVERSAL_OPENEDBTREE; traversal->state = LFSR_TRAVERSAL_OPENEDBTREE;
continue; continue;
// no? continue to next ftree // no? continue to next file
} else { } else {
traversal->u.opened = ftree->next; traversal->u.opened = file->next;
continue; continue;
} }
@@ -9190,35 +9196,40 @@ int lfsr_dir_rewind(lfs_t *lfs, lfsr_dir_t *dir) {
#define LFSR_FTREE_ISNULLORBSPROUTORBLEAF 0x80000000 #define LFSR_FTREE_ISNULLORBSPROUTORBLEAF 0x80000000
#define LFSR_FTREE_NULL (LFSR_FTREE_ISNULLORBSPROUTORBLEAF | 0) #define LFSR_FTREE_NULL() \
((lfsr_ftree_t){.u.size=(LFSR_FTREE_ISNULLORBSPROUTORBLEAF | 0)})
static inline bool lfsr_ftree_isnull(const lfsr_ftree_t *ftree) { static inline bool lfsr_ftree_isnull(const lfsr_ftree_t *ftree) {
return (lfs_size_t)ftree->u.bsprout.data.u.disk.size return (lfs_size_t)ftree->u.bsprout.data.u.disk.size
== (LFSR_FTREE_ISNULLORBSPROUTORBLEAF | 0); == (LFSR_FTREE_ISNULLORBSPROUTORBLEAF | 0);
} }
static inline bool lfsr_ftree_isbsprout(const lfsr_ftree_t *ftree) { static inline bool lfsr_ftree_isbsprout(
const lfsr_mdir_t *mdir, const lfsr_ftree_t *ftree) {
return (lfs_size_t)ftree->u.bsprout.data.u.disk.size return (lfs_size_t)ftree->u.bsprout.data.u.disk.size
> (LFSR_FTREE_ISNULLORBSPROUTORBLEAF | 0) > (LFSR_FTREE_ISNULLORBSPROUTORBLEAF | 0)
&& lfsr_bsprout_isbsprout(&ftree->mdir, &ftree->u.bsprout); && lfsr_bsprout_isbsprout(mdir, &ftree->u.bsprout);
} }
static inline bool lfsr_ftree_isbleaf(const lfsr_ftree_t *ftree) { static inline bool lfsr_ftree_isbleaf(
const lfsr_mdir_t *mdir, const lfsr_ftree_t *ftree) {
return (lfs_size_t)ftree->u.bsprout.data.u.disk.size return (lfs_size_t)ftree->u.bsprout.data.u.disk.size
> (LFSR_FTREE_ISNULLORBSPROUTORBLEAF | 0) > (LFSR_FTREE_ISNULLORBSPROUTORBLEAF | 0)
&& lfsr_bsprout_isbleaf(&ftree->mdir, &ftree->u.bsprout); && lfsr_bsprout_isbleaf(mdir, &ftree->u.bsprout);
} }
static inline bool lfsr_ftree_isbshrub(const lfsr_ftree_t *ftree) { static inline bool lfsr_ftree_isbshrub(
const lfsr_mdir_t *mdir, const lfsr_ftree_t *ftree) {
return !(ftree->u.bsprout.data.u.disk.size return !(ftree->u.bsprout.data.u.disk.size
& LFSR_FTREE_ISNULLORBSPROUTORBLEAF) & LFSR_FTREE_ISNULLORBSPROUTORBLEAF)
&& lfsr_bshrub_isbshrub(&ftree->mdir, &ftree->u.bshrub); && lfsr_bshrub_isbshrub(mdir, &ftree->u.bshrub);
} }
static inline bool lfsr_ftree_isbtree(const lfsr_ftree_t *ftree) { static inline bool lfsr_ftree_isbtree(
const lfsr_mdir_t *mdir, const lfsr_ftree_t *ftree) {
return !(ftree->u.bsprout.data.u.disk.size return !(ftree->u.bsprout.data.u.disk.size
& LFSR_FTREE_ISNULLORBSPROUTORBLEAF) & LFSR_FTREE_ISNULLORBSPROUTORBLEAF)
&& lfsr_bshrub_isbtree(&ftree->mdir, &ftree->u.bshrub); && lfsr_bshrub_isbtree(mdir, &ftree->u.bshrub);
} }
static inline bool lfsr_ftree_isbshruborbtree(const lfsr_ftree_t *ftree) { static inline bool lfsr_ftree_isbshruborbtree(const lfsr_ftree_t *ftree) {
@@ -9286,7 +9297,8 @@ static inline lfs_off_t lfsr_file_size_(const lfsr_file_t *file) {
// file operations // file operations
// needed in lfsr_file_opencfg // needed in lfsr_file_opencfg
static lfs_ssize_t lfsr_ftree_read(lfs_t *lfs, const lfsr_ftree_t *ftree, static lfs_ssize_t lfsr_ftree_read(lfs_t *lfs,
const lfsr_mdir_t *mdir, const lfsr_ftree_t *ftree,
lfs_off_t pos, uint8_t *buffer, lfs_size_t size); lfs_off_t pos, uint8_t *buffer, lfs_size_t size);
int lfsr_file_opencfg(lfs_t *lfs, lfsr_file_t *file, int lfsr_file_opencfg(lfs_t *lfs, lfsr_file_t *file,
@@ -9305,7 +9317,7 @@ int lfsr_file_opencfg(lfs_t *lfs, lfsr_file_t *file,
file->cfg = cfg; file->cfg = cfg;
file->pos = 0; file->pos = 0;
// default data state // default data state
file->ftree.u.size = LFSR_FTREE_NULL; file->ftree = LFSR_FTREE_NULL();
// lookup our parent // lookup our parent
lfsr_tag_t tag; lfsr_tag_t tag;
@@ -9313,9 +9325,9 @@ int lfsr_file_opencfg(lfs_t *lfs, lfsr_file_t *file,
const char *name; const char *name;
lfs_size_t name_size; lfs_size_t name_size;
int err = lfsr_mtree_pathlookup(lfs, path, int err = lfsr_mtree_pathlookup(lfs, path,
&file->ftree.mdir, &tag, &file->mdir, &tag,
&did, &name, &name_size); &did, &name, &name_size);
if (err && (err != LFS_ERR_NOENT || file->ftree.mdir.mid == -1)) { if (err && (err != LFS_ERR_NOENT || file->mdir.mid == -1)) {
return err; return err;
} }
@@ -9337,8 +9349,8 @@ int lfsr_file_opencfg(lfs_t *lfs, lfsr_file_t *file,
// but it's the only way for us to save the file name. // but it's the only way for us to save the file name.
// //
// TODO or is it? ;) // TODO or is it? ;)
err = lfsr_mdir_commit(lfs, &file->ftree.mdir, LFSR_ATTRS( err = lfsr_mdir_commit(lfs, &file->mdir, LFSR_ATTRS(
LFSR_ATTR(file->ftree.mdir.mid, LFSR_ATTR(file->mdir.mid,
REG, +1, CAT( REG, +1, CAT(
LFSR_DATA_LEB128(did), LFSR_DATA_LEB128(did),
LFSR_DATA_BUF(name, name_size))))); LFSR_DATA_BUF(name, name_size)))));
@@ -9362,8 +9374,8 @@ int lfsr_file_opencfg(lfs_t *lfs, lfsr_file_t *file,
// read any inlined state // read any inlined state
lfsr_tag_t tag; lfsr_tag_t tag;
lfsr_data_t data; lfsr_data_t data;
err = lfsr_mdir_lookupnext(lfs, &file->ftree.mdir, err = lfsr_mdir_lookupnext(lfs, &file->mdir,
file->ftree.mdir.mid, LFSR_TAG_DATA, file->mdir.mid, LFSR_TAG_DATA,
&tag, &data); &tag, &data);
if (err && err != LFS_ERR_NOENT) { if (err && err != LFS_ERR_NOENT) {
return err; return err;
@@ -9388,8 +9400,8 @@ int lfsr_file_opencfg(lfs_t *lfs, lfsr_file_t *file,
file->ftree.u.bleaf.becksum.size = -1; file->ftree.u.bleaf.becksum.size = -1;
if (lfsr_o_iswriteable(flags)) { if (lfsr_o_iswriteable(flags)) {
lfsr_data_t data; lfsr_data_t data;
err = lfsr_mdir_lookupnext(lfs, &file->ftree.mdir, err = lfsr_mdir_lookupnext(lfs, &file->mdir,
file->ftree.mdir.mid, LFSR_TAG_BECKSUM, file->mdir.mid, LFSR_TAG_BECKSUM,
NULL, &data); NULL, &data);
if (err && err != LFS_ERR_NOENT) { if (err && err != LFS_ERR_NOENT) {
return err; return err;
@@ -9412,7 +9424,7 @@ int lfsr_file_opencfg(lfs_t *lfs, lfsr_file_t *file,
} }
file->ftree.u.bshrub.rbyd.blocks[0] file->ftree.u.bshrub.rbyd.blocks[0]
= file->ftree.mdir.rbyd.blocks[0]; = file->mdir.rbyd.blocks[0];
file->ftree.u.bshrub.rbyd.trunk = trunk; file->ftree.u.bshrub.rbyd.trunk = trunk;
file->ftree.u.bshrub.rbyd.weight = weight; file->ftree.u.bshrub.rbyd.weight = weight;
// force estimate recalculation if we write to this shrub // force estimate recalculation if we write to this shrub
@@ -9444,7 +9456,7 @@ int lfsr_file_opencfg(lfs_t *lfs, lfsr_file_t *file,
if (lfsr_ftree_size(&file->ftree) <= lfs->cfg->cache_size if (lfsr_ftree_size(&file->ftree) <= lfs->cfg->cache_size
&& lfsr_ftree_size(&file->ftree) <= lfs->cfg->inline_size && lfsr_ftree_size(&file->ftree) <= lfs->cfg->inline_size
&& lfsr_ftree_size(&file->ftree) <= lfs->cfg->fragment_size) { && lfsr_ftree_size(&file->ftree) <= lfs->cfg->fragment_size) {
lfs_ssize_t d = lfsr_ftree_read(lfs, &file->ftree, lfs_ssize_t d = lfsr_ftree_read(lfs, &file->mdir, &file->ftree,
0, file->buffer, lfsr_ftree_size(&file->ftree)); 0, file->buffer, lfsr_ftree_size(&file->ftree));
if (d < 0) { if (d < 0) {
err = d; err = d;
@@ -9455,7 +9467,7 @@ int lfsr_file_opencfg(lfs_t *lfs, lfsr_file_t *file,
file->flags |= LFS_F_UNFLUSHED; file->flags |= LFS_F_UNFLUSHED;
file->buffer_pos = 0; file->buffer_pos = 0;
file->buffer_size = lfsr_ftree_size(&file->ftree); file->buffer_size = lfsr_ftree_size(&file->ftree);
file->ftree.u.size = LFSR_FTREE_NULL; file->ftree = LFSR_FTREE_NULL();
} }
// add to tracked mdirs // add to tracked mdirs
@@ -9507,7 +9519,8 @@ int lfsr_file_close(lfs_t *lfs, lfsr_file_t *file) {
// low-level ftree operations // low-level ftree operations
static int lfsr_ftree_lookupnext(lfs_t *lfs, const lfsr_ftree_t *ftree, static int lfsr_ftree_lookupnext(lfs_t *lfs,
const lfsr_mdir_t *mdir, const lfsr_ftree_t *ftree,
lfs_off_t pos, lfs_off_t pos,
lfsr_bid_t *bid_, lfsr_tag_t *tag_, lfsr_bid_t *weight_, lfsr_bid_t *bid_, lfsr_tag_t *tag_, lfsr_bid_t *weight_,
lfsr_bptr_t *bptr_, lfsr_ecksum_t *becksum_) { lfsr_bptr_t *bptr_, lfsr_ecksum_t *becksum_) {
@@ -9518,7 +9531,7 @@ static int lfsr_ftree_lookupnext(lfs_t *lfs, const lfsr_ftree_t *ftree,
LFS_ASSERT(!lfsr_ftree_isnull(ftree)); LFS_ASSERT(!lfsr_ftree_isnull(ftree));
// inlined sprout? // inlined sprout?
if (lfsr_ftree_isbsprout(ftree)) { if (lfsr_ftree_isbsprout(mdir, ftree)) {
if (bid_) { if (bid_) {
*bid_ = lfsr_data_size(&ftree->u.bsprout.data)-1; *bid_ = lfsr_data_size(&ftree->u.bsprout.data)-1;
} }
@@ -9537,7 +9550,7 @@ static int lfsr_ftree_lookupnext(lfs_t *lfs, const lfsr_ftree_t *ftree,
return 0; return 0;
// block pointer? // block pointer?
} else if (lfsr_ftree_isbleaf(ftree)) { } else if (lfsr_ftree_isbleaf(mdir, ftree)) {
if (bid_) { if (bid_) {
*bid_ = lfsr_data_size(&ftree->u.bptr.data)-1; *bid_ = lfsr_data_size(&ftree->u.bptr.data)-1;
} }
@@ -9564,7 +9577,7 @@ static int lfsr_ftree_lookupnext(lfs_t *lfs, const lfsr_ftree_t *ftree,
lfsr_bid_t weight; lfsr_bid_t weight;
lfsr_data_t data; lfsr_data_t data;
int err = lfsr_bshrub_lookupnext_(lfs, int err = lfsr_bshrub_lookupnext_(lfs,
&ftree->mdir, &ftree->u.bshrub, mdir, &ftree->u.bshrub,
pos, pos,
&bid, &rbyd, &rid, &tag, &weight, &data); &bid, &rbyd, &rid, &tag, &weight, &data);
if (err) { if (err) {
@@ -9616,7 +9629,8 @@ static int lfsr_ftree_lookupnext(lfs_t *lfs, const lfsr_ftree_t *ftree,
} }
} }
static lfs_ssize_t lfsr_ftree_readnext(lfs_t *lfs, const lfsr_ftree_t *ftree, static lfs_ssize_t lfsr_ftree_readnext(lfs_t *lfs,
const lfsr_mdir_t *mdir, const lfsr_ftree_t *ftree,
lfs_off_t pos, uint8_t *buffer, lfs_size_t size) { lfs_off_t pos, uint8_t *buffer, lfs_size_t size) {
lfs_off_t pos_ = pos; lfs_off_t pos_ = pos;
// read one btree entry // read one btree entry
@@ -9624,7 +9638,7 @@ static lfs_ssize_t lfsr_ftree_readnext(lfs_t *lfs, const lfsr_ftree_t *ftree,
lfsr_tag_t tag; lfsr_tag_t tag;
lfsr_bid_t weight; lfsr_bid_t weight;
lfsr_bptr_t bptr; lfsr_bptr_t bptr;
int err = lfsr_ftree_lookupnext(lfs, ftree, pos_, int err = lfsr_ftree_lookupnext(lfs, mdir, ftree, pos_,
&bid, &tag, &weight, &bptr, NULL); &bid, &tag, &weight, &bptr, NULL);
if (err) { if (err) {
return err; return err;
@@ -9663,11 +9677,12 @@ static lfs_ssize_t lfsr_ftree_readnext(lfs_t *lfs, const lfsr_ftree_t *ftree,
return pos_ - pos; return pos_ - pos;
} }
static lfs_ssize_t lfsr_ftree_read(lfs_t *lfs, const lfsr_ftree_t *ftree, static lfs_ssize_t lfsr_ftree_read(lfs_t *lfs,
const lfsr_mdir_t *mdir, const lfsr_ftree_t *ftree,
lfs_off_t pos, uint8_t *buffer, lfs_size_t size) { lfs_off_t pos, uint8_t *buffer, lfs_size_t size) {
lfs_off_t pos_ = pos; lfs_off_t pos_ = pos;
while (size > 0 && pos_ < lfsr_ftree_size(ftree)) { while (size > 0 && pos_ < lfsr_ftree_size(ftree)) {
lfs_ssize_t d = lfsr_ftree_readnext(lfs, ftree, lfs_ssize_t d = lfsr_ftree_readnext(lfs, mdir, ftree,
pos_, buffer, size); pos_, buffer, size);
if (d < 0) { if (d < 0) {
LFS_ASSERT(d != LFS_ERR_NOENT); LFS_ASSERT(d != LFS_ERR_NOENT);
@@ -9682,7 +9697,8 @@ static lfs_ssize_t lfsr_ftree_read(lfs_t *lfs, const lfsr_ftree_t *ftree,
return pos_ - pos; return pos_ - pos;
} }
static int lfsr_ftree_carve(lfs_t *lfs, lfsr_ftree_t *ftree, static int lfsr_ftree_carve(lfs_t *lfs,
lfsr_mdir_t *mdir, lfsr_ftree_t *ftree,
lfs_off_t pos, lfs_off_t weight, lfs_soff_t delta, lfs_off_t pos, lfs_off_t weight, lfs_soff_t delta,
lfsr_tag_t tag, const lfsr_bptr_t *bptr, const lfsr_ecksum_t *becksum) { lfsr_tag_t tag, const lfsr_bptr_t *bptr, const lfsr_ecksum_t *becksum) {
// Note! This function has some rather special constraints: // Note! This function has some rather special constraints:
@@ -9704,19 +9720,19 @@ static int lfsr_ftree_carve(lfs_t *lfs, lfsr_ftree_t *ftree,
// //
// before we touch anything, if our file is a btree, we need to mark all // before we touch anything, if our file is a btree, we need to mark all
// other references btree as unerased // other references btree as unerased
if (lfsr_ftree_isbtree(ftree)) { if (lfsr_ftree_isbtree(mdir, ftree)) {
for (lfsr_openedmdir_t *opened_ = lfs->opened[ for (lfsr_openedmdir_t *opened_ = lfs->opened[
LFS_TYPE_REG-LFS_TYPE_REG]; LFS_TYPE_REG-LFS_TYPE_REG];
opened_; opened_;
opened_ = opened_->next) { opened_ = opened_->next) {
lfsr_ftree_t *ftree_ = (lfsr_ftree_t*)opened_; lfsr_file_t *file_ = (lfsr_file_t*)opened_;
if (ftree_ != ftree if (&file_->ftree != ftree
&& lfsr_ftree_isbtree(ftree_) && lfsr_ftree_isbtree(&file_->mdir, &file_->ftree)
&& lfsr_btree_cmp( && lfsr_btree_cmp(
&ftree_->u.btree, &file_->ftree.u.btree,
&ftree->u.btree) == 0) { &ftree->u.btree) == 0) {
// mark as unerased // mark as unerased
ftree_->u.btree.eoff = -1; file_->ftree.u.btree.eoff = -1;
} }
} }
} }
@@ -9724,7 +9740,7 @@ static int lfsr_ftree_carve(lfs_t *lfs, lfsr_ftree_t *ftree,
// always convert to bshrub/btree when this function is called // always convert to bshrub/btree when this function is called
if (!lfsr_ftree_isbshruborbtree(ftree)) { if (!lfsr_ftree_isbshruborbtree(ftree)) {
lfsr_bshrub_t bshrub; lfsr_bshrub_t bshrub;
bshrub.rbyd.blocks[0] = ftree->mdir.rbyd.blocks[0]; bshrub.rbyd.blocks[0] = mdir->rbyd.blocks[0];
bshrub.rbyd.trunk = 0; bshrub.rbyd.trunk = 0;
bshrub.rbyd.weight = 0; bshrub.rbyd.weight = 0;
// force estimate recalculation // force estimate recalculation
@@ -9735,16 +9751,16 @@ static int lfsr_ftree_carve(lfs_t *lfs, lfsr_ftree_t *ftree,
// they have no state that needs to be compacted // they have no state that needs to be compacted
uint8_t bptr_buf[LFSR_BPTR_DSIZE]; uint8_t bptr_buf[LFSR_BPTR_DSIZE];
uint8_t becksum_buf[LFSR_ECKSUM_DSIZE]; uint8_t becksum_buf[LFSR_ECKSUM_DSIZE];
int err = lfsr_bshrub_commit(lfs, &ftree->mdir, &bshrub, int err = lfsr_bshrub_commit(lfs, mdir, &bshrub,
LFSR_ATTRS( LFSR_ATTRS(
(lfsr_ftree_isbsprout(ftree)) (lfsr_ftree_isbsprout(mdir, ftree))
? LFSR_ATTR(0, ? LFSR_ATTR(0,
DATA, +lfsr_ftree_size(ftree), DATA, +lfsr_ftree_size(ftree),
DATA(ftree->u.bsprout.data)) DATA(ftree->u.bsprout.data))
: LFSR_ATTR(0, : LFSR_ATTR(0,
BLOCK, +lfsr_ftree_size(ftree), BLOCK, +lfsr_ftree_size(ftree),
FROMBPTR(&ftree->u.bptr, bptr_buf)), FROMBPTR(&ftree->u.bptr, bptr_buf)),
(lfsr_ftree_isbleaf(ftree) (lfsr_ftree_isbleaf(mdir, ftree)
&& ftree->u.bleaf.becksum.size != -1) && ftree->u.bleaf.becksum.size != -1)
? LFSR_ATTR(lfsr_ftree_size(ftree)-1, ? LFSR_ATTR(lfsr_ftree_size(ftree)-1,
BECKSUM, 0, BECKSUM, 0,
@@ -9774,7 +9790,7 @@ static int lfsr_ftree_carve(lfs_t *lfs, lfsr_ftree_t *ftree,
lfsr_bid_t weight_; lfsr_bid_t weight_;
lfsr_bptr_t bptr_; lfsr_bptr_t bptr_;
lfsr_ecksum_t becksum_; lfsr_ecksum_t becksum_;
int err = lfsr_ftree_lookupnext(lfs, ftree, int err = lfsr_ftree_lookupnext(lfs, mdir, ftree,
pos, pos,
&bid_, &tag_, &weight_, &bptr_, &becksum_); &bid_, &tag_, &weight_, &bptr_, &becksum_);
if (err) { if (err) {
@@ -9799,7 +9815,7 @@ static int lfsr_ftree_carve(lfs_t *lfs, lfsr_ftree_t *ftree,
lfs->cfg->fragment_size, lfs->cfg->fragment_size,
-1); -1);
err = lfsr_bshrub_commit(lfs, &ftree->mdir, &ftree->u.bshrub, err = lfsr_bshrub_commit(lfs, mdir, &ftree->u.bshrub,
LFSR_ATTRS( LFSR_ATTRS(
LFSR_ATTR(bid_, LFSR_ATTR(bid_,
GROW(WIDE(DATA)), GROW(WIDE(DATA)),
@@ -9827,7 +9843,7 @@ static int lfsr_ftree_carve(lfs_t *lfs, lfsr_ftree_t *ftree,
bptr_.data = lfsr_data_truncate(bptr_.data, bptr_.data = lfsr_data_truncate(bptr_.data,
lfsr_data_size(&bptr_.data) - lfs->cfg->fragment_size); lfsr_data_size(&bptr_.data) - lfs->cfg->fragment_size);
err = lfsr_bshrub_commit(lfs, &ftree->mdir, &ftree->u.bshrub, err = lfsr_bshrub_commit(lfs, mdir, &ftree->u.bshrub,
LFSR_ATTRS( LFSR_ATTRS(
LFSR_ATTR(bid_, LFSR_ATTR(bid_,
GROW(WIDE(BLOCK)), GROW(WIDE(BLOCK)),
@@ -9888,7 +9904,7 @@ static int lfsr_ftree_carve(lfs_t *lfs, lfsr_ftree_t *ftree,
LFS_ASSERT(attr_count_ <= sizeof(attrs_)/sizeof(lfsr_attr_t)); LFS_ASSERT(attr_count_ <= sizeof(attrs_)/sizeof(lfsr_attr_t));
LFS_ASSERT(buf_size <= sizeof(buf)); LFS_ASSERT(buf_size <= sizeof(buf));
err = lfsr_bshrub_commit(lfs, &ftree->mdir, &ftree->u.bshrub, err = lfsr_bshrub_commit(lfs, mdir, &ftree->u.bshrub,
attrs_, attr_count_); attrs_, attr_count_);
if (err) { if (err) {
return err; return err;
@@ -9994,7 +10010,7 @@ static int lfsr_ftree_carve(lfs_t *lfs, lfsr_ftree_t *ftree,
LFS_ASSERT(attr_count_ <= sizeof(attrs_)/sizeof(lfsr_attr_t)); LFS_ASSERT(attr_count_ <= sizeof(attrs_)/sizeof(lfsr_attr_t));
LFS_ASSERT(buf_size <= sizeof(buf)); LFS_ASSERT(buf_size <= sizeof(buf));
int err = lfsr_bshrub_commit(lfs, &ftree->mdir, &ftree->u.bshrub, int err = lfsr_bshrub_commit(lfs, mdir, &ftree->u.bshrub,
attrs_, attr_count_); attrs_, attr_count_);
if (err) { if (err) {
return err; return err;
@@ -10004,7 +10020,8 @@ static int lfsr_ftree_carve(lfs_t *lfs, lfsr_ftree_t *ftree,
return 0; return 0;
} }
static int lfsr_ftree_flush(lfs_t *lfs, lfsr_ftree_t *ftree, static int lfsr_ftree_flush(lfs_t *lfs,
lfsr_mdir_t *mdir, lfsr_ftree_t *ftree,
lfs_off_t pos, const uint8_t *buffer, lfs_size_t size) { lfs_off_t pos, const uint8_t *buffer, lfs_size_t size) {
// we can skip some btree lookups if we know we are aligned from a // we can skip some btree lookups if we know we are aligned from a
// previous iteration, we already do way too many btree lookups // previous iteration, we already do way too many btree lookups
@@ -10036,7 +10053,7 @@ static int lfsr_ftree_flush(lfs_t *lfs, lfsr_ftree_t *ftree,
lfsr_tag_t tag; lfsr_tag_t tag;
lfsr_bid_t weight; lfsr_bid_t weight;
lfsr_ecksum_t becksum; lfsr_ecksum_t becksum;
int err = lfsr_ftree_lookupnext(lfs, ftree, int err = lfsr_ftree_lookupnext(lfs, mdir, ftree,
lfs_smax32(pos - (lfs->cfg->crystal_thresh-1), 0), lfs_smax32(pos - (lfs->cfg->crystal_thresh-1), 0),
&bid, &tag, &weight, &bptr, &becksum); &bid, &tag, &weight, &bptr, &becksum);
if (err) { if (err) {
@@ -10094,7 +10111,7 @@ static int lfsr_ftree_flush(lfs_t *lfs, lfsr_ftree_t *ftree,
lfsr_bid_t bid; lfsr_bid_t bid;
lfsr_tag_t tag; lfsr_tag_t tag;
lfsr_bid_t weight; lfsr_bid_t weight;
int err = lfsr_ftree_lookupnext(lfs, ftree, int err = lfsr_ftree_lookupnext(lfs, mdir, ftree,
lfs_min32( lfs_min32(
crystal_start + (lfs->cfg->crystal_thresh-1), crystal_start + (lfs->cfg->crystal_thresh-1),
lfsr_ftree_size(ftree)-1), lfsr_ftree_size(ftree)-1),
@@ -10140,7 +10157,7 @@ static int lfsr_ftree_flush(lfs_t *lfs, lfsr_ftree_t *ftree,
lfsr_tag_t tag; lfsr_tag_t tag;
lfsr_bid_t weight; lfsr_bid_t weight;
lfsr_ecksum_t becksum; lfsr_ecksum_t becksum;
int err = lfsr_ftree_lookupnext(lfs, ftree, int err = lfsr_ftree_lookupnext(lfs, mdir, ftree,
lfs_min32( lfs_min32(
crystal_start-1, crystal_start-1,
lfsr_ftree_size(ftree)-1), lfsr_ftree_size(ftree)-1),
@@ -10259,7 +10276,7 @@ static int lfsr_ftree_flush(lfs_t *lfs, lfsr_ftree_t *ftree,
lfsr_tag_t tag_; lfsr_tag_t tag_;
lfsr_bid_t weight_; lfsr_bid_t weight_;
lfsr_bptr_t bptr_; lfsr_bptr_t bptr_;
err = lfsr_ftree_lookupnext(lfs, ftree, pos_, err = lfsr_ftree_lookupnext(lfs, mdir, ftree, pos_,
&bid_, &tag_, &weight_, &bptr_, NULL); &bid_, &tag_, &weight_, &bptr_, NULL);
if (err) { if (err) {
LFS_ASSERT(err != LFS_ERR_NOENT); LFS_ASSERT(err != LFS_ERR_NOENT);
@@ -10373,7 +10390,7 @@ static int lfsr_ftree_flush(lfs_t *lfs, lfsr_ftree_t *ftree,
} }
// and write it into our tree // and write it into our tree
err = lfsr_ftree_carve(lfs, ftree, err = lfsr_ftree_carve(lfs, mdir, ftree,
block_start, block_end - block_start, 0, block_start, block_end - block_start, 0,
LFSR_TAG_BLOCK, &bptr, &becksum); LFSR_TAG_BLOCK, &bptr, &becksum);
if (err) { if (err) {
@@ -10412,7 +10429,7 @@ static int lfsr_ftree_flush(lfs_t *lfs, lfsr_ftree_t *ftree,
lfsr_tag_t tag; lfsr_tag_t tag;
lfsr_bid_t weight; lfsr_bid_t weight;
lfsr_bptr_t bptr; lfsr_bptr_t bptr;
int err = lfsr_ftree_lookupnext(lfs, ftree, int err = lfsr_ftree_lookupnext(lfs, mdir, ftree,
fragment_start-1, fragment_start-1,
&bid, &tag, &weight, &bptr, NULL); &bid, &tag, &weight, &bptr, NULL);
if (err) { if (err) {
@@ -10450,7 +10467,7 @@ static int lfsr_ftree_flush(lfs_t *lfs, lfsr_ftree_t *ftree,
lfsr_tag_t tag; lfsr_tag_t tag;
lfsr_bid_t weight; lfsr_bid_t weight;
lfsr_bptr_t bptr; lfsr_bptr_t bptr;
int err = lfsr_ftree_lookupnext(lfs, ftree, int err = lfsr_ftree_lookupnext(lfs, mdir, ftree,
fragment_end, fragment_end,
&bid, &tag, &weight, &bptr, NULL); &bid, &tag, &weight, &bptr, NULL);
if (err) { if (err) {
@@ -10477,7 +10494,7 @@ static int lfsr_ftree_flush(lfs_t *lfs, lfsr_ftree_t *ftree,
// once we've figured out what fragment to write, carve it into // once we've figured out what fragment to write, carve it into
// our tree // our tree
int err = lfsr_ftree_carve(lfs, ftree, int err = lfsr_ftree_carve(lfs, mdir, ftree,
fragment_start, fragment_end - fragment_start, 0, fragment_start, fragment_end - fragment_start, 0,
LFSR_TAG_DATA, &(const lfsr_bptr_t){.data=data}, NULL); LFSR_TAG_DATA, &(const lfsr_bptr_t){.data=data}, NULL);
if (err && err != LFS_ERR_RANGE) { if (err && err != LFS_ERR_RANGE) {
@@ -10534,7 +10551,8 @@ lfs_ssize_t lfsr_file_read(lfs_t *lfs, lfsr_file_t *file,
if (pos_ < lfsr_ftree_size(&file->ftree)) { if (pos_ < lfsr_ftree_size(&file->ftree)) {
// bypass buffer? // bypass buffer?
if ((lfs_size_t)d >= lfs->cfg->cache_size) { if ((lfs_size_t)d >= lfs->cfg->cache_size) {
lfs_ssize_t d_ = lfsr_ftree_readnext(lfs, &file->ftree, lfs_ssize_t d_ = lfsr_ftree_readnext(lfs,
&file->mdir, &file->ftree,
pos_, buffer_, d); pos_, buffer_, d);
if (d_ < 0) { if (d_ < 0) {
LFS_ASSERT(d_ != LFS_ERR_NOENT); LFS_ASSERT(d_ != LFS_ERR_NOENT);
@@ -10562,7 +10580,8 @@ lfs_ssize_t lfsr_file_read(lfs_t *lfs, lfsr_file_t *file,
} }
// try to fill our buffer with some data // try to fill our buffer with some data
lfs_ssize_t d_ = lfsr_ftree_readnext(lfs, &file->ftree, lfs_ssize_t d_ = lfsr_ftree_readnext(lfs,
&file->mdir, &file->ftree,
pos_, file->buffer, d); pos_, file->buffer, d);
if (d_ < 0) { if (d_ < 0) {
LFS_ASSERT(d != LFS_ERR_NOENT); LFS_ASSERT(d != LFS_ERR_NOENT);
@@ -10638,7 +10657,7 @@ lfs_ssize_t lfsr_file_write(lfs_t *lfs, lfsr_file_t *file,
// //
if (!lfsr_f_isunflushed(file->flags) if (!lfsr_f_isunflushed(file->flags)
&& size >= lfs->cfg->cache_size) { && size >= lfs->cfg->cache_size) {
err = lfsr_ftree_flush(lfs, &file->ftree, err = lfsr_ftree_flush(lfs, &file->mdir, &file->ftree,
pos, buffer_, size); pos, buffer_, size);
if (err) { if (err) {
goto failed; goto failed;
@@ -10698,7 +10717,7 @@ lfs_ssize_t lfsr_file_write(lfs_t *lfs, lfsr_file_t *file,
} }
// flush our buffer so the above can't fail // flush our buffer so the above can't fail
err = lfsr_ftree_flush(lfs, &file->ftree, err = lfsr_ftree_flush(lfs, &file->mdir, &file->ftree,
file->buffer_pos, file->buffer, file->buffer_size); file->buffer_pos, file->buffer, file->buffer_size);
if (err) { if (err) {
goto failed; goto failed;
@@ -10772,7 +10791,7 @@ int lfsr_file_flush(lfs_t *lfs, lfsr_file_t *file) {
if (lfsr_f_isunflushed(file->flags) if (lfsr_f_isunflushed(file->flags)
&& file->buffer_size != 0) { && file->buffer_size != 0) {
// flush // flush
err = lfsr_ftree_flush(lfs, &file->ftree, err = lfsr_ftree_flush(lfs, &file->mdir, &file->ftree,
file->buffer_pos, file->buffer, file->buffer_size); file->buffer_pos, file->buffer, file->buffer_size);
if (err) { if (err) {
goto failed; goto failed;
@@ -10791,7 +10810,7 @@ failed:;
int lfsr_file_sync(lfs_t *lfs, lfsr_file_t *file) { int lfsr_file_sync(lfs_t *lfs, lfsr_file_t *file) {
// do nothing if our file has been removed // do nothing if our file has been removed
if (file->ftree.mdir.mid == -1) { if (file->mdir.mid == -1) {
return 0; return 0;
} }
@@ -10820,8 +10839,8 @@ int lfsr_file_sync(lfs_t *lfs, lfsr_file_t *file) {
// or bptr // or bptr
// //
// this is convenient because bptrs are a bit annoying to commit // this is convenient because bptrs are a bit annoying to commit
LFS_ASSERT(!lfsr_ftree_isbsprout(&file->ftree)); LFS_ASSERT(!lfsr_ftree_isbsprout(&file->mdir, &file->ftree));
LFS_ASSERT(!lfsr_ftree_isbleaf(&file->ftree)); LFS_ASSERT(!lfsr_ftree_isbleaf(&file->mdir, &file->ftree));
// small files should start as zero, const prop should optimize this out // small files should start as zero, const prop should optimize this out
LFS_ASSERT(!lfsr_f_isunflushed(file->flags) LFS_ASSERT(!lfsr_f_isunflushed(file->flags)
|| file->buffer_pos == 0); || file->buffer_pos == 0);
@@ -10841,20 +10860,20 @@ int lfsr_file_sync(lfs_t *lfs, lfsr_file_t *file) {
if (lfsr_f_isunsynced(file->flags)) { if (lfsr_f_isunsynced(file->flags)) {
// commit our file's metadata // commit our file's metadata
uint8_t buf[LFSR_BTREE_DSIZE]; uint8_t buf[LFSR_BTREE_DSIZE];
int err = lfsr_mdir_commit(lfs, &file->ftree.mdir, LFSR_ATTRS( int err = lfsr_mdir_commit(lfs, &file->mdir, LFSR_ATTRS(
(lfsr_f_isunflushed(file->flags) && file->buffer_size == 0) (lfsr_f_isunflushed(file->flags) && file->buffer_size == 0)
? LFSR_ATTR(file->ftree.mdir.mid, ? LFSR_ATTR(file->mdir.mid,
WIDE(RM(STRUCT)), 0, WIDE(RM(STRUCT)), 0,
NULL()) NULL())
: (lfsr_f_isunflushed(file->flags)) : (lfsr_f_isunflushed(file->flags))
? LFSR_ATTR(file->ftree.mdir.mid, ? LFSR_ATTR(file->mdir.mid,
WIDE(DATA), 0, WIDE(DATA), 0,
BUF(file->buffer, file->buffer_size)) BUF(file->buffer, file->buffer_size))
: (lfsr_ftree_isbshrub(&file->ftree)) : (lfsr_ftree_isbshrub(&file->mdir, &file->ftree))
? LFSR_ATTR(file->ftree.mdir.mid, ? LFSR_ATTR(file->mdir.mid,
WIDE(SHRUBTRUNK), 0, WIDE(SHRUBTRUNK), 0,
SHRUBTRUNK(&file->ftree.u.bshrub)) SHRUBTRUNK(&file->ftree.u.bshrub))
: LFSR_ATTR(file->ftree.mdir.mid, : LFSR_ATTR(file->mdir.mid,
WIDE(BTREE), 0, WIDE(BTREE), 0,
FROMBTREE(&file->ftree.u.btree, buf)))); FROMBTREE(&file->ftree.u.btree, buf))));
if (err) { if (err) {
@@ -10868,7 +10887,7 @@ int lfsr_file_sync(lfs_t *lfs, lfsr_file_t *file) {
opened_; opened_;
opened_ = opened_->next) { opened_ = opened_->next) {
lfsr_file_t *file_ = (lfsr_file_t*)opened_; lfsr_file_t *file_ = (lfsr_file_t*)opened_;
if (file_->ftree.mdir.mid == file->ftree.mdir.mid if (file_->mdir.mid == file->mdir.mid
// don't double update // don't double update
&& file_ != file && file_ != file
// don't update desynced file handles // don't update desynced file handles
@@ -10977,7 +10996,7 @@ int lfsr_file_truncate(lfs_t *lfs, lfsr_file_t *file, lfs_off_t size_) {
file->buffer_pos = 0; file->buffer_pos = 0;
file->buffer_size = 0; file->buffer_size = 0;
lfs_ssize_t d = lfsr_ftree_read(lfs, &file->ftree, lfs_ssize_t d = lfsr_ftree_read(lfs, &file->mdir, &file->ftree,
0, file->buffer, size_); 0, file->buffer, size_);
if (d < 0) { if (d < 0) {
err = d; err = d;
@@ -10998,12 +11017,12 @@ int lfsr_file_truncate(lfs_t *lfs, lfsr_file_t *file, lfs_off_t size_) {
file->flags |= LFS_F_UNFLUSHED; file->flags |= LFS_F_UNFLUSHED;
file->buffer_pos = 0; file->buffer_pos = 0;
file->buffer_size = size_; file->buffer_size = size_;
file->ftree.u.size = LFSR_FTREE_NULL; file->ftree = LFSR_FTREE_NULL();
// truncate our file normally // truncate our file normally
} else { } else {
// truncate our ftree // truncate our ftree
err = lfsr_ftree_carve(lfs, &file->ftree, err = lfsr_ftree_carve(lfs, &file->mdir, &file->ftree,
lfs_min32(size, size_), lfs_min32(size, size_),
size - lfs_min32(size, size_), size - lfs_min32(size, size_),
+size_ - size, +size_ - size,
@@ -11083,7 +11102,7 @@ int lfsr_file_fruncate(lfs_t *lfs, lfsr_file_t *file, lfs_off_t size_) {
file->buffer_pos = 0; file->buffer_pos = 0;
file->buffer_size = 0; file->buffer_size = 0;
lfs_ssize_t d = lfsr_ftree_read(lfs, &file->ftree, lfs_ssize_t d = lfsr_ftree_read(lfs, &file->mdir, &file->ftree,
lfsr_ftree_size(&file->ftree) - lfs_min32( lfsr_ftree_size(&file->ftree) - lfs_min32(
size_, size_,
lfsr_ftree_size(&file->ftree)), lfsr_ftree_size(&file->ftree)),
@@ -11116,12 +11135,12 @@ int lfsr_file_fruncate(lfs_t *lfs, lfsr_file_t *file, lfs_off_t size_) {
file->flags |= LFS_F_UNFLUSHED; file->flags |= LFS_F_UNFLUSHED;
file->buffer_pos = 0; file->buffer_pos = 0;
file->buffer_size = size_; file->buffer_size = size_;
file->ftree.u.size = LFSR_FTREE_NULL; file->ftree = LFSR_FTREE_NULL();
// fruncate our file normally // fruncate our file normally
} else { } else {
// fruncate our ftree // fruncate our ftree
err = lfsr_ftree_carve(lfs, &file->ftree, err = lfsr_ftree_carve(lfs, &file->mdir, &file->ftree,
0, 0,
lfs_smax32(size - size_, 0), lfs_smax32(size - size_, 0),
+size_ - size, +size_ - size,
+2 -2
View File
@@ -537,8 +537,6 @@ typedef struct lfsr_bshrub {
// the lfsr_ftree_t struct is a sort of proto-file // the lfsr_ftree_t struct is a sort of proto-file
typedef struct lfsr_ftree { typedef struct lfsr_ftree {
lfsr_openedmdir_t *next;
lfsr_mdir_t mdir;
union { union {
lfs_soff_t size; lfs_soff_t size;
lfsr_data_t data; lfsr_data_t data;
@@ -551,6 +549,8 @@ typedef struct lfsr_ftree {
} lfsr_ftree_t; } lfsr_ftree_t;
typedef struct lfsr_file { typedef struct lfsr_file {
lfsr_openedmdir_t *next;
lfsr_mdir_t mdir;
lfsr_ftree_t ftree; lfsr_ftree_t ftree;
uint32_t flags; uint32_t flags;
lfs_off_t pos; lfs_off_t pos;