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%)
This commit is contained in:
Christopher Haster
2025-11-30 00:24:23 -06:00
parent ce6cbc3c77
commit 8db3ce342c
2 changed files with 17 additions and 15 deletions

30
lfs3.c
View File

@ -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;

2
lfs3.h
View File

@ -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,