From 8db3ce342c8ea1422af45e29362f88fa593a4923 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Sun, 30 Nov 2025 00:24:23 -0600 Subject: [PATCH] rattrs: Replaced LFS3_tag_TAIL with single-recurse LFS3_tag_RATTRS This originally started as an attempt to drop LFS3_tag_TAIL entirely, but that didn't really go anywhere. Any attempt to work around the double rattr-lists during mtree splits results in more mess than this magic rattr. But I did notice we only need to support "simple" rattrs during mtree splits, which means we can just call lfs3_rbyd_appendrattrs to handle these. Maybe this will be problematic if we ever want to deduplicate lfs3_mdir_commit___ and lfs3_rbyd_appendrattrs, but I don't see that happening because of the different concerns (mdir-specific rattrs): function code stack ctx lfs3_mdir_commit___ 1052 744 396 lfs3_rbyd_appendrattrs 142 584 388 The benefit of a single-recurse LFS3_tag_RATTRS: - Simplifies lfs3_mdir_commit__, no more awkward loop recursion. - May have other use cases for nesting simple rattrs? Adds a bit of code: code stack ctx before: 35316 2176 660 after: 35320 (+0.0%) 2176 (+0.0%) 660 (+0.0%) code stack ctx gbmap before: 38148 2192 772 gbmap after: 38172 (+0.1%) 2192 (+0.0%) 772 (+0.0%) --- lfs3.c | 30 ++++++++++++++++-------------- lfs3.h | 2 +- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/lfs3.c b/lfs3.c index b39902eb..b318c7b4 100644 --- a/lfs3.c +++ b/lfs3.c @@ -1945,9 +1945,6 @@ typedef uint8_t lfs3_count_t; // null rattr terminates rattr lists #define LFS3_RATTR_NULL ((lfs3_rattr_t)0) -// alternatively, a tail rattr tail-recurses into another rattr list -#define LFS3_RATTR_TAIL LFS3_RATTR(0, LFS3_tag_TAIL, 0) - // create an attribute list #define LFS3_RATTRS(...) ((const lfs3_rattr_t[]){__VA_ARGS__}) @@ -8261,20 +8258,24 @@ static int lfs3_mdir_commit___(lfs3_t *lfs3, lfs3_mdir_t *mdir_, // is still included && (lfs3_size_t)(rid + 1) <= (lfs3_size_t)end_rid) { - const lfs3_rattr_t *r = rattrs; - recurse:; - for (; *r; r = lfs3_rattr_next(r, &rid)) { + for (const lfs3_rattr_t *r = rattrs; + *r; + r = lfs3_rattr_next(r, &rid)) { // we just happen to never split in an mdir commit LFS3_ASSERT(!(r > rattrs && lfs3_rattr_isinsert(r))); - // rattr lists can be chained, but only tail-recursively - if (lfs3_rattr_tag(r) == LFS3_tag_TAIL) { + // nested rattr list? we only support simple rattrs here + if (lfs3_rattr_tag(r) == LFS3_tag_RATTRS) { const lfs3_rattr_t *rattrs_ = (const lfs3_rattr_t*)lfs3_rattr_arg(r, 0); - // switch to chained rattr-list - r = rattrs_; - goto recurse; + // recurse once + int err = lfs3_rbyd_appendrattrs(lfs3, &mdir_->r, + rid, start_rid, end_rid, + rattrs_); + if (err) { + return err; + } // shrub tags append a set of attributes to an unrelated trunk // in our rbyd @@ -9286,9 +9287,10 @@ static int lfs3_mdir_commit_(lfs3_t *lfs3, lfs3_mdir_t *mdir, LFS3_RATTR_ARG(&mtree_), // were we committing to the mroot? include any -1 rattrs (mdir->mid <= -1) - ? LFS3_RATTR_TAIL - : LFS3_RATTR_NULL, - LFS3_RATTR_ARG(rattrs))); + ? LFS3_RATTR(2, LFS3_tag_RATTRS, 0) + : LFS3_RATTR(2, LFS3_TAG_NULL, 0), + LFS3_RATTR_ARG(rattrs), + LFS3_RATTR_NULL)); if (err) { LFS3_ASSERT(err != LFS3_ERR_RANGE); goto failed; diff --git a/lfs3.h b/lfs3.h index a0e3d64c..ab77b7de 100644 --- a/lfs3.h +++ b/lfs3.h @@ -829,7 +829,7 @@ enum lfs3_tag { // in-device only tags, these should never get written to disk LFS3_tag_INTERNAL = 0x0000, - LFS3_tag_TAIL = 0x0001, + LFS3_tag_RATTRS = 0x0001, LFS3_tag_SHRUBCOMMIT = 0x0002, LFS3_tag_GRMPUSH = 0x0003, LFS3_tag_MOVE = 0x0004,