Some small tweaks

- Updated LFSR_BTREE_INLINESIZE to properly include the overhead for
  mdir pointers, which need 2 block addresses instead of 1. This adds
  4 bytes to the lfsr_btree_t struct.

- Changed code that marks rbyds as "needing compaction" to use -1
  instead of block_size. This can use a cheaper constant and helps
  debugging.

- Changed the mid representation of root to 0.0 from ?.-1. The mid 0.0
  is always reserved for the roots dstart, so it shouldn't be used for
  any actual file. This disambiguates root vs special metadata mids and
  is a step towards making mids unsigned.

  It also saves a tiny bit of code since 0 comparisons are generally
  cheaper and we can leverage the order-preserving conversion of mid
  to an integer.
This commit is contained in:
Christopher Haster
2023-08-04 22:33:09 -05:00
parent da4e86abac
commit 3c42ed98a4
2 changed files with 35 additions and 19 deletions
+27 -12
View File
@@ -1532,6 +1532,17 @@ static lfs_ssize_t lfsr_fcrc_fromdisk(lfs_t *lfs, lfsr_fcrc_t *fcrc,
#define LFSR_MID(_bid, _rid) ((lfsr_mid_t){_bid, _rid}) #define LFSR_MID(_bid, _rid) ((lfsr_mid_t){_bid, _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;
}
// we use the root's dstart at 0.0 to represent root
static inline bool lfsr_mid_isroot(lfsr_mid_t mid) {
return lfsr_mid_cmp(mid, LFSR_MID(0, 0)) == 0;
}
/// Global-state things /// /// Global-state things ///
@@ -1947,7 +1958,7 @@ static int lfsr_rbyd_fetch(lfs_t *lfs, lfsr_rbyd_t *rbyd,
} }
if (!erased) { if (!erased) {
rbyd->off = lfs->cfg->block_size; rbyd->off = -1;
} }
return 0; return 0;
@@ -2098,7 +2109,7 @@ static int lfsr_rbyd_appendrev(lfs_t *lfs, lfsr_rbyd_t *rbyd, uint32_t rev) {
failed: failed:
// if we fail mark the rbyd as unerased and release the pcache // if we fail mark the rbyd as unerased and release the pcache
lfs_cache_zero(lfs, &lfs->pcache); lfs_cache_zero(lfs, &lfs->pcache);
rbyd->off = lfs->cfg->block_size; rbyd->off = -1;
return err; return err;
} }
@@ -2710,7 +2721,7 @@ leaf:;
failed:; failed:;
// if we fail mark the rbyd as unerased and release the pcache // if we fail mark the rbyd as unerased and release the pcache
lfs_cache_zero(lfs, &lfs->pcache); lfs_cache_zero(lfs, &lfs->pcache);
rbyd->off = lfs->cfg->block_size; rbyd->off = -1;
return err; return err;
} }
@@ -2993,7 +3004,7 @@ static int lfsr_rbyd_compact(lfs_t *lfs, lfsr_rbyd_t *rbyd,
failed:; failed:;
// if we fail mark the rbyd as unerased and release the pcache // if we fail mark the rbyd as unerased and release the pcache
lfs_cache_zero(lfs, &lfs->pcache); lfs_cache_zero(lfs, &lfs->pcache);
rbyd->off = lfs->cfg->block_size; rbyd->off = -1;
return err; return err;
#else #else
@@ -3095,7 +3106,7 @@ static int lfsr_rbyd_commit(lfs_t *lfs, lfsr_rbyd_t *rbyd,
int err = lfsr_bd_read(lfs, rbyd_.block, aligned, lfs->cfg->prog_size, int err = lfsr_bd_read(lfs, rbyd_.block, aligned, lfs->cfg->prog_size,
&perturb, 1); &perturb, 1);
if (err && err != LFS_ERR_CORRUPT) { if (err && err != LFS_ERR_CORRUPT) {
rbyd->off = lfs->cfg->block_size; rbyd->off = -1;
return err; return err;
} }
@@ -3204,7 +3215,7 @@ static int lfsr_rbyd_commit(lfs_t *lfs, lfsr_rbyd_t *rbyd,
failed:; failed:;
// if we fail mark the rbyd as unerased and release the pcache // if we fail mark the rbyd as unerased and release the pcache
lfs_cache_zero(lfs, &lfs->pcache); lfs_cache_zero(lfs, &lfs->pcache);
rbyd->off = lfs->cfg->block_size; rbyd->off = -1;
return err; return err;
} }
@@ -5119,7 +5130,7 @@ static int lfsr_mdir_alloc(lfs_t *lfs, lfsr_mdir_t *mdir, lfsr_mid_t mid) {
mdir->m.rbyd.weight = 0; mdir->m.rbyd.weight = 0;
mdir->m.rbyd.block = blocks[1]; mdir->m.rbyd.block = blocks[1];
// mark mdir as needing compaction // mark mdir as needing compaction
mdir->m.rbyd.off = lfs->cfg->block_size; mdir->m.rbyd.off = -1;
mdir->m.rbyd.trunk = 0; mdir->m.rbyd.trunk = 0;
return 0; return 0;
} }
@@ -6223,7 +6234,8 @@ static int lfsr_mtree_pathlookup(lfs_t *lfs, const char *path,
lfsr_mdir_t *mdir_, lfsr_tag_t *tag_, lfsr_mdir_t *mdir_, lfsr_tag_t *tag_,
lfs_size_t *did_, const char **name_, lfs_size_t *name_size_) { lfs_size_t *did_, const char **name_, lfs_size_t *name_size_) {
// setup root // setup root
lfsr_mdir_t mdir = {.mid.rid=-1}; lfsr_mdir_t mdir;
mdir.mid = LFSR_MID(0, 0);
lfsr_tag_t tag = LFSR_TAG_DIR; lfsr_tag_t tag = LFSR_TAG_DIR;
lfs_size_t did = LFSR_DID_ROOT; lfs_size_t did = LFSR_DID_ROOT;
@@ -6277,7 +6289,7 @@ static int lfsr_mtree_pathlookup(lfs_t *lfs, const char *path,
if (name[0] == '\0') { if (name[0] == '\0') {
// generally we don't allow operations that change our root, // generally we don't allow operations that change our root,
// report root as inval, but let upper layers intercept this // report root as inval, but let upper layers intercept this
if (mdir.mid.rid == -1) { if (lfsr_mid_isroot(mdir.mid)) {
return LFS_ERR_INVAL; return LFS_ERR_INVAL;
} }
return 0; return 0;
@@ -6289,7 +6301,7 @@ static int lfsr_mtree_pathlookup(lfs_t *lfs, const char *path,
} }
// read the next did from the mdir if this is not the root // read the next did from the mdir if this is not the root
if (mdir.mid.rid != -1) { if (!lfsr_mid_isroot(mdir.mid)) {
lfsr_data_t data; lfsr_data_t data;
int err = lfsr_mdir_lookup(lfs, &mdir, mdir.mid.rid, LFSR_TAG_DID, int err = lfsr_mdir_lookup(lfs, &mdir, mdir.mid.rid, LFSR_TAG_DID,
NULL, &data); NULL, &data);
@@ -7020,6 +7032,9 @@ static int lfsr_formatinited(lfs_t *lfs) {
return err; return err;
} }
// note the initial revision count is arbitrary, but we use
// -1 and 0 here to help test that our sequence comparison
// works correctly
err = lfsr_rbyd_appendrev(lfs, &rbyd, (uint32_t)i - 1); err = lfsr_rbyd_appendrev(lfs, &rbyd, (uint32_t)i - 1);
if (err) { if (err) {
return err; return err;
@@ -7223,7 +7238,7 @@ int lfsr_mkdir(lfs_t *lfs, const char *path) {
err = lfsr_mtree_pathlookup(lfs, path, err = lfsr_mtree_pathlookup(lfs, path,
&parent.mdir, NULL, &parent.mdir, NULL,
&parent_did, &name, &name_size); &parent_did, &name, &name_size);
if (err && (err != LFS_ERR_NOENT || parent.mdir.mid.rid == -1)) { if (err && (err != LFS_ERR_NOENT || lfsr_mid_isroot(parent.mdir.mid))) {
return err; return err;
} }
@@ -7450,7 +7465,7 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) {
err = lfsr_mtree_pathlookup(lfs, new_path, err = lfsr_mtree_pathlookup(lfs, new_path,
&new_mdir, &new_tag, &new_mdir, &new_tag,
&new_did, &new_name, &new_name_size); &new_did, &new_name, &new_name_size);
if (err && (err != LFS_ERR_NOENT || new_mdir.mid.rid == -1)) { if (err && (err != LFS_ERR_NOENT || lfsr_mid_isroot(new_mdir.mid))) {
return err; return err;
} }
bool exists = (err != LFS_ERR_NOENT); bool exists = (err != LFS_ERR_NOENT);
+8 -7
View File
@@ -52,6 +52,11 @@ typedef int16_t lfsr_smbid_t;
typedef uint16_t lfsr_mrid_t; typedef uint16_t lfsr_mrid_t;
typedef int16_t lfsr_smrid_t; typedef int16_t lfsr_smrid_t;
typedef struct lfsr_mid {
lfsr_smbid_t bid;
lfsr_smrid_t rid;
} lfsr_mid_t;
// Maximum name size in bytes, may be redefined to reduce the size of the // Maximum name size in bytes, may be redefined to reduce the size of the
// info struct. Limited to <= 1022. Stored in superblock and must be // info struct. Limited to <= 1022. Stored in superblock and must be
// respected by other littlefs drivers. // respected by other littlefs drivers.
@@ -342,8 +347,8 @@ typedef struct lfsr_rbyd {
// off=0, trunk=0 => not yet committed // off=0, trunk=0 => not yet committed
// off=0, trunk>0 => not yet fetched // off=0, trunk>0 => not yet fetched
// off=block_size => rbyd not erased/needs compaction // off=block_size => rbyd not erased/needs compaction
lfs_off_t off;
lfs_off_t trunk; lfs_off_t trunk;
lfs_off_t off;
uint32_t crc; uint32_t crc;
} lfsr_rbyd_t; } lfsr_rbyd_t;
@@ -353,7 +358,8 @@ typedef struct lfsr_rbyd {
// //
// Pointers we store: // Pointers we store:
// - block addresses => 1 leb128 => 5 bytes (worst case) // - block addresses => 1 leb128 => 5 bytes (worst case)
#define LFSR_BTREE_INLINESIZE 5 // - mdir addresses => 2 leb128 => 10 bytes (worst case)
#define LFSR_BTREE_INLINESIZE 10
typedef union lfsr_btree { typedef union lfsr_btree {
// note this lines up with weight in lfsr_rbyd_t // note this lines up with weight in lfsr_rbyd_t
@@ -373,11 +379,6 @@ typedef union lfsr_btree {
} inlined; } inlined;
} lfsr_btree_t; } lfsr_btree_t;
typedef struct lfsr_mid {
lfsr_smbid_t bid;
lfsr_smrid_t rid;
} lfsr_mid_t;
typedef struct lfsr_mdir { typedef struct lfsr_mdir {
lfsr_mid_t mid; lfsr_mid_t mid;
struct { struct {