From c00e0b2af6477c791fd84501e9b8164b090d2fab Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Tue, 20 Aug 2024 01:26:32 -0500 Subject: [PATCH] Fixed explicit trunks messing with canonical checksums Updating the canonical checksum should only depend on if the tag is a trunkish tag (not a checksum tag), and not if the tag is in the current trunk. The trunk parameter to lfsr_rbyd_fetch should have no effect on the canonical checksum. Fixed in boath lfsr_rbyd_fetch and scripts. Curiously no code changes: code stack before: 36416 2616 after: 36416 (+0.0%) 2616 (+0.0% --- lfs.c | 66 +++++++++++++++++++++++---------------------- scripts/dbgbmap.py | 51 ++++++++++++++++++----------------- scripts/dbgbtree.py | 51 ++++++++++++++++++----------------- scripts/dbglfs.py | 51 ++++++++++++++++++----------------- scripts/dbgmtree.py | 51 ++++++++++++++++++----------------- scripts/dbgrbyd.py | 56 +++++++++++++++++++------------------- 6 files changed, 167 insertions(+), 159 deletions(-) diff --git a/lfs.c b/lfs.c index 9ac5bb8c..e6bcb763 100644 --- a/lfs.c +++ b/lfs.c @@ -3066,40 +3066,42 @@ static int lfsr_rbyd_fetch(lfs_t *lfs, lfsr_rbyd_t *rbyd, } } - // found a trunk of a tree? - if (lfsr_tag_istrunk(tag) - && (!trunk || off <= trunk || trunk__)) { - // start of trunk? - if (!trunk__) { - // keep track of trunk's entry point - trunk__ = off; - // reset weight - weight_ = 0; - } - - // derive weight of the tree from alt pointers - // - // NOTE we can't check for overflow/underflow here because we - // may be overeagerly parsing an invalid commit, it's ok for - // this to overflow/underflow as long as we throw it out later - // on a bad cksum - weight_ += weight__; - - // end of trunk? - if (!lfsr_tag_isalt(tag)) { - // update canonical checksum, xoring out any perturb - // state, we don't want erased-state affecting our - // canonical checksum - cksum = cksum_ ^ ((lfsr_rbyd_isperturb(rbyd)) - ? LFS_CRC32C_ODDZERO - : LFS_CRC32C_EVENZERO); - // update trunk and weight, unless we are a shrub trunk - if (!lfsr_tag_isshrub(tag) || trunk__ == trunk) { - trunk_ = trunk__; - weight = weight_; + // found a trunk? + if (lfsr_tag_istrunk(tag)) { + if (!(trunk && off > trunk && !trunk__)) { + // start of trunk? + if (!trunk__) { + // keep track of trunk's entry point + trunk__ = off; + // reset weight + weight_ = 0; + } + + // derive weight of the tree from alt pointers + // + // NOTE we can't check for overflow/underflow here because we + // may be overeagerly parsing an invalid commit, it's ok for + // this to overflow/underflow as long as we throw it out later + // on a bad cksum + weight_ += weight__; + + // end of trunk? + if (!lfsr_tag_isalt(tag)) { + // update trunk and weight, unless we are a shrub trunk + if (!lfsr_tag_isshrub(tag) || trunk__ == trunk) { + trunk_ = trunk__; + weight = weight_; + } + trunk__ = 0; } - trunk__ = 0; } + + // update canonical checksum, xoring out any perturb + // state, we don't want erased-state affecting our + // canonical checksum + cksum = cksum_ ^ ((lfsr_rbyd_isperturb(rbyd)) + ? LFS_CRC32C_ODDZERO + : LFS_CRC32C_EVENZERO); } // skip data diff --git a/scripts/dbgbmap.py b/scripts/dbgbmap.py index da51a3c0..a5e0f28e 100755 --- a/scripts/dbgbmap.py +++ b/scripts/dbgbmap.py @@ -695,33 +695,34 @@ class Rbyd: cksum__ = cksum_ ^ (0xfca42daf if perturb else 0) # evaluate trunks - if (tag & 0xf000) != TAG_CKSUM and ( - not trunk or j_-d <= trunk or trunk___): - # new trunk? - if not trunk___: - trunk___ = j_-d - weight__ = 0 + if (tag & 0xf000) != TAG_CKSUM: + if not (trunk and j_-d > trunk and not trunk___): + # new trunk? + if not trunk___: + trunk___ = j_-d + weight__ = 0 - # keep track of weight - weight__ += w + # keep track of weight + weight__ += w - # end of trunk? - if not tag & TAG_ALT: - # update canonical checksum, xoring out any perturb state - cksum_ = cksum__ ^ (0xfca42daf if perturb else 0) - # update trunk/weight unless we found a shrub or an - # explicit trunk (which may be a shrub) is requested - if not tag & TAG_SHRUB or trunk___ == trunk: - trunk__ = trunk___ - weight_ = weight__ - # keep track of eoff for best matching trunk - if trunk and j_ + size > trunk: - eoff_ = j_ + size - eoff = eoff_ - cksum = cksum_ - trunk_ = trunk__ - weight = weight_ - trunk___ = 0 + # end of trunk? + if not tag & TAG_ALT: + # update trunk/weight unless we found a shrub or an + # explicit trunk (which may be a shrub) is requested + if not tag & TAG_SHRUB or trunk___ == trunk: + trunk__ = trunk___ + weight_ = weight__ + # keep track of eoff for best matching trunk + if trunk and j_ + size > trunk: + eoff_ = j_ + size + eoff = eoff_ + cksum = cksum_ + trunk_ = trunk__ + weight = weight_ + trunk___ = 0 + + # update canonical checksum, xoring out any perturb state + cksum_ = cksum__ ^ (0xfca42daf if perturb else 0) if not tag & TAG_ALT: j_ += size diff --git a/scripts/dbgbtree.py b/scripts/dbgbtree.py index dddb7bca..34c6e774 100755 --- a/scripts/dbgbtree.py +++ b/scripts/dbgbtree.py @@ -368,33 +368,34 @@ class Rbyd: cksum__ = cksum_ ^ (0xfca42daf if perturb else 0) # evaluate trunks - if (tag & 0xf000) != TAG_CKSUM and ( - not trunk or j_-d <= trunk or trunk___): - # new trunk? - if not trunk___: - trunk___ = j_-d - weight__ = 0 + if (tag & 0xf000) != TAG_CKSUM: + if not (trunk and j_-d > trunk and not trunk___): + # new trunk? + if not trunk___: + trunk___ = j_-d + weight__ = 0 - # keep track of weight - weight__ += w + # keep track of weight + weight__ += w - # end of trunk? - if not tag & TAG_ALT: - # update canonical checksum, xoring out any perturb state - cksum_ = cksum__ ^ (0xfca42daf if perturb else 0) - # update trunk/weight unless we found a shrub or an - # explicit trunk (which may be a shrub) is requested - if not tag & TAG_SHRUB or trunk___ == trunk: - trunk__ = trunk___ - weight_ = weight__ - # keep track of eoff for best matching trunk - if trunk and j_ + size > trunk: - eoff_ = j_ + size - eoff = eoff_ - cksum = cksum_ - trunk_ = trunk__ - weight = weight_ - trunk___ = 0 + # end of trunk? + if not tag & TAG_ALT: + # update trunk/weight unless we found a shrub or an + # explicit trunk (which may be a shrub) is requested + if not tag & TAG_SHRUB or trunk___ == trunk: + trunk__ = trunk___ + weight_ = weight__ + # keep track of eoff for best matching trunk + if trunk and j_ + size > trunk: + eoff_ = j_ + size + eoff = eoff_ + cksum = cksum_ + trunk_ = trunk__ + weight = weight_ + trunk___ = 0 + + # update canonical checksum, xoring out any perturb state + cksum_ = cksum__ ^ (0xfca42daf if perturb else 0) if not tag & TAG_ALT: j_ += size diff --git a/scripts/dbglfs.py b/scripts/dbglfs.py index 126ebde0..334ef803 100755 --- a/scripts/dbglfs.py +++ b/scripts/dbglfs.py @@ -399,33 +399,34 @@ class Rbyd: cksum__ = cksum_ ^ (0xfca42daf if perturb else 0) # evaluate trunks - if (tag & 0xf000) != TAG_CKSUM and ( - not trunk or j_-d <= trunk or trunk___): - # new trunk? - if not trunk___: - trunk___ = j_-d - weight__ = 0 + if (tag & 0xf000) != TAG_CKSUM: + if not (trunk and j_-d > trunk and not trunk___): + # new trunk? + if not trunk___: + trunk___ = j_-d + weight__ = 0 - # keep track of weight - weight__ += w + # keep track of weight + weight__ += w - # end of trunk? - if not tag & TAG_ALT: - # update canonical checksum, xoring out any perturb state - cksum_ = cksum__ ^ (0xfca42daf if perturb else 0) - # update trunk/weight unless we found a shrub or an - # explicit trunk (which may be a shrub) is requested - if not tag & TAG_SHRUB or trunk___ == trunk: - trunk__ = trunk___ - weight_ = weight__ - # keep track of eoff for best matching trunk - if trunk and j_ + size > trunk: - eoff_ = j_ + size - eoff = eoff_ - cksum = cksum_ - trunk_ = trunk__ - weight = weight_ - trunk___ = 0 + # end of trunk? + if not tag & TAG_ALT: + # update trunk/weight unless we found a shrub or an + # explicit trunk (which may be a shrub) is requested + if not tag & TAG_SHRUB or trunk___ == trunk: + trunk__ = trunk___ + weight_ = weight__ + # keep track of eoff for best matching trunk + if trunk and j_ + size > trunk: + eoff_ = j_ + size + eoff = eoff_ + cksum = cksum_ + trunk_ = trunk__ + weight = weight_ + trunk___ = 0 + + # update canonical checksum, xoring out any perturb state + cksum_ = cksum__ ^ (0xfca42daf if perturb else 0) if not tag & TAG_ALT: j_ += size diff --git a/scripts/dbgmtree.py b/scripts/dbgmtree.py index 8103d2d4..6accfee4 100755 --- a/scripts/dbgmtree.py +++ b/scripts/dbgmtree.py @@ -383,33 +383,34 @@ class Rbyd: cksum__ = cksum_ ^ (0xfca42daf if perturb else 0) # evaluate trunks - if (tag & 0xf000) != TAG_CKSUM and ( - not trunk or j_-d <= trunk or trunk___): - # new trunk? - if not trunk___: - trunk___ = j_-d - weight__ = 0 + if (tag & 0xf000) != TAG_CKSUM: + if not (trunk and j_-d > trunk and not trunk___): + # new trunk? + if not trunk___: + trunk___ = j_-d + weight__ = 0 - # keep track of weight - weight__ += w + # keep track of weight + weight__ += w - # end of trunk? - if not tag & TAG_ALT: - # update canonical checksum, xoring out any perturb state - cksum_ = cksum__ ^ (0xfca42daf if perturb else 0) - # update trunk/weight unless we found a shrub or an - # explicit trunk (which may be a shrub) is requested - if not tag & TAG_SHRUB or trunk___ == trunk: - trunk__ = trunk___ - weight_ = weight__ - # keep track of eoff for best matching trunk - if trunk and j_ + size > trunk: - eoff_ = j_ + size - eoff = eoff_ - cksum = cksum_ - trunk_ = trunk__ - weight = weight_ - trunk___ = 0 + # end of trunk? + if not tag & TAG_ALT: + # update trunk/weight unless we found a shrub or an + # explicit trunk (which may be a shrub) is requested + if not tag & TAG_SHRUB or trunk___ == trunk: + trunk__ = trunk___ + weight_ = weight__ + # keep track of eoff for best matching trunk + if trunk and j_ + size > trunk: + eoff_ = j_ + size + eoff = eoff_ + cksum = cksum_ + trunk_ = trunk__ + weight = weight_ + trunk___ = 0 + + # update canonical checksum, xoring out any perturb state + cksum_ = cksum__ ^ (0xfca42daf if perturb else 0) if not tag & TAG_ALT: j_ += size diff --git a/scripts/dbgrbyd.py b/scripts/dbgrbyd.py index 4134b048..01501c71 100755 --- a/scripts/dbgrbyd.py +++ b/scripts/dbgrbyd.py @@ -577,12 +577,13 @@ def dbg_log(data, block_size, rev, eoff, weight, *, # end of trunk? if not tag & TAG_ALT: - # update canonical checksum, xoring out any perturb state - cksum = cksum_ ^ (0xfca42daf if perturb else 0) # derive the current tag's rid from alt weights rid = lower_ + w-1 trunk_ = 0 + # update canonical checksum, xoring out any perturb state + cksum = cksum_ ^ (0xfca42daf if perturb else 0) + # show human-readable tag representation print('%s%08x:%s %*s%s%*s %-*s%s%s%s' % ( '\x1b[90m' if color and j >= eoff else '', @@ -976,33 +977,34 @@ def main(disk, blocks=None, *, cksum__ = cksum_ ^ (0xfca42daf if perturb else 0) # evaluate trunks - if (tag & 0xf000) != TAG_CKSUM and ( - not trunk or j_-d <= trunk or trunk___): - # new trunk? - if not trunk___: - trunk___ = j_-d - weight__ = 0 + if (tag & 0xf000) != TAG_CKSUM: + if not (trunk and j_-d > trunk and not trunk___): + # new trunk? + if not trunk___: + trunk___ = j_-d + weight__ = 0 - # keep track of weight - weight__ += w + # keep track of weight + weight__ += w - # end of trunk? - if not tag & TAG_ALT: - # update canonical checksum, xoring out any perturb state - cksum_ = cksum__ ^ (0xfca42daf if perturb else 0) - # update trunk/weight unless we found a shrub or an - # explicit trunk (which may be a shrub) is requested - if not tag & TAG_SHRUB or trunk___ == trunk: - trunk__ = trunk___ - weight_ = weight__ - # keep track of eoff for best matching trunk - if trunk and j_ + size > trunk: - eoff_ = j_ + size - eoff = eoff_ - cksum = cksum_ - trunk_ = trunk__ - weight = weight_ - trunk___ = 0 + # end of trunk? + if not tag & TAG_ALT: + # update trunk/weight unless we found a shrub or an + # explicit trunk (which may be a shrub) is requested + if not tag & TAG_SHRUB or trunk___ == trunk: + trunk__ = trunk___ + weight_ = weight__ + # keep track of eoff for best matching trunk + if trunk and j_ + size > trunk: + eoff_ = j_ + size + eoff = eoff_ + cksum = cksum_ + trunk_ = trunk__ + weight = weight_ + trunk___ = 0 + + # update canonical checksum, xoring out any perturb state + cksum_ = cksum__ ^ (0xfca42daf if perturb else 0) if not tag & TAG_ALT: j_ += size