Tweaked LFSR_RATTR_ to take rattr.u

I think passing around rattr.u.datas was undefined behavior, since we
could end up un-unioning it as le32/leb128/lleb128 later.

Taking rattr.u directly in LFSR_RATTR_ means we can't use LFSR_RATTR_ to
create lfsr_rattr_ts from scratch, since rattr.u is not actually a named
type, but we conveniently don't need to do this. And maybe that's a good
thing since it forces the typed variants?

Also renamed rattr.u.data_count -> rattr.u.count now that rattr.u.data
is no longer the default interface in lfsr_rattr_t.

---

Curiously saves a tiny bit of code. If anything I'd have expected a code
increase:

           code          stack          ctx
  before: 35536           2440          636
  after:  35528 (-0.0%)   2440 (+0.0%)  636 (+0.0%)
This commit is contained in:
Christopher Haster
2025-02-12 14:56:48 -06:00
parent 91341a4c48
commit dfd9b82619
+80 -80
View File
@@ -2090,9 +2090,9 @@ static inline lfsr_data_t lfsr_data_fromlleb128(uint32_t word,
typedef struct lfsr_rattr { typedef struct lfsr_rattr {
lfsr_tag_t tag; lfsr_tag_t tag;
// ignoring lazy/special tags // ignoring lazy/special tags
// sign(data_count)=0 => in-RAM buffer or estimate for lazy tags // sign(count)=0 => in-RAM buffer or estimate for lazy tags
// sign(data_count)=1 => multiple concatenated datas // sign(count)=1 => multiple concatenated datas
int16_t data_count; int16_t count;
lfsr_srid_t weight; lfsr_srid_t weight;
union { union {
const uint8_t *buffer; const uint8_t *buffer;
@@ -2105,39 +2105,39 @@ typedef struct lfsr_rattr {
} lfsr_rattr_t; } lfsr_rattr_t;
// low-level attr macro // low-level attr macro
#define LFSR_RATTR_(_tag, _weight, _datas, _data_count) \ #define LFSR_RATTR_(_tag, _weight, _u, _count) \
((lfsr_rattr_t){ \ ((lfsr_rattr_t){ \
.tag=_tag, \ .tag=_tag, \
.data_count=_data_count, \ .count=_count, \
.weight=_weight, \ .weight=_weight, \
.u.etc=_datas}) .u=_u})
// high-level attr macros // high-level attr macros
#define LFSR_RATTR(_tag, _weight) \ #define LFSR_RATTR(_tag, _weight) \
((lfsr_rattr_t){ \ ((lfsr_rattr_t){ \
.tag=_tag, \ .tag=_tag, \
.data_count=0, \ .count=0, \
.weight=_weight, \ .weight=_weight, \
.u.datas=NULL}) .u.datas=NULL})
#define LFSR_RATTR_BUF(_tag, _weight, _buffer, _size) \ #define LFSR_RATTR_BUF(_tag, _weight, _buffer, _size) \
((lfsr_rattr_t){ \ ((lfsr_rattr_t){ \
.tag=_tag, \ .tag=_tag, \
.data_count=(uint16_t){_size}, \ .count=(uint16_t){_size}, \
.weight=_weight, \ .weight=_weight, \
.u.buffer=(const void*)(_buffer)}) .u.buffer=(const void*)(_buffer)})
#define LFSR_RATTR_DATA(_tag, _weight, _data) \ #define LFSR_RATTR_DATA(_tag, _weight, _data) \
((lfsr_rattr_t){ \ ((lfsr_rattr_t){ \
.tag=_tag, \ .tag=_tag, \
.data_count=-1, \ .count=-1, \
.weight=_weight, \ .weight=_weight, \
.u.datas=_data}) .u.datas=_data})
#define LFSR_RATTR_CAT_(_tag, _weight, _datas, _data_count) \ #define LFSR_RATTR_CAT_(_tag, _weight, _datas, _data_count) \
((lfsr_rattr_t){ \ ((lfsr_rattr_t){ \
.tag=_tag, \ .tag=_tag, \
.data_count=-(uint16_t){_data_count}, \ .count=-(uint16_t){_data_count}, \
.weight=_weight, \ .weight=_weight, \
.u.datas=_datas}) .u.datas=_datas})
@@ -2151,7 +2151,7 @@ typedef struct lfsr_rattr {
#define LFSR_RATTR_NOOP() \ #define LFSR_RATTR_NOOP() \
((lfsr_rattr_t){ \ ((lfsr_rattr_t){ \
.tag=LFSR_TAG_NULL, \ .tag=LFSR_TAG_NULL, \
.data_count=0, \ .count=0, \
.weight=0, \ .weight=0, \
.u.buffer=NULL}) .u.buffer=NULL})
@@ -2161,21 +2161,21 @@ typedef struct lfsr_rattr {
#define LFSR_RATTR_LE32(_tag, _weight, _le32) \ #define LFSR_RATTR_LE32(_tag, _weight, _le32) \
((lfsr_rattr_t){ \ ((lfsr_rattr_t){ \
.tag=_tag, \ .tag=_tag, \
.data_count=0, \ .count=0, \
.weight=_weight, \ .weight=_weight, \
.u.le32=_le32}) .u.le32=_le32})
#define LFSR_RATTR_LEB128(_tag, _weight, _leb128) \ #define LFSR_RATTR_LEB128(_tag, _weight, _leb128) \
((lfsr_rattr_t){ \ ((lfsr_rattr_t){ \
.tag=_tag, \ .tag=_tag, \
.data_count=0, \ .count=0, \
.weight=_weight, \ .weight=_weight, \
.u.leb128=_leb128}) .u.leb128=_leb128})
#define LFSR_RATTR_LLEB128(_tag, _weight, _lleb128) \ #define LFSR_RATTR_LLEB128(_tag, _weight, _lleb128) \
((lfsr_rattr_t){ \ ((lfsr_rattr_t){ \
.tag=_tag, \ .tag=_tag, \
.data_count=0, \ .count=0, \
.weight=_weight, \ .weight=_weight, \
.u.lleb128=_lleb128}) .u.lleb128=_lleb128})
@@ -2189,7 +2189,7 @@ typedef struct lfsr_name {
#define LFSR_RATTR_NAME_(_tag, _weight, _name) \ #define LFSR_RATTR_NAME_(_tag, _weight, _name) \
((lfsr_rattr_t){ \ ((lfsr_rattr_t){ \
.tag=_tag, \ .tag=_tag, \
.data_count=0, \ .count=0, \
.weight=_weight, \ .weight=_weight, \
.u.etc=(const lfsr_name_t*){_name}}) .u.etc=(const lfsr_name_t*){_name}})
@@ -2206,7 +2206,7 @@ typedef struct lfsr_name {
#define LFSR_RATTR_GEOMETRY(_tag, _weight, _geometry) \ #define LFSR_RATTR_GEOMETRY(_tag, _weight, _geometry) \
((lfsr_rattr_t){ \ ((lfsr_rattr_t){ \
.tag=_tag, \ .tag=_tag, \
.data_count=0, \ .count=0, \
.weight=_weight, \ .weight=_weight, \
.u.etc=(const lfsr_geometry_t*){_geometry}}) .u.etc=(const lfsr_geometry_t*){_geometry}})
@@ -2214,35 +2214,35 @@ typedef struct lfsr_name {
#define LFSR_RATTR_BPTR(_tag, _weight, _bptr) \ #define LFSR_RATTR_BPTR(_tag, _weight, _bptr) \
((lfsr_rattr_t){ \ ((lfsr_rattr_t){ \
.tag=_tag, \ .tag=_tag, \
.data_count=LFSR_BPTR_DSIZE, \ .count=LFSR_BPTR_DSIZE, \
.weight=_weight, \ .weight=_weight, \
.u.etc=(const lfsr_bptr_t*){_bptr}}) .u.etc=(const lfsr_bptr_t*){_bptr}})
#define LFSR_RATTR_SHRUB(_tag, _weight, _shrub) \ #define LFSR_RATTR_SHRUB(_tag, _weight, _shrub) \
((lfsr_rattr_t){ \ ((lfsr_rattr_t){ \
.tag=_tag, \ .tag=_tag, \
.data_count=0, \ .count=0, \
.weight=_weight, \ .weight=_weight, \
.u.etc=(const lfsr_shrub_t*){_shrub}}) .u.etc=(const lfsr_shrub_t*){_shrub}})
#define LFSR_RATTR_BTREE(_tag, _weight, _btree) \ #define LFSR_RATTR_BTREE(_tag, _weight, _btree) \
((lfsr_rattr_t){ \ ((lfsr_rattr_t){ \
.tag=_tag, \ .tag=_tag, \
.data_count=0, \ .count=0, \
.weight=_weight, \ .weight=_weight, \
.u.etc=(const lfsr_btree_t*){_btree}}) .u.etc=(const lfsr_btree_t*){_btree}})
#define LFSR_RATTR_MPTR(_tag, _weight, _mptr) \ #define LFSR_RATTR_MPTR(_tag, _weight, _mptr) \
((lfsr_rattr_t){ \ ((lfsr_rattr_t){ \
.tag=_tag, \ .tag=_tag, \
.data_count=0, \ .count=0, \
.weight=_weight, \ .weight=_weight, \
.u.etc=(const lfs_block_t*){_mptr}}) .u.etc=(const lfs_block_t*){_mptr}})
#define LFSR_RATTR_ECKSUM(_tag, _weight, _ecksum) \ #define LFSR_RATTR_ECKSUM(_tag, _weight, _ecksum) \
((lfsr_rattr_t){ \ ((lfsr_rattr_t){ \
.tag=_tag, \ .tag=_tag, \
.data_count=0, \ .count=0, \
.weight=_weight, \ .weight=_weight, \
.u.etc=(const lfsr_ecksum_t*){_ecksum}}) .u.etc=(const lfsr_ecksum_t*){_ecksum}})
@@ -2251,28 +2251,28 @@ typedef struct lfsr_name {
#define LFSR_RATTR_RATTRS(_rattrs, _rattr_count) \ #define LFSR_RATTR_RATTRS(_rattrs, _rattr_count) \
((lfsr_rattr_t){ \ ((lfsr_rattr_t){ \
.tag=LFSR_TAG_RATTRS, \ .tag=LFSR_TAG_RATTRS, \
.data_count=(uint16_t){_rattr_count}, \ .count=(uint16_t){_rattr_count}, \
.weight=0, \ .weight=0, \
.u.etc=(const lfsr_rattr_t*){_rattrs}}) .u.etc=(const lfsr_rattr_t*){_rattrs}})
#define LFSR_RATTR_SHRUBCOMMIT(_shrubcommit) \ #define LFSR_RATTR_SHRUBCOMMIT(_shrubcommit) \
((lfsr_rattr_t){ \ ((lfsr_rattr_t){ \
.tag=LFSR_TAG_SHRUBCOMMIT, \ .tag=LFSR_TAG_SHRUBCOMMIT, \
.data_count=0, \ .count=0, \
.weight=0, \ .weight=0, \
.u.etc=(const lfsr_shrubcommit_t*){_shrubcommit}}) .u.etc=(const lfsr_shrubcommit_t*){_shrubcommit}})
#define LFSR_RATTR_MOVE(_move) \ #define LFSR_RATTR_MOVE(_move) \
((lfsr_rattr_t){ \ ((lfsr_rattr_t){ \
.tag=LFSR_TAG_MOVE, \ .tag=LFSR_TAG_MOVE, \
.data_count=0, \ .count=0, \
.weight=0, \ .weight=0, \
.u.etc=(const lfsr_mdir_t*){_move}}) .u.etc=(const lfsr_mdir_t*){_move}})
#define LFSR_RATTR_ATTRS(_attrs, _attr_count) \ #define LFSR_RATTR_ATTRS(_attrs, _attr_count) \
((lfsr_rattr_t){ \ ((lfsr_rattr_t){ \
.tag=LFSR_TAG_ATTRS, \ .tag=LFSR_TAG_ATTRS, \
.data_count=(uint16_t){_attr_count}, \ .count=(uint16_t){_attr_count}, \
.weight=0, \ .weight=0, \
.u.etc=(const struct lfs_attr*){_attrs}}) .u.etc=(const struct lfs_attr*){_attrs}})
@@ -2304,7 +2304,7 @@ static inline lfsr_srid_t lfsr_rattr_nextrid(lfsr_rattr_t rattr,
static inline lfsr_tag_t lfsr_rattr_dtag(lfsr_rattr_t rattr) { static inline lfsr_tag_t lfsr_rattr_dtag(lfsr_rattr_t rattr) {
// lazily tag encoding can be bypassed with explicit data, this is // lazily tag encoding can be bypassed with explicit data, this is
// necessary to allow copies during compaction, relocation, etc // necessary to allow copies during compaction, relocation, etc
if (rattr.data_count >= 0) { if (rattr.count >= 0) {
return rattr.tag; return rattr.tag;
} else { } else {
return LFSR_TAG_DATA; return LFSR_TAG_DATA;
@@ -2315,11 +2315,11 @@ static inline lfs_size_t lfsr_rattr_dsize(lfsr_rattr_t rattr) {
// note this does not include the tag size // note this does not include the tag size
// //
// this gets a bit complicated for concatenated data // this gets a bit complicated for concatenated data
if (rattr.data_count >= 0) { if (rattr.count >= 0) {
return rattr.data_count; return rattr.count;
} else { } else {
const lfsr_data_t *datas = rattr.u.datas; const lfsr_data_t *datas = rattr.u.datas;
lfs_size_t data_count = -rattr.data_count; lfs_size_t data_count = -rattr.count;
lfs_size_t size = 0; lfs_size_t size = 0;
for (lfs_size_t i = 0; i < data_count; i++) { for (lfs_size_t i = 0; i < data_count; i++) {
size += lfsr_data_size(datas[i]); size += lfsr_data_size(datas[i]);
@@ -3476,8 +3476,8 @@ static int lfsr_rbyd_appendrattr_(lfs_t *lfs, lfsr_rbyd_t *rbyd,
// we encode most tags lazily as this heavily reduces stack usage, // we encode most tags lazily as this heavily reduces stack usage,
// though this does make us less gc-able at compile time // though this does make us less gc-able at compile time
lfs_size_t size; lfs_size_t size;
const void *datas; const void *data;
int16_t data_count; int16_t count;
struct { struct {
// uh, there's probably a better way to do this, but I'm not // uh, there's probably a better way to do this, but I'm not
// sure what it is // sure what it is
@@ -3509,10 +3509,10 @@ static int lfsr_rbyd_appendrattr_(lfs_t *lfs, lfsr_rbyd_t *rbyd,
case LFSR_TAG_WCOMPAT:; case LFSR_TAG_WCOMPAT:;
case LFSR_TAG_OCOMPAT:; case LFSR_TAG_OCOMPAT:;
case LFSR_TAG_GCKSUMDELTA:; case LFSR_TAG_GCKSUMDELTA:;
lfsr_data_t data = lfsr_data_fromle32(rattr.u.le32, ctx.u.buf); lfsr_data_t data_ = lfsr_data_fromle32(rattr.u.le32, ctx.u.buf);
size = lfsr_data_size(data); size = lfsr_data_size(data_);
datas = ctx.u.buf; data = ctx.u.buf;
data_count = size; count = size;
break; break;
// leb128? // leb128?
@@ -3525,18 +3525,18 @@ static int lfsr_rbyd_appendrattr_(lfs_t *lfs, lfsr_rbyd_t *rbyd,
// little-leb128s should not exceed 28-bits // little-leb128s should not exceed 28-bits
LFS_ASSERT(rattr.tag != LFSR_TAG_NAMELIMIT LFS_ASSERT(rattr.tag != LFSR_TAG_NAMELIMIT
|| rattr.u.leb128 <= 0x0fffffff); || rattr.u.leb128 <= 0x0fffffff);
data = lfsr_data_fromleb128(rattr.u.leb128, ctx.u.buf); data_ = lfsr_data_fromleb128(rattr.u.leb128, ctx.u.buf);
size = lfsr_data_size(data); size = lfsr_data_size(data_);
datas = ctx.u.buf; data = ctx.u.buf;
data_count = size; count = size;
break; break;
// geometry? // geometry?
case LFSR_TAG_GEOMETRY:; case LFSR_TAG_GEOMETRY:;
data = lfsr_data_fromgeometry(rattr.u.etc, ctx.u.buf); data_ = lfsr_data_fromgeometry(rattr.u.etc, ctx.u.buf);
size = lfsr_data_size(data); size = lfsr_data_size(data_);
datas = ctx.u.buf; data = ctx.u.buf;
data_count = size; count = size;
break; break;
// name? // name?
@@ -3548,17 +3548,17 @@ static int lfsr_rbyd_appendrattr_(lfs_t *lfs, lfsr_rbyd_t *rbyd,
ctx.u.name.datas[0] = lfsr_data_fromleb128(name->did, ctx.u.name.buf); ctx.u.name.datas[0] = lfsr_data_fromleb128(name->did, ctx.u.name.buf);
ctx.u.name.datas[1] = LFSR_DATA_BUF(name->name, name->name_len); ctx.u.name.datas[1] = LFSR_DATA_BUF(name->name, name->name_len);
size = lfsr_data_size(ctx.u.name.datas[0]) + name->name_len; size = lfsr_data_size(ctx.u.name.datas[0]) + name->name_len;
datas = &ctx.u.name.datas; data = &ctx.u.name.datas;
data_count = -2; count = -2;
break; break;
// bptr? // bptr?
case LFSR_TAG_BLOCK:; case LFSR_TAG_BLOCK:;
case LFSR_TAG_SHRUB | LFSR_TAG_BLOCK:; case LFSR_TAG_SHRUB | LFSR_TAG_BLOCK:;
data = lfsr_data_frombptr(rattr.u.etc, ctx.u.buf); data_ = lfsr_data_frombptr(rattr.u.etc, ctx.u.buf);
size = lfsr_data_size(data); size = lfsr_data_size(data_);
datas = ctx.u.buf; data = ctx.u.buf;
data_count = size; count = size;
break; break;
// shrub trunk? // shrub trunk?
@@ -3566,43 +3566,43 @@ static int lfsr_rbyd_appendrattr_(lfs_t *lfs, lfsr_rbyd_t *rbyd,
// note unlike the other lazy tags, we _need_ to lazily encode // note unlike the other lazy tags, we _need_ to lazily encode
// shrub trunks, since they change underneath us during mdir // shrub trunks, since they change underneath us during mdir
// compactions, relocations, etc // compactions, relocations, etc
data = lfsr_data_fromshrub(rattr.u.etc, ctx.u.buf); data_ = lfsr_data_fromshrub(rattr.u.etc, ctx.u.buf);
size = lfsr_data_size(data); size = lfsr_data_size(data_);
datas = ctx.u.buf; data = ctx.u.buf;
data_count = size; count = size;
break; break;
// btree? // btree?
case LFSR_TAG_BTREE:; case LFSR_TAG_BTREE:;
case LFSR_TAG_MTREE:; case LFSR_TAG_MTREE:;
data = lfsr_data_frombtree(rattr.u.etc, ctx.u.buf); data_ = lfsr_data_frombtree(rattr.u.etc, ctx.u.buf);
size = lfsr_data_size(data); size = lfsr_data_size(data_);
datas = ctx.u.buf; data = ctx.u.buf;
data_count = size; count = size;
break; break;
// mptr? // mptr?
case LFSR_TAG_MROOT:; case LFSR_TAG_MROOT:;
case LFSR_TAG_MDIR:; case LFSR_TAG_MDIR:;
data = lfsr_data_frommptr(rattr.u.etc, ctx.u.buf); data_ = lfsr_data_frommptr(rattr.u.etc, ctx.u.buf);
size = lfsr_data_size(data); size = lfsr_data_size(data_);
datas = ctx.u.buf; data = ctx.u.buf;
data_count = size; count = size;
break; break;
// ecksum? // ecksum?
case LFSR_TAG_ECKSUM:; case LFSR_TAG_ECKSUM:;
data = lfsr_data_fromecksum(rattr.u.etc, ctx.u.buf); data_ = lfsr_data_fromecksum(rattr.u.etc, ctx.u.buf);
size = lfsr_data_size(data); size = lfsr_data_size(data_);
datas = ctx.u.buf; data = ctx.u.buf;
data_count = size; count = size;
break; break;
// default to raw data // default to raw data
default:; default:;
size = lfsr_rattr_dsize(rattr); size = lfsr_rattr_dsize(rattr);
datas = rattr.u.datas; data = rattr.u.datas;
data_count = rattr.data_count; count = rattr.count;
break; break;
} }
@@ -3620,29 +3620,29 @@ static int lfsr_rbyd_appendrattr_(lfs_t *lfs, lfsr_rbyd_t *rbyd,
} }
// direct buffer? // direct buffer?
if (data_count >= 0) { if (count >= 0) {
err = lfsr_bd_prog(lfs, err = lfsr_bd_prog(lfs,
rbyd->blocks[0], lfsr_rbyd_eoff(rbyd), datas, data_count, rbyd->blocks[0], lfsr_rbyd_eoff(rbyd), data, count,
&rbyd->cksum, false); &rbyd->cksum, false);
if (err) { if (err) {
return err; return err;
} }
rbyd->eoff += data_count; rbyd->eoff += count;
// indirect concatenated data? // indirect concatenated data?
} else { } else {
const lfsr_data_t *datas_ = datas; const lfsr_data_t *datas = data;
lfs_size_t data_count_ = -data_count; lfs_size_t data_count = -count;
for (lfs_size_t i = 0; i < data_count_; i++) { for (lfs_size_t i = 0; i < data_count; i++) {
err = lfsr_bd_progdata(lfs, err = lfsr_bd_progdata(lfs,
rbyd->blocks[0], lfsr_rbyd_eoff(rbyd), datas_[i], rbyd->blocks[0], lfsr_rbyd_eoff(rbyd), datas[i],
&rbyd->cksum, false); &rbyd->cksum, false);
if (err) { if (err) {
return err; return err;
} }
rbyd->eoff += lfsr_data_size(datas_[i]); rbyd->eoff += lfsr_data_size(datas[i]);
} }
} }
@@ -4403,7 +4403,7 @@ leaf:;
? LFSR_TAG_NULL ? LFSR_TAG_NULL
: lfsr_tag_key(rattr.tag)), : lfsr_tag_key(rattr.tag)),
upper_rid - lower_rid + rattr.weight, upper_rid - lower_rid + rattr.weight,
rattr.u.datas, rattr.data_count)); rattr.u, rattr.count));
if (err) { if (err) {
return err; return err;
} }
@@ -4726,7 +4726,7 @@ static int lfsr_rbyd_appendcompactrattr(lfs_t *lfs, lfsr_rbyd_t *rbyd,
err = lfsr_rbyd_appendrattr_(lfs, rbyd, LFSR_RATTR_( err = lfsr_rbyd_appendrattr_(lfs, rbyd, LFSR_RATTR_(
(lfsr_rbyd_isshrub(rbyd) ? LFSR_TAG_SHRUB : 0) | rattr.tag, (lfsr_rbyd_isshrub(rbyd) ? LFSR_TAG_SHRUB : 0) | rattr.tag,
rattr.weight, rattr.weight,
rattr.u.datas, rattr.data_count)); rattr.u, rattr.count));
if (err) { if (err) {
return err; return err;
} }
@@ -7604,7 +7604,7 @@ static int lfsr_mdir_commit__(lfs_t *lfs, lfsr_mdir_t *mdir,
// must be the last tag // must be the last tag
LFS_ASSERT(i == rattr_count-1); LFS_ASSERT(i == rattr_count-1);
const lfsr_rattr_t *rattrs_ = rattrs[i].u.etc; const lfsr_rattr_t *rattrs_ = rattrs[i].u.etc;
lfs_size_t rattr_count_ = rattrs[i].data_count; lfs_size_t rattr_count_ = rattrs[i].count;
// switch to chained rattr-list // switch to chained rattr-list
rattrs = rattrs_; rattrs = rattrs_;
@@ -7716,7 +7716,7 @@ static int lfsr_mdir_commit__(lfs_t *lfs, lfsr_mdir_t *mdir,
// custom attributes need to be reencoded into our tag format // custom attributes need to be reencoded into our tag format
} else if (lfsr_tag_key(rattrs[i].tag) == LFSR_TAG_ATTRS) { } else if (lfsr_tag_key(rattrs[i].tag) == LFSR_TAG_ATTRS) {
const struct lfs_attr *attrs_ = rattrs[i].u.etc; const struct lfs_attr *attrs_ = rattrs[i].u.etc;
lfs_size_t attr_count_ = rattrs[i].data_count; lfs_size_t attr_count_ = rattrs[i].count;
for (lfs_size_t j = 0; j < attr_count_; j++) { for (lfs_size_t j = 0; j < attr_count_; j++) {
// skip readonly attrs and lazy attrs // skip readonly attrs and lazy attrs
@@ -11676,7 +11676,7 @@ static int lfsr_file_carve(lfs_t *lfs, lfsr_file_t *file,
bid = lfs_min(bid, file->b.shrub.weight); bid = lfs_min(bid, file->b.shrub.weight);
rattrs[rattr_count++] = LFSR_RATTR_( rattrs[rattr_count++] = LFSR_RATTR_(
rattr.tag, +(weight + rattr.weight), rattr.tag, +(weight + rattr.weight),
rattr.u.datas, rattr.data_count); rattr.u, rattr.count);
} }
} }