mirror of
https://github.com/littlefs-project/littlefs.git
synced 2025-12-01 12:20:02 +00:00
trv: Reintroduced LFS3_T_EXCL
With the relaxation of traversal behavior under mutation, I think it
makes sense to bring back LFS3_T_EXCL. If only to allow traversals to
gaurantee termination under mutation. Now that traversals no longer
guarantee forward progress, it's possible to get stuck looping
indefinitely if the filesystem is constantly being mutated.
Non-excl traversals are probably still useful for GC work and debugging
threads, but LFS3_T_EXCL now allows traversals to terminate immediately
with LFS3_ERR_BUSY at the first sign of unrelated filesystem mutation:
LFS3_T_EXCL 0x00000008 Error if filesystem modified
Internally, we already track unrelated mutation to avoid corrupt state
(LFS3_t_DIRTY), so this is a very low-cost feature:
code stack ctx
before: 35944 2280 660
after: 35964 (+0.1%) 2280 (+0.0%) 660 (+0.0%)
code stack ctx
gbmap before: 38916 2296 772
gbmap after: 38940 (+0.1%) 2296 (+0.0%) 772 (+0.0%)
code stack ctx
gc before: 36016 2280 768
gc after: 36036 (+0.1%) 2280 (+0.0%) 768 (+0.0%)
This commit is contained in:
11
lfs3.c
11
lfs3.c
@ -7355,6 +7355,10 @@ static inline bool lfs3_t_ismtreeonly(uint32_t flags) {
|
||||
return flags & LFS3_T_MTREEONLY;
|
||||
}
|
||||
|
||||
static inline bool lfs3_t_isexcl(uint32_t flags) {
|
||||
return flags & LFS3_T_EXCL;
|
||||
}
|
||||
|
||||
static inline bool lfs3_t_ismkconsistent(uint32_t flags) {
|
||||
(void)flags;
|
||||
#ifndef LFS3_RDONLY
|
||||
@ -16914,6 +16918,7 @@ int lfs3_trv_open(lfs3_t *lfs3, lfs3_trv_t *trv, uint32_t flags) {
|
||||
LFS3_IFDEF_RDONLY(0, LFS3_T_RDWR)
|
||||
| LFS3_T_RDONLY
|
||||
| LFS3_T_MTREEONLY
|
||||
| LFS3_T_EXCL
|
||||
| LFS3_IFDEF_RDONLY(0, LFS3_T_MKCONSISTENT)
|
||||
| LFS3_IFDEF_RDONLY(0, LFS3_T_RELOOKAHEAD)
|
||||
| LFS3_IFDEF_RDONLY(0,
|
||||
@ -16959,6 +16964,12 @@ int lfs3_trv_read(lfs3_t *lfs3, lfs3_trv_t *trv,
|
||||
struct lfs3_tinfo *tinfo) {
|
||||
LFS3_ASSERT(lfs3_handle_isopen(lfs3, &trv->gc.t.h));
|
||||
|
||||
// filesystem modified? excl? terminate early
|
||||
if (lfs3_t_isexcl(trv->gc.t.h.flags)
|
||||
&& lfs3_t_isdirty(trv->gc.t.h.flags)) {
|
||||
return LFS3_ERR_BUSY;
|
||||
}
|
||||
|
||||
// check for pending grms every step, just in case some other
|
||||
// operation introduced new grms
|
||||
#ifndef LFS3_RDONLY
|
||||
|
||||
2
lfs3.h
2
lfs3.h
@ -77,6 +77,7 @@ enum lfs3_err {
|
||||
LFS3_ERR_UNKNOWN = -1, // Unknown error
|
||||
LFS3_ERR_INVAL = -22, // Invalid parameter
|
||||
LFS3_ERR_NOTSUP = -95, // Operation not supported
|
||||
LFS3_ERR_BUSY = -16, // Device or resource busy
|
||||
LFS3_ERR_IO = -5, // Error during device operation
|
||||
LFS3_ERR_CORRUPT = -84, // Corrupted
|
||||
LFS3_ERR_NOENT = -2, // No directory entry
|
||||
@ -318,6 +319,7 @@ enum lfs3_btype {
|
||||
#define LFS3_T_RDONLY 1 // Open traversal as read only
|
||||
#define LFS3_T_MTREEONLY \
|
||||
0x00000002 // Only traverse the mtree
|
||||
#define LFS3_T_EXCL 0x00000008 // Error if filesystem modified
|
||||
#ifndef LFS3_RDONLY
|
||||
#define LFS3_T_MKCONSISTENT \
|
||||
0x00000100 // Make the filesystem consistent
|
||||
|
||||
@ -12,6 +12,7 @@ ERR_OK = 0 # No error
|
||||
ERR_UNKNOWN = -1 # Unknown error
|
||||
ERR_INVAL = -22 # Invalid parameter
|
||||
ERR_NOTSUP = -95 # Operation not supported
|
||||
ERR_BUSY = -16 # Device or resource busy
|
||||
ERR_IO = -5 # Error during device operation
|
||||
ERR_CORRUPT = -84 # Corrupted
|
||||
ERR_NOENT = -2 # No directory entry
|
||||
|
||||
@ -139,6 +139,7 @@ T_MODE = 1 # -m The traversal's access mode
|
||||
T_RDWR = 0 # -^ Open traversal as read and write
|
||||
T_RDONLY = 1 # -^ Open traversal as read only
|
||||
T_MTREEONLY = 0x00000002 # -- Only traverse the mtree
|
||||
T_EXCL = 0x00000008 # -- Error if filesystem modified
|
||||
T_MKCONSISTENT = 0x00000100 # -- Make the filesystem consistent
|
||||
T_RELOOKAHEAD = 0x00000200 # -- Repopulate lookahead buffer
|
||||
T_REGBMAP = 0x00000400 # -- Repopulate the gbmap
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user