Skip to content

Commit 1f3c47b

Browse files
committed
Moved revision count noise behind ifdef LFS_NOISY
littlefs is intentionally designed to not rely on noise, even with cksum collisions (hello, perturb bit!). So it makes sense for this to be an optional feature, even if it's a small one. Disabling revision count noise by default also helps with testing. The whole point of revision count noise is to make cksum collisions less likely, which is a bit counterproductive when that's something we want to test! This doesn't really change the revision count encoding: vvvvrrrr rrrrrrnn nnnnnnnn nnnnnnnn '-.''----.----''---------.--------' '------|---------------|---------- 4-bit relocation revision '---------------|---------- recycle-bits recycle counter '---------- pseudorandom noise (optional) I considered moving the recycle-bits down when we're not adding noise, but the extra logic just isn't worth making the revision count a bit more human-readable. --- This saves a small bit of code in the default build, at the cost of some code for the runtime checks in the LFS_NOISY build. Though I'm hoping future config work will let users opt-out of these runtime checks: code stack ctx before: 38548 2624 640 default after: 38508 (-0.1%) 2624 (+0.0%) 640 (+0.0%) LFS_NOISY after: 38568 (+0.1%) 2624 (+0.0%) 640 (+0.0%) Honestly the thing I'm more worried about is using one of our precious mount flags for this... There's not that many bits left!
1 parent 6fb9211 commit 1f3c47b

File tree

6 files changed

+193
-138
lines changed

6 files changed

+193
-138
lines changed

lfs.c

+26-10
Original file line numberDiff line numberDiff line change
@@ -6888,6 +6888,12 @@ static inline bool lfsr_m_isrdonly(uint32_t flags) {
68886888
return flags & LFS_M_RDONLY;
68896889
}
68906890

6891+
#ifdef LFS_NOISY
6892+
static inline bool lfsr_m_isnoisy(uint32_t flags) {
6893+
return flags & LFS_M_NOISY;
6894+
}
6895+
#endif
6896+
68916897
#ifdef LFS_CKPROGS
68926898
static inline bool lfsr_m_isckprogs(uint32_t flags) {
68936899
return flags & LFS_M_CKPROGS;
@@ -7198,15 +7204,20 @@ static int lfsr_fs_consumegdelta(lfs_t *lfs, const lfsr_mdir_t *mdir) {
71987204
// '-.''----.----''---------.--------'
71997205
// '------|---------------|---------- 4-bit relocation revision
72007206
// '---------------|---------- recycle-bits recycle counter
7201-
// '---------- pseudorandom nonce
7207+
// '---------- pseudorandom noise (optional)
72027208

72037209
static inline uint32_t lfsr_rev_init(lfs_t *lfs, uint32_t rev) {
7210+
(void)lfs;
72047211
// we really only care about the top revision bits here
72057212
rev &= ~((1 << 28)-1);
72067213
// increment revision
72077214
rev += 1 << 28;
7208-
// xor in a pseudorandom nonce
7209-
rev ^= ((1 << (28-lfs_smax(lfs->recycle_bits, 0)))-1) & lfs->gcksum;
7215+
// xor in pseudorandom noise
7216+
#ifdef LFS_NOISY
7217+
if (lfsr_m_isnoisy(lfs->flags)) {
7218+
rev ^= ((1 << (28-lfs_smax(lfs->recycle_bits, 0)))-1) & lfs->gcksum;
7219+
}
7220+
#endif
72107221
return rev;
72117222
}
72127223

@@ -7223,8 +7234,12 @@ static inline bool lfsr_rev_needsrelocation(lfs_t *lfs, uint32_t rev) {
72237234
static inline uint32_t lfsr_rev_inc(lfs_t *lfs, uint32_t rev) {
72247235
// increment recycle counter/revision
72257236
rev += 1 << (28-lfs_smax(lfs->recycle_bits, 0));
7226-
// xor in a pseudorandom nonce
7227-
rev ^= ((1 << (28-lfs_smax(lfs->recycle_bits, 0)))-1) & lfs->gcksum;
7237+
// xor in pseudorandom noise
7238+
#ifdef LFS_NOISY
7239+
if (lfsr_m_isnoisy(lfs->flags)) {
7240+
rev ^= ((1 << (28-lfs_smax(lfs->recycle_bits, 0)))-1) & lfs->gcksum;
7241+
}
7242+
#endif
72287243
return rev;
72297244
}
72307245

@@ -13421,6 +13436,7 @@ static int lfs_init(lfs_t *lfs, uint32_t flags,
1342113436
| LFS_M_RDONLY
1342213437
| LFS_M_FLUSH
1342313438
| LFS_M_SYNC
13439+
| LFS_IFDEF_NOISY(LFS_M_NOISY, 0)
1342413440
| LFS_IFDEF_CKPROGS(LFS_M_CKPROGS, 0)
1342513441
| LFS_IFDEF_CKFETCHES(LFS_M_CKFETCHES, 0)
1342613442
| LFS_IFDEF_CKPARITY(LFS_M_CKPARITY, 0)
@@ -14249,6 +14265,7 @@ int lfsr_mount(lfs_t *lfs, uint32_t flags,
1424914265
| LFS_M_RDONLY
1425014266
| LFS_M_FLUSH
1425114267
| LFS_M_SYNC
14268+
| LFS_IFDEF_NOISY(LFS_M_NOISY, 0)
1425214269
| LFS_IFDEF_CKPROGS(LFS_M_CKPROGS, 0)
1425314270
| LFS_IFDEF_CKFETCHES(LFS_M_CKFETCHES, 0)
1425414271
| LFS_IFDEF_CKPARITY(LFS_M_CKPARITY, 0)
@@ -14262,16 +14279,14 @@ int lfsr_mount(lfs_t *lfs, uint32_t flags,
1426214279
LFS_ASSERT(!lfsr_m_isrdonly(flags) || !lfsr_t_ismkconsistent(flags));
1426314280
LFS_ASSERT(!lfsr_m_isrdonly(flags) || !lfsr_t_islookahead(flags));
1426414281
LFS_ASSERT(!lfsr_m_isrdonly(flags) || !lfsr_t_iscompact(flags));
14265-
// some flags don't make sense when only traversing the mtree
14266-
LFS_ASSERT(!lfsr_t_ismtreeonly(flags) || !lfsr_t_islookahead(flags));
14267-
LFS_ASSERT(!lfsr_t_ismtreeonly(flags) || !lfsr_t_isckdata(flags));
1426814282

1426914283
int err = lfs_init(lfs,
1427014284
flags & (
1427114285
LFS_M_RDWR
1427214286
| LFS_M_RDONLY
1427314287
| LFS_M_FLUSH
1427414288
| LFS_M_SYNC
14289+
| LFS_IFDEF_NOISY(LFS_M_NOISY, 0)
1427514290
| LFS_IFDEF_CKPROGS(LFS_M_CKPROGS, 0)
1427614291
| LFS_IFDEF_CKFETCHES(LFS_M_CKFETCHES, 0)
1427714292
| LFS_IFDEF_CKPARITY(LFS_M_CKPARITY, 0)
@@ -14441,18 +14456,18 @@ int lfsr_format(lfs_t *lfs, uint32_t flags,
1444114456
// unknown flags?
1444214457
LFS_ASSERT((flags & ~(
1444314458
LFS_F_RDWR
14459+
| LFS_IFDEF_NOISY(LFS_F_NOISY, 0)
1444414460
| LFS_IFDEF_CKPROGS(LFS_F_CKPROGS, 0)
1444514461
| LFS_IFDEF_CKFETCHES(LFS_F_CKFETCHES, 0)
1444614462
| LFS_IFDEF_CKPARITY(LFS_F_CKPARITY, 0)
1444714463
| LFS_IFDEF_CKDATACKSUMS(LFS_F_CKDATACKSUMS, 0)
1444814464
| LFS_F_CKMETA
1444914465
| LFS_F_CKDATA)) == 0);
14450-
// some flags don't make sense when only traversing the mtree
14451-
LFS_ASSERT(!lfsr_t_ismtreeonly(flags) || !lfsr_t_isckdata(flags));
1445214466

1445314467
int err = lfs_init(lfs,
1445414468
flags & (
1445514469
LFS_F_RDWR
14470+
| LFS_IFDEF_NOISY(LFS_F_NOISY, 0)
1445614471
| LFS_IFDEF_CKPROGS(LFS_F_CKPROGS, 0)
1445714472
| LFS_IFDEF_CKFETCHES(LFS_F_CKFETCHES, 0)
1445814473
| LFS_IFDEF_CKPARITY(LFS_F_CKPARITY, 0)
@@ -14512,6 +14527,7 @@ int lfsr_fs_stat(lfs_t *lfs, struct lfs_fsinfo *fsinfo) {
1451214527
LFS_I_RDONLY
1451314528
| LFS_I_FLUSH
1451414529
| LFS_I_SYNC
14530+
| LFS_IFDEF_NOISY(LFS_I_NOISY, 0)
1451514531
| LFS_IFDEF_CKPROGS(LFS_I_CKPROGS, 0)
1451614532
| LFS_IFDEF_CKFETCHES(LFS_I_CKFETCHES, 0)
1451714533
| LFS_IFDEF_CKPARITY(LFS_I_CKPARITY, 0)

lfs.h

+9
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,9 @@ enum lfs_type {
162162
// Filesystem format flags
163163
#define LFS_F_MODE 1 // Format's access mode
164164
#define LFS_F_RDWR 0 // Format the filesystem as read and write
165+
#ifdef LFS_NOISY
166+
#define LFS_F_NOISY 0x00000010 // Add noise to revision counts
167+
#endif
165168
#ifdef LFS_CKPROGS
166169
#define LFS_F_CKPROGS 0x00000800 // Check progs by reading back progged data
167170
#endif
@@ -185,6 +188,9 @@ enum lfs_type {
185188
#define LFS_M_RDONLY 1 // Mount the filesystem as read only
186189
#define LFS_M_FLUSH 0x00000040 // Open all files with LFS_O_FLUSH
187190
#define LFS_M_SYNC 0x00000080 // Open all files with LFS_O_SYNC
191+
#ifdef LFS_NOISY
192+
#define LFS_M_NOISY 0x00000010 // Add noise to revision counts
193+
#endif
188194
#ifdef LFS_CKPROGS
189195
#define LFS_M_CKPROGS 0x00000800 // Check progs by reading back progged data
190196
#endif
@@ -210,6 +216,9 @@ enum lfs_type {
210216
#define LFS_I_RDONLY 0x00000001 // Mounted read only
211217
#define LFS_I_FLUSH 0x00000040 // Mounted with LFS_M_FLUSH
212218
#define LFS_I_SYNC 0x00000080 // Mounted with LFS_M_SYNC
219+
#ifdef LFS_NOISY
220+
#define LFS_I_NOISY 0x00000010 // Mounted with LFS_M_NOISY
221+
#endif
213222
#ifdef LFS_CKPROGS
214223
#define LFS_I_CKPROGS 0x00000800 // Mounted with LFS_M_CKPROGS
215224
#endif

lfs_util.h

+9
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626

2727
// LFS_BIGGEST enables all opt-in features
2828
#ifdef LFS_BIGGEST
29+
#ifndef LFS_NOISY
30+
#define LFS_NOISY
31+
#endif
2932
#ifndef LFS_CKPROGS
3033
#define LFS_CKPROGS
3134
#endif
@@ -189,6 +192,12 @@ extern "C"
189192

190193

191194
// Some ifdef conveniences
195+
#ifdef LFS_NOISY
196+
#define LFS_IFDEF_NOISY(a, b) (a)
197+
#else
198+
#define LFS_IFDEF_NOISY(a, b) (b)
199+
#endif
200+
192201
#ifdef LFS_CKPROGS
193202
#define LFS_IFDEF_CKPROGS(a, b) (a)
194203
#else

scripts/dbgflags.py

+3
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
# Filesystem format flags
5858
('F', 'MODE', 1, "Format's access mode" ),
5959
('^', 'RDWR', 0, "Format the filesystem as read and write" ),
60+
('F', 'NOISY', 0x00000010, "Add noise to revision counts" ),
6061
('F', 'CKPROGS', 0x00000800, "Check progs by reading back progged data" ),
6162
('F', 'CKFETCHES', 0x00001000, "Check block checksums before first use" ),
6263
('F', 'CKPARITY', 0x00002000, "Check metadata tag parity bits" ),
@@ -72,6 +73,7 @@
7273
('^', 'RDONLY', 1, "Mount the filesystem as read only" ),
7374
('M', 'FLUSH', 0x00000040, "Open all files with LFS_O_FLUSH" ),
7475
('M', 'SYNC', 0x00000080, "Open all files with LFS_O_SYNC" ),
76+
('M', 'NOISY', 0x00000010, "Add noise to revision counts" ),
7577
('M', 'CKPROGS', 0x00000800, "Check progs by reading back progged data" ),
7678
('M', 'CKFETCHES', 0x00001000, "Check block checksums before first use" ),
7779
('M', 'CKPARITY', 0x00002000, "Check metadata tag parity bits" ),
@@ -97,6 +99,7 @@
9799
('I', 'RDONLY', 0x00000001, "Mounted read only" ),
98100
('I', 'FLUSH', 0x00000040, "Mounted with LFS_M_FLUSH" ),
99101
('I', 'SYNC', 0x00000080, "Mounted with LFS_M_SYNC" ),
102+
('I', 'NOISY', 0x00000010, "Mounted with LFS_M_NOISY" ),
100103
('I', 'CKPROGS', 0x00000800, "Mounted with LFS_M_CKPROGS" ),
101104
('I', 'CKFETCHES', 0x00001000, "Mounted with LFS_M_CKFETCHES" ),
102105
('I', 'CKPARITY', 0x00002000, "Mounted with LFS_M_CKPARITY" ),

tests/test_mount.toml

+7
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ code = '''
1717
defines.RDONLY = [false, true]
1818
defines.FLUSH = [false, true]
1919
defines.SYNC = [false, true]
20+
defines.NOISY = [false, true]
2021
defines.CKPROGS = [false, true]
2122
defines.CKFETCHES = [false, true]
2223
defines.CKPARITY = [false, true]
@@ -27,6 +28,7 @@ defines.COMPACT = [false, true]
2728
defines.CKMETA = [false, true]
2829
defines.CKDATA = [false, true]
2930
if = [
31+
'LFS_IFDEF_NOISY(true, !NOISY)',
3032
'LFS_IFDEF_CKPROGS(true, !CKPROGS)',
3133
'LFS_IFDEF_CKFETCHES(true, !CKFETCHES)',
3234
'LFS_IFDEF_CKPARITY(true, !CKPARITY)',
@@ -42,6 +44,7 @@ code = '''
4244
((RDONLY) ? LFS_M_RDONLY : LFS_M_RDWR)
4345
| ((FLUSH) ? LFS_M_FLUSH : 0)
4446
| ((SYNC) ? LFS_M_SYNC : 0)
47+
| ((NOISY) ? LFS_IFDEF_NOISY(LFS_M_NOISY, -1) : 0)
4548
| ((CKPROGS) ? LFS_IFDEF_CKPROGS(LFS_M_CKPROGS, -1) : 0)
4649
| ((CKFETCHES) ? LFS_IFDEF_CKFETCHES(LFS_M_CKFETCHES, -1) : 0)
4750
| ((CKPARITY) ? LFS_IFDEF_CKPARITY(LFS_M_CKPARITY, -1) : 0)
@@ -62,6 +65,7 @@ code = '''
6265
((RDONLY) ? LFS_I_RDONLY : 0)
6366
| ((FLUSH) ? LFS_I_FLUSH : 0)
6467
| ((SYNC) ? LFS_I_SYNC : 0)
68+
| ((NOISY) ? LFS_IFDEF_NOISY(LFS_M_NOISY, -1) : 0)
6569
| ((CKPROGS) ? LFS_IFDEF_CKPROGS(LFS_I_CKPROGS, -1) : 0)
6670
| ((CKFETCHES) ? LFS_IFDEF_CKFETCHES(LFS_I_CKFETCHES, -1) : 0)
6771
| ((CKPARITY) ? LFS_IFDEF_CKPARITY(LFS_I_CKPARITY, -1) : 0)
@@ -82,13 +86,15 @@ code = '''
8286
#
8387
# these end up passed to mount internally
8488
[cases.test_mount_format_flags]
89+
defines.NOISY = [false, true]
8590
defines.CKPROGS = [false, true]
8691
defines.CKFETCHES = [false, true]
8792
defines.CKPARITY = [false, true]
8893
defines.CKDATACKSUMS = [false, true]
8994
defines.CKMETA = [false, true]
9095
defines.CKDATA = [false, true]
9196
if = [
97+
'LFS_IFDEF_NOISY(true, !NOISY)',
9298
'LFS_IFDEF_CKPROGS(true, !CKPROGS)',
9399
'LFS_IFDEF_CKFETCHES(true, !CKFETCHES)',
94100
'LFS_IFDEF_CKPARITY(true, !CKPARITY)',
@@ -98,6 +104,7 @@ code = '''
98104
lfs_t lfs;
99105
lfsr_format(&lfs,
100106
LFS_F_RDWR
107+
| ((NOISY) ? LFS_IFDEF_NOISY(LFS_F_NOISY, -1) : 0)
101108
| ((CKPROGS) ? LFS_IFDEF_CKPROGS(LFS_F_CKPROGS, -1) : 0)
102109
| ((CKFETCHES) ? LFS_IFDEF_CKFETCHES(LFS_F_CKFETCHES, -1) : 0)
103110
| ((CKPARITY) ? LFS_IFDEF_CKPARITY(LFS_F_CKPARITY, -1) : 0)

0 commit comments

Comments
 (0)