Some small tweaks to mdir comparison functions

- lfsr_mid_cmp no longer uses a union. This was undefined behavior and
  the lfsr_mid_t type isn't word aligned, so this could break pretty badly
  on machine/compiler change.

  Also dropped ordering based on endianness, since we need to marshal
  these into an int for the comparison anyways.

- Changed lfsr_mdir_cmp to use min/max functions as part of the
  comparison. The result is also "ordered" now, though the ordering
  is nonsensical. I guess the mrootanchor is less than all other mdirs?

  Also considered only comparing a single min/max block, since it would
  be an error for mdirs to share blocks, but note we rely on
  lfsr_mdir_cmp to check for relocations in lfsr_mdir_commit. These
  relocations can end up being partial in the case of bad block
  detection.
This commit is contained in:
Christopher Haster
2023-08-10 12:34:38 -05:00
parent 571be807dc
commit 0449b06506
2 changed files with 8 additions and 13 deletions
+8 -8
View File
@@ -1564,9 +1564,9 @@ static int lfsr_data_readecksum(lfs_t *lfs, lfsr_data_t *data,
#define LFSR_MID(_bid, _rid) ((lfsr_mid_t){.bid=_bid, .rid=_rid})
static inline int lfsr_mid_cmp(lfsr_mid_t a, lfsr_mid_t b) {
union { lfsr_mid_t mid; lfs_ssize_t w; } a_u = {.mid=a};
union { lfsr_mid_t mid; lfs_ssize_t w; } b_u = {.mid=b};
return a_u.w - b_u.w;
int32_t a_w = ((int32_t)a.bid << 16) | (int32_t)a.rid;
int32_t b_w = ((int32_t)b.bid << 16) | (int32_t)b.rid;
return a_w - b_w;
}
// we use the root's bookmark at 0.0 to represent root
@@ -4984,12 +4984,12 @@ static int lfsr_btree_traversal_next(lfs_t *lfs,
static inline int lfsr_mdir_cmp(
const lfs_block_t a[static 2],
const lfs_block_t b[static 2]) {
// allow either order
if ((a[0] == b[0] && a[1] == b[1])
|| (a[0] == b[1] && a[1] == b[0])) {
return 0;
// note these can be in either order
int maxcmp = lfs_max32(a[0], a[1]) - lfs_max32(b[0], b[1]);
if (maxcmp != 0) {
return maxcmp;
} else {
return 1;
return lfs_min32(a[0], a[1]) - lfs_min32(b[0], b[1]);
}
}
-5
View File
@@ -53,13 +53,8 @@ typedef uint16_t lfsr_mrid_t;
typedef int16_t lfsr_smrid_t;
typedef struct lfsr_mid {
#ifdef LFS_BIG_ENDIAN
lfsr_smbid_t bid;
lfsr_smrid_t rid;
#else
lfsr_smrid_t rid;
lfsr_smbid_t bid;
#endif
} lfsr_mid_t;
// Maximum name size in bytes, may be redefined to reduce the size of the