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:
@@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user