Reworked grm encoding a bit

This drops the leading count/mode byte, and instead uses mid=0 to
terminate grms. This shaves off 1 bytes from grmdeltas.

Previously, we needed the count/mode byte for a couple reasons:

- We needed to know the number of grm entries somehow, and there wasn't
  always an obvious sentinel value. mid=-1, for example, is
  unrepresentable with our unsigned leb128 encoding.

  But now that development has settled, we can use mid=0.0 to figure out
  the end-of-queue. mid=0.0 should always map to the root bookmark,
  which doesn't make sense to delete, so it makes for a reasonable null
  terminator here.

- It provided a route for future grm extensions, which could use the >2
  count/mode encodings.

  But I think we can use additional grm tag encodings for this.

  There's only one gdelta tag so far, but the current plan for future
  gdelta tags is to carve out the bottom 2 bits for redund like we do
  with the struct tags:

    LFSR_TAG_GDELTA        0x01tt  v--- ---1 -ttt ttrr
    LFSR_TAG_GRMDELTA      0x0100  v--- ---1 ---- ----
    LFSR_TAG_GBMAPDELTA    0x0104  v--- ---1 ---- -1rr
    LFSR_TAG_GDDTREEDELTA  0x0108  v--- ---1 ---- 1-rr
    LFSR_TAG_GPTREEDELTA   0x010c  v--- ---1 ---- 11rr
    ...

  Decoding is a bit more complicated for gstate, since we will need to
  xor those bits if mutable, but this avoids needing a full byte just
  for redund in every auxiliary tree.

  Long story short, we can leverage the lower 2 bits of the grm tag for
  future extensions using the same mechanism.

This may seem like a lot of effort for only a handful of bytes, but keep
in mind each gdelta lives in more-or-less every mdir in the filesystem.

Also saves a bit of code/ctx:

           code          stack          ctx
  before: 35772           2368          640
  after:  35768 (-0.0%)   2368 (+0.0%)  636 (-0.6%)
This commit is contained in:
Christopher Haster
2025-04-29 12:32:01 -05:00
parent 98b4aaccc5
commit f2e6b60f36
7 changed files with 145 additions and 153 deletions
+75 -69
View File
@@ -7185,29 +7185,34 @@ static void lfsr_fs_mkdirty(lfs_t *lfs) {
/// Global-state things /// /// Global-state things ///
// grm (global remove) things // grm (global remove) things
static inline uint8_t lfsr_grm_count_(const lfsr_grm_t *grm) { static inline lfs_size_t lfsr_grm_count_(const lfsr_grm_t *grm) {
return (grm->mids[0] >= 0) + (grm->mids[1] >= 0); return (grm->queue[0] != 0) + (grm->queue[1] != 0);
} }
static inline uint8_t lfsr_grm_count(const lfs_t *lfs) { static inline lfs_size_t lfsr_grm_count(const lfs_t *lfs) {
return lfsr_grm_count_(&lfs->grm); return lfsr_grm_count_(&lfs->grm);
} }
static inline void lfsr_grm_push(lfs_t *lfs, lfsr_smid_t mid) { static inline void lfsr_grm_push(lfs_t *lfs, lfsr_smid_t mid) {
LFS_ASSERT(lfs->grm.mids[1] == -1); // note mid=0.0 always maps to the root bookmark and should never
lfs->grm.mids[1] = lfs->grm.mids[0]; // be grmed
lfs->grm.mids[0] = mid; LFS_ASSERT(mid != 0);
LFS_ASSERT(lfs->grm.queue[1] == 0);
lfs->grm.queue[1] = lfs->grm.queue[0];
lfs->grm.queue[0] = mid;
} }
static inline lfsr_smid_t lfsr_grm_pop(lfs_t *lfs) { static inline lfsr_smid_t lfsr_grm_pop(lfs_t *lfs) {
lfsr_smid_t mid = lfs->grm.mids[0]; lfsr_smid_t mid = lfs->grm.queue[0];
lfs->grm.mids[0] = lfs->grm.mids[1]; lfs->grm.queue[0] = lfs->grm.queue[1];
lfs->grm.mids[1] = -1; lfs->grm.queue[1] = 0;
return mid; return mid;
} }
static inline bool lfsr_grm_ismidrm(const lfs_t *lfs, lfsr_smid_t mid) { static inline bool lfsr_grm_ismidrm(const lfs_t *lfs, lfsr_smid_t mid) {
return lfs->grm.mids[0] == mid || lfs->grm.mids[1] == mid; return mid != 0
&& (lfs->grm.queue[0] == mid
|| lfs->grm.queue[1] == mid);
} }
#define LFSR_DATA_GRM(_grm, _buffer) \ #define LFSR_DATA_GRM(_grm, _buffer) \
@@ -7218,15 +7223,11 @@ static lfsr_data_t lfsr_data_fromgrm(const lfsr_grm_t *grm,
// make sure to zero so we don't leak any info // make sure to zero so we don't leak any info
lfs_memset(buffer, 0, LFSR_GRM_DSIZE); lfs_memset(buffer, 0, LFSR_GRM_DSIZE);
// first encode the number of grms, this can be 0, 1, or 2 and may // encode grms
// be extended to a general purpose leb128 type field in the future lfs_size_t count = lfsr_grm_count_(grm);
uint8_t mode = lfsr_grm_count_(grm);
lfs_ssize_t d = 0; lfs_ssize_t d = 0;
buffer[d] = mode; for (lfs_size_t i = 0; i < count; i++) {
d += 1; lfs_ssize_t d_ = lfs_toleb128(grm->queue[i], &buffer[d], 5);
for (uint8_t i = 0; i < mode; i++) {
lfs_ssize_t d_ = lfs_toleb128(grm->mids[i], &buffer[d], 5);
if (d_ < 0) { if (d_ < 0) {
LFS_UNREACHABLE(); LFS_UNREACHABLE();
} }
@@ -7242,28 +7243,26 @@ static inline lfsr_mid_t lfsr_mtree_weight(lfs_t *lfs);
static int lfsr_data_readgrm(lfs_t *lfs, lfsr_data_t *data, static int lfsr_data_readgrm(lfs_t *lfs, lfsr_data_t *data,
lfsr_grm_t *grm) { lfsr_grm_t *grm) {
// clear first // clear first
grm->mids[0] = -1; grm->queue[0] = 0;
grm->mids[1] = -1; grm->queue[1] = 0;
// first read the mode field // decode grms, these are terminated by either a null (mid=0) or the
uint8_t mode; // size of the grm buffer
lfs_ssize_t d = lfsr_data_read(lfs, data, &mode, 1); for (lfs_size_t i = 0; i < 2; i++) {
if (d < 0) { lfsr_mid_t mid;
return d; int err = lfsr_data_readleb128(lfs, data, &mid);
}
LFS_ASSERT(d == 1);
// unknown mode? return an error, we may be able to mount read-only
if (mode > 2) {
return LFS_ERR_CORRUPT;
}
for (uint8_t i = 0; i < mode; i++) {
int err = lfsr_data_readleb128(lfs, data, (lfsr_mid_t*)&grm->mids[i]);
if (err) { if (err) {
return err; return err;
} }
LFS_ASSERT((lfsr_mid_t)grm->mids[i] < lfsr_mtree_weight(lfs));
// null grm?
if (!mid) {
break;
}
// grm inside mtree?
LFS_ASSERT(mid < lfsr_mtree_weight(lfs));
grm->queue[i] = mid;
} }
return 0; return 0;
@@ -7271,24 +7270,31 @@ static int lfsr_data_readgrm(lfs_t *lfs, lfsr_data_t *data,
// some mdir-related gstate things we need // some mdir-related gstate things we need
// zero any pending gdeltas
static void lfsr_fs_flushgdelta(lfs_t *lfs) { static void lfsr_fs_flushgdelta(lfs_t *lfs) {
// zero any pending gdeltas // zero the gcksumdelta
lfs->gcksum_d = 0; lfs->gcksum_d = 0;
// zero the grmdelta
lfs_memset(lfs->grm_d, 0, LFSR_GRM_DSIZE); lfs_memset(lfs->grm_d, 0, LFSR_GRM_DSIZE);
} }
// commit any pending gdeltas
static void lfsr_fs_commitgdelta(lfs_t *lfs) { static void lfsr_fs_commitgdelta(lfs_t *lfs) {
// commit any pending gdeltas // keep track of the on-disk gcksum
lfs->gcksum_p = lfs->gcksum; lfs->gcksum_p = lfs->gcksum;
// keep track of the on-disk grm
lfsr_data_fromgrm(&lfs->grm, lfs->grm_p); lfsr_data_fromgrm(&lfs->grm, lfs->grm_p);
} }
// revert gstate to on-disk state
static void lfsr_fs_revertgdelta(lfs_t *lfs) { static void lfsr_fs_revertgdelta(lfs_t *lfs) {
// revert gstate to on-disk state // revert to the on-disk gcksum
lfs->gcksum = lfs->gcksum_p; lfs->gcksum = lfs->gcksum_p;
// revert to the on-disk grm
int err = lfsr_data_readgrm(lfs, int err = lfsr_data_readgrm(lfs,
&LFSR_DATA_BUF(lfs->grm_p, LFSR_GRM_DSIZE), &LFSR_DATA_BUF(lfs->grm_p, LFSR_GRM_DSIZE),
&lfs->grm); &lfs->grm);
@@ -8526,13 +8532,13 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
// adjust pending grms? // adjust pending grms?
} else { } else {
for (int j = 0; j < 2; j++) { for (int j = 0; j < 2; j++) {
if (lfsr_mbid(lfs, lfs->grm.mids[j]) == lfsr_mbid(lfs, mid_) if (lfsr_mbid(lfs, lfs->grm.queue[j]) == lfsr_mbid(lfs, mid_)
&& lfs->grm.mids[j] >= mid_) { && lfs->grm.queue[j] >= mid_) {
// deleting a pending grm doesn't really make sense // deleting a pending grm doesn't really make sense
LFS_ASSERT(lfs->grm.mids[j] >= mid_ - rattrs[i].weight); LFS_ASSERT(lfs->grm.queue[j] >= mid_ - rattrs[i].weight);
// adjust the grm // adjust the grm
lfs->grm.mids[j] += rattrs[i].weight; lfs->grm.queue[j] += rattrs[i].weight;
} }
} }
} }
@@ -8825,16 +8831,16 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
// patch any pending grms // patch any pending grms
for (int j = 0; j < 2; j++) { for (int j = 0; j < 2; j++) {
if (lfsr_mbid(lfs, lfs->grm.mids[j]) if (lfsr_mbid(lfs, lfs->grm.queue[j])
== lfsr_mbid(lfs, lfs_smax(mdir->mid, 0))) { == lfsr_mbid(lfs, lfs_smax(mdir->mid, 0))) {
if (mdelta > 0 if (mdelta > 0
&& lfsr_mrid(lfs, lfs->grm.mids[j]) && lfsr_mrid(lfs, lfs->grm.queue[j])
>= (lfsr_srid_t)mdir_[0].rbyd.weight) { >= (lfsr_srid_t)mdir_[0].rbyd.weight) {
lfs->grm.mids[j] lfs->grm.queue[j]
+= (1 << lfs->mbits) - mdir_[0].rbyd.weight; += (1 << lfs->mbits) - mdir_[0].rbyd.weight;
} }
} else if (lfs->grm.mids[j] > mdir->mid) { } else if (lfs->grm.queue[j] > mdir->mid) {
lfs->grm.mids[j] += mdelta; lfs->grm.queue[j] += mdelta;
} }
} }
@@ -10286,7 +10292,7 @@ int lfsr_mkdir(lfs_t *lfs, const char *path) {
if (err) { if (err) {
return err; return err;
} }
LFS_ASSERT(lfs->grm.mids[0] == mdir.mid); LFS_ASSERT(lfs->grm.queue[0] == mdir.mid);
// committing our bookmark may have changed the mid of our metadata entry, // committing our bookmark may have changed the mid of our metadata entry,
// we need to look it up again, we can at least avoid the full path walk // we need to look it up again, we can at least avoid the full path walk
@@ -10644,7 +10650,7 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) {
// update moved files with the new mdir // update moved files with the new mdir
} else if (lfsr_o_type(o->flags) == LFS_TYPE_REG } else if (lfsr_o_type(o->flags) == LFS_TYPE_REG
&& o->mdir.mid == lfs->grm.mids[0]) { && o->mdir.mid == lfs->grm.queue[0]) {
o->mdir = new_mdir; o->mdir = new_mdir;
// mark any removed dirs as zombied // mark any removed dirs as zombied
@@ -10662,8 +10668,8 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) {
} }
if (((lfsr_dir_t*)o)->did == old_did if (((lfsr_dir_t*)o)->did == old_did
&& o->mdir.mid >= lfs->grm.mids[0]) { && o->mdir.mid >= lfs->grm.queue[0]) {
if (o->mdir.mid == lfs->grm.mids[0]) { if (o->mdir.mid == lfs->grm.queue[0]) {
o->mdir.mid += 1; o->mdir.mid += 1;
} else { } else {
((lfsr_dir_t*)o)->pos -= 1; ((lfsr_dir_t*)o)->pos -= 1;
@@ -10673,7 +10679,7 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) {
// clobber entangled traversals // clobber entangled traversals
} else if (lfsr_o_type(o->flags) == LFS_type_TRAVERSAL } else if (lfsr_o_type(o->flags) == LFS_type_TRAVERSAL
&& ((exists && o->mdir.mid == new_mdir.mid) && ((exists && o->mdir.mid == new_mdir.mid)
|| o->mdir.mid == lfs->grm.mids[0])) { || o->mdir.mid == lfs->grm.queue[0])) {
lfsr_traversal_clobber(lfs, (lfsr_traversal_t*)o); lfsr_traversal_clobber(lfs, (lfsr_traversal_t*)o);
} }
} }
@@ -13486,8 +13492,8 @@ static int lfs_init(lfs_t *lfs, uint32_t flags,
lfs->gcksum_p = 0; lfs->gcksum_p = 0;
lfs->gcksum_d = 0; lfs->gcksum_d = 0;
lfs->grm.mids[0] = -1; lfs->grm.queue[0] = -1;
lfs->grm.mids[1] = -1; lfs->grm.queue[1] = -1;
lfs_memset(lfs->grm_p, 0, LFSR_GRM_DSIZE); lfs_memset(lfs->grm_p, 0, LFSR_GRM_DSIZE);
lfs_memset(lfs->grm_d, 0, LFSR_GRM_DSIZE); lfs_memset(lfs->grm_d, 0, LFSR_GRM_DSIZE);
@@ -14019,14 +14025,14 @@ static int lfsr_mountinited(lfs_t *lfs) {
// found pending grms? this should only happen if we lost power // found pending grms? this should only happen if we lost power
if (lfsr_grm_count(lfs) == 2) { if (lfsr_grm_count(lfs) == 2) {
LFS_INFO("Found pending grm %"PRId32".%"PRId32" %"PRId32".%"PRId32, LFS_INFO("Found pending grm %"PRId32".%"PRId32" %"PRId32".%"PRId32,
lfsr_dbgmbid(lfs, lfs->grm.mids[0]), lfsr_dbgmbid(lfs, lfs->grm.queue[0]),
lfsr_dbgmrid(lfs, lfs->grm.mids[0]), lfsr_dbgmrid(lfs, lfs->grm.queue[0]),
lfsr_dbgmbid(lfs, lfs->grm.mids[1]), lfsr_dbgmbid(lfs, lfs->grm.queue[1]),
lfsr_dbgmrid(lfs, lfs->grm.mids[1])); lfsr_dbgmrid(lfs, lfs->grm.queue[1]));
} else if (lfsr_grm_count(lfs) == 1) { } else if (lfsr_grm_count(lfs) == 1) {
LFS_INFO("Found pending grm %"PRId32".%"PRId32, LFS_INFO("Found pending grm %"PRId32".%"PRId32,
lfsr_dbgmbid(lfs, lfs->grm.mids[0]), lfsr_dbgmbid(lfs, lfs->grm.queue[0]),
lfsr_dbgmrid(lfs, lfs->grm.mids[0])); lfsr_dbgmrid(lfs, lfs->grm.queue[0]));
} }
return 0; return 0;
@@ -14434,22 +14440,22 @@ lfs_ssize_t lfsr_fs_size(lfs_t *lfs) {
static int lfsr_fs_fixgrm(lfs_t *lfs) { static int lfsr_fs_fixgrm(lfs_t *lfs) {
if (lfsr_grm_count(lfs) == 2) { if (lfsr_grm_count(lfs) == 2) {
LFS_INFO("Fixing grm %"PRId32".%"PRId32" %"PRId32".%"PRId32, LFS_INFO("Fixing grm %"PRId32".%"PRId32" %"PRId32".%"PRId32,
lfsr_dbgmbid(lfs, lfs->grm.mids[0]), lfsr_dbgmbid(lfs, lfs->grm.queue[0]),
lfsr_dbgmrid(lfs, lfs->grm.mids[0]), lfsr_dbgmrid(lfs, lfs->grm.queue[0]),
lfsr_dbgmbid(lfs, lfs->grm.mids[1]), lfsr_dbgmbid(lfs, lfs->grm.queue[1]),
lfsr_dbgmrid(lfs, lfs->grm.mids[1])); lfsr_dbgmrid(lfs, lfs->grm.queue[1]));
} else if (lfsr_grm_count(lfs) == 1) { } else if (lfsr_grm_count(lfs) == 1) {
LFS_INFO("Fixing grm %"PRId32".%"PRId32, LFS_INFO("Fixing grm %"PRId32".%"PRId32,
lfsr_dbgmbid(lfs, lfs->grm.mids[0]), lfsr_dbgmbid(lfs, lfs->grm.queue[0]),
lfsr_dbgmrid(lfs, lfs->grm.mids[0])); lfsr_dbgmrid(lfs, lfs->grm.queue[0]));
} }
while (lfsr_grm_count(lfs) > 0) { while (lfsr_grm_count(lfs) > 0) {
LFS_ASSERT(lfs->grm.mids[0] != -1); LFS_ASSERT(lfs->grm.queue[0] != -1);
// find our mdir // find our mdir
lfsr_mdir_t mdir; lfsr_mdir_t mdir;
int err = lfsr_mtree_lookup(lfs, lfs->grm.mids[0], int err = lfsr_mtree_lookup(lfs, lfs->grm.queue[0],
&mdir); &mdir);
if (err) { if (err) {
LFS_ASSERT(err != LFS_ERR_NOENT); LFS_ASSERT(err != LFS_ERR_NOENT);
+4 -6
View File
@@ -812,18 +812,16 @@ typedef struct lfsr_traversal {
//} lfs_gstate_t; //} lfs_gstate_t;
// grm encoding: // grm encoding:
// .---. mode: 1 leb128 1 byte // .- -+- -+- -+- -+- -. mids: 2 leb128s <=2x5 bytes
// |mod| mids: 2 leb128s <=2x5 bytes // ' mids ' total: <=10 bytes
// +- -+- -+- -+- -+- -. total: <=11 bytes
// ' mid x mod '
// + + // + +
// ' ' // ' '
// '- -+- -+- -+- -+- -' // '- -+- -+- -+- -+- -'
// //
#define LFSR_GRM_DSIZE (1+5+5) #define LFSR_GRM_DSIZE (5+5)
typedef struct lfsr_grm { typedef struct lfsr_grm {
lfsr_smid_t mids[2]; lfsr_smid_t queue[2];
} lfsr_grm_t; } lfsr_grm_t;
#ifdef LFS_CKPARITY #ifdef LFS_CKPARITY
+14 -18
View File
@@ -2726,26 +2726,22 @@ class Gstate:
def __init__(self, mtree, tag, gdeltas): def __init__(self, mtree, tag, gdeltas):
super().__init__(mtree, tag, gdeltas) super().__init__(mtree, tag, gdeltas)
queue = []
d = 0 d = 0
count, d_ = fromleb128(self.data, d); d += d_ for _ in range(2):
rms = [] mid, d_ = fromleb128(self.data, d); d += d_
if count <= 2: # a null mid (mid=0.0) terminates the grm queue
for _ in range(count): if not mid:
mid, d_ = fromleb128(self.data, d); d += d_ break
mid = mtree.mid(mid) mid = mtree.mid(mid)
# map mbids -> -1 if mroot-inlined # map mbids -> -1 if mroot-inlined
if mtree.mtree is None: if mtree.mtree is None:
mid = mtree.mid(-1, mid.mrid) mid = mtree.mid(-1, mid.mrid)
rms.append(mid) queue.append(mid)
self.count = count self.queue = queue
self.rms = rms
def repr(self): def repr(self):
return 'grm %s' % ( return 'grm [%s]' % ', '.join(mid.repr() for mid in self.queue)
'none' if self.count == 0
else ' '.join(mid.repr() for mid in self.rms)
if self.count <= 2
else '0x%x %d' % (self.count, len(self.data)))
# keep track of known gstate # keep track of known gstate
_known = [g for g in Gstate.__subclasses__() if g.tag is not None] _known = [g for g in Gstate.__subclasses__() if g.tag is not None]
@@ -2961,7 +2957,7 @@ class Lfs:
if not isinstance(mid, Mid): if not isinstance(mid, Mid):
mid = self.mid(mid) mid = self.mid(mid)
return mid in self.gstate.grm.rms return mid in self.gstate.grm.queue
# lookup operations # lookup operations
def lookup(self, mid, mdir=None, *, def lookup(self, mid, mdir=None, *,
+14 -18
View File
@@ -2756,26 +2756,22 @@ class Gstate:
def __init__(self, mtree, tag, gdeltas): def __init__(self, mtree, tag, gdeltas):
super().__init__(mtree, tag, gdeltas) super().__init__(mtree, tag, gdeltas)
queue = []
d = 0 d = 0
count, d_ = fromleb128(self.data, d); d += d_ for _ in range(2):
rms = [] mid, d_ = fromleb128(self.data, d); d += d_
if count <= 2: # a null mid (mid=0.0) terminates the grm queue
for _ in range(count): if not mid:
mid, d_ = fromleb128(self.data, d); d += d_ break
mid = mtree.mid(mid) mid = mtree.mid(mid)
# map mbids -> -1 if mroot-inlined # map mbids -> -1 if mroot-inlined
if mtree.mtree is None: if mtree.mtree is None:
mid = mtree.mid(-1, mid.mrid) mid = mtree.mid(-1, mid.mrid)
rms.append(mid) queue.append(mid)
self.count = count self.queue = queue
self.rms = rms
def repr(self): def repr(self):
return 'grm %s' % ( return 'grm [%s]' % ', '.join(mid.repr() for mid in self.queue)
'none' if self.count == 0
else ' '.join(mid.repr() for mid in self.rms)
if self.count <= 2
else '0x%x %d' % (self.count, len(self.data)))
# keep track of known gstate # keep track of known gstate
_known = [g for g in Gstate.__subclasses__() if g.tag is not None] _known = [g for g in Gstate.__subclasses__() if g.tag is not None]
@@ -2991,7 +2987,7 @@ class Lfs:
if not isinstance(mid, Mid): if not isinstance(mid, Mid):
mid = self.mid(mid) mid = self.mid(mid)
return mid in self.gstate.grm.rms return mid in self.gstate.grm.queue
# lookup operations # lookup operations
def lookup(self, mid, mdir=None, *, def lookup(self, mid, mdir=None, *,
+14 -18
View File
@@ -2683,26 +2683,22 @@ class Gstate:
def __init__(self, mtree, tag, gdeltas): def __init__(self, mtree, tag, gdeltas):
super().__init__(mtree, tag, gdeltas) super().__init__(mtree, tag, gdeltas)
queue = []
d = 0 d = 0
count, d_ = fromleb128(self.data, d); d += d_ for _ in range(2):
rms = [] mid, d_ = fromleb128(self.data, d); d += d_
if count <= 2: # a null mid (mid=0.0) terminates the grm queue
for _ in range(count): if not mid:
mid, d_ = fromleb128(self.data, d); d += d_ break
mid = mtree.mid(mid) mid = mtree.mid(mid)
# map mbids -> -1 if mroot-inlined # map mbids -> -1 if mroot-inlined
if mtree.mtree is None: if mtree.mtree is None:
mid = mtree.mid(-1, mid.mrid) mid = mtree.mid(-1, mid.mrid)
rms.append(mid) queue.append(mid)
self.count = count self.queue = queue
self.rms = rms
def repr(self): def repr(self):
return 'grm %s' % ( return 'grm [%s]' % ', '.join(mid.repr() for mid in self.queue)
'none' if self.count == 0
else ' '.join(mid.repr() for mid in self.rms)
if self.count <= 2
else '0x%x %d' % (self.count, len(self.data)))
# keep track of known gstate # keep track of known gstate
_known = [g for g in Gstate.__subclasses__() if g.tag is not None] _known = [g for g in Gstate.__subclasses__() if g.tag is not None]
@@ -2918,7 +2914,7 @@ class Lfs:
if not isinstance(mid, Mid): if not isinstance(mid, Mid):
mid = self.mid(mid) mid = self.mid(mid)
return mid in self.gstate.grm.rms return mid in self.gstate.grm.queue
# lookup operations # lookup operations
def lookup(self, mid, mdir=None, *, def lookup(self, mid, mdir=None, *,
+8 -8
View File
@@ -7976,8 +7976,8 @@ code = '''
lfsr_fs_mkconsistent(&lfs) => 0; lfsr_fs_mkconsistent(&lfs) => 0;
// we should have cleaned up all grms/orphans // we should have cleaned up all grms/orphans
assert(lfs.grm.mids[0] == -1); assert(lfs.grm.queue[0] == 0);
assert(lfs.grm.mids[1] == -1); assert(lfs.grm.queue[1] == 0);
assert(!(lfs.flags & LFS_I_MKCONSISTENT)); assert(!(lfs.flags & LFS_I_MKCONSISTENT));
struct lfs_fsinfo fsinfo; struct lfs_fsinfo fsinfo;
@@ -8112,8 +8112,8 @@ code = '''
lfsr_fs_mkconsistent(&lfs) => 0; lfsr_fs_mkconsistent(&lfs) => 0;
// we should have cleaned up all grms/orphans // we should have cleaned up all grms/orphans
assert(lfs.grm.mids[0] == -1); assert(lfs.grm.queue[0] == 0);
assert(lfs.grm.mids[1] == -1); assert(lfs.grm.queue[1] == 0);
assert(!(lfs.flags & LFS_I_MKCONSISTENT)); assert(!(lfs.flags & LFS_I_MKCONSISTENT));
struct lfs_fsinfo fsinfo; struct lfs_fsinfo fsinfo;
@@ -8262,8 +8262,8 @@ code = '''
lfsr_fs_mkconsistent(&lfs) => 0; lfsr_fs_mkconsistent(&lfs) => 0;
// we should have cleaned up all grms/orphans // we should have cleaned up all grms/orphans
assert(lfs.grm.mids[0] == -1); assert(lfs.grm.queue[0] == 0);
assert(lfs.grm.mids[1] == -1); assert(lfs.grm.queue[1] == 0);
assert(!(lfs.flags & LFS_I_MKCONSISTENT)); assert(!(lfs.flags & LFS_I_MKCONSISTENT));
struct lfs_fsinfo fsinfo; struct lfs_fsinfo fsinfo;
@@ -8418,8 +8418,8 @@ code = '''
lfsr_fs_mkconsistent(&lfs) => 0; lfsr_fs_mkconsistent(&lfs) => 0;
// we should have cleaned up all grms/orphans // we should have cleaned up all grms/orphans
assert(lfs.grm.mids[0] == -1); assert(lfs.grm.queue[0] == 0);
assert(lfs.grm.mids[1] == -1); assert(lfs.grm.queue[1] == 0);
assert(!(lfs.flags & LFS_I_MKCONSISTENT)); assert(!(lfs.flags & LFS_I_MKCONSISTENT));
struct lfs_fsinfo fsinfo; struct lfs_fsinfo fsinfo;
+16 -16
View File
@@ -6461,8 +6461,8 @@ code = '''
lfsr_traversal_close(&lfs, &t) => 0; lfsr_traversal_close(&lfs, &t) => 0;
// we should have cleaned up all grms/orphans // we should have cleaned up all grms/orphans
assert(lfs.grm.mids[0] == -1); assert(lfs.grm.queue[0] == 0);
assert(lfs.grm.mids[1] == -1); assert(lfs.grm.queue[1] == 0);
assert(!(lfs.flags & LFS_I_MKCONSISTENT)); assert(!(lfs.flags & LFS_I_MKCONSISTENT));
// which means there shouldn't be that many files left // which means there shouldn't be that many files left
@@ -6603,8 +6603,8 @@ code = '''
lfsr_traversal_close(&lfs, &t) => 0; lfsr_traversal_close(&lfs, &t) => 0;
// we should be able to clean up grms // we should be able to clean up grms
assert(lfs.grm.mids[0] == -1); assert(lfs.grm.queue[0] == 0);
assert(lfs.grm.mids[1] == -1); assert(lfs.grm.queue[1] == 0);
// if we introduce actual orphans, me _must not_ clear the orphan flag // if we introduce actual orphans, me _must not_ clear the orphan flag
if (ORPHANS >= 3) { if (ORPHANS >= 3) {
assert(lfs.flags & LFS_I_MKCONSISTENT); assert(lfs.flags & LFS_I_MKCONSISTENT);
@@ -6762,8 +6762,8 @@ code = '''
lfsr_traversal_close(&lfs, &t) => 0; lfsr_traversal_close(&lfs, &t) => 0;
// we should have cleaned up all grms/orphans // we should have cleaned up all grms/orphans
assert(lfs.grm.mids[0] == -1); assert(lfs.grm.queue[0] == 0);
assert(lfs.grm.mids[1] == -1); assert(lfs.grm.queue[1] == 0);
assert(!(lfs.flags & LFS_I_MKCONSISTENT)); assert(!(lfs.flags & LFS_I_MKCONSISTENT));
// which means there shouldn't be that many files left // which means there shouldn't be that many files left
@@ -6920,8 +6920,8 @@ code = '''
lfsr_traversal_close(&lfs, &t) => 0; lfsr_traversal_close(&lfs, &t) => 0;
// we should have cleaned up all grms/orphans // we should have cleaned up all grms/orphans
assert(lfs.grm.mids[0] == -1); assert(lfs.grm.queue[0] == 0);
assert(lfs.grm.mids[1] == -1); assert(lfs.grm.queue[1] == 0);
assert(!(lfs.flags & LFS_I_MKCONSISTENT)); assert(!(lfs.flags & LFS_I_MKCONSISTENT));
// which means there shouldn't be that many files left // which means there shouldn't be that many files left
@@ -7089,8 +7089,8 @@ code = '''
lfsr_traversal_close(&lfs, &t) => 0; lfsr_traversal_close(&lfs, &t) => 0;
// we should have cleaned up all grms/orphans // we should have cleaned up all grms/orphans
assert(lfs.grm.mids[0] == -1); assert(lfs.grm.queue[0] == 0);
assert(lfs.grm.mids[1] == -1); assert(lfs.grm.queue[1] == 0);
assert(!(lfs.flags & LFS_I_MKCONSISTENT)); assert(!(lfs.flags & LFS_I_MKCONSISTENT));
// which means there shouldn't be that many files left // which means there shouldn't be that many files left
@@ -7256,8 +7256,8 @@ code = '''
lfsr_traversal_close(&lfs, &t) => 0; lfsr_traversal_close(&lfs, &t) => 0;
// we should have cleaned up all grms/orphans // we should have cleaned up all grms/orphans
assert(lfs.grm.mids[0] == -1); assert(lfs.grm.queue[0] == 0);
assert(lfs.grm.mids[1] == -1); assert(lfs.grm.queue[1] == 0);
assert(!(lfs.flags & LFS_I_MKCONSISTENT)); assert(!(lfs.flags & LFS_I_MKCONSISTENT));
// which means there shouldn't be that many files left // which means there shouldn't be that many files left
@@ -7421,8 +7421,8 @@ code = '''
lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT; lfsr_traversal_read(&lfs, &t, &tinfo) => LFS_ERR_NOENT;
// we should have cleaned up all grms/orphans // we should have cleaned up all grms/orphans
assert(lfs.grm.mids[0] == -1); assert(lfs.grm.queue[0] == 0);
assert(lfs.grm.mids[1] == -1); assert(lfs.grm.queue[1] == 0);
assert(!(lfs.flags & LFS_I_MKCONSISTENT)); assert(!(lfs.flags & LFS_I_MKCONSISTENT));
// which means there shouldn't be that many files left // which means there shouldn't be that many files left
@@ -7614,8 +7614,8 @@ code = '''
lfsr_traversal_close(&lfs, &t) => 0; lfsr_traversal_close(&lfs, &t) => 0;
// we should be able to clean up grms // we should be able to clean up grms
assert(lfs.grm.mids[0] == -1); assert(lfs.grm.queue[0] == 0);
assert(lfs.grm.mids[1] == -1); assert(lfs.grm.queue[1] == 0);
// if we introduce actual orphans, me _must not_ clear the orphan flag // if we introduce actual orphans, me _must not_ clear the orphan flag
if (ORPHANS >= 3) { if (ORPHANS >= 3) {
assert(lfs.flags & LFS_I_MKCONSISTENT); assert(lfs.flags & LFS_I_MKCONSISTENT);