Reworked o/f/m/gc/i/t flags

This is mainly to free up space for flags, we're pretty close to running
out of 32-bits with future planned features:

1. Reduced file type info from 8 -> 4 bits

   We don't really need more than this, but it does mean type info is
   no longer a simple byte load.

2. Moved most internal file-state flags into the next 4 bits

   These are mostly file-type specific (except LFS_o_ZOMBIE), so we
   don't need to worry too much about overlap.

3. Compacted ck-flags into 5 bits:

     LFS_M_CKPROGS       0x00000800
     LFS_M_CKFETCHES     0x00001000
     LFS_M_CKPARITY      0x00002000
     LFS_M_CKMETAREDUND* 0x00004000
     LFS_M_CKDATACKSUMS  0x00008000

     *Planned

   Now that ck-flags are a bit more mature, it's pretty clear we'll
   probably never have CKMETACKSUMS (ckcksums + small tag reads is
   crazy expensive) or CKDATAREDUND (non-trivial parity fanout makes
   this crazy expensives. So reserving bits for these just wastes bits.

This also moves things around so ck-flags no longer overlap with open
flags.

It's a tight fit, and I still think file-specific ck-flags are out-of-
scope, but this at least decreases flag ambiguity.

New jenga:

              8     8     8     8
            .----++----++----++----.
            .-..-..-.-------.------.
  o_flags:  |t||f||t|       |  o   |
            |-||-||-|-------:--.---'
            |-||-||-'--.----.------.
  t_flags:  |t||f|| t  |    | tstt |
            '-''-'|----|----'------'
            .----.|----|.--.:--:.--.
  m_flags:  | f  || t  ||c ||o ||m |
            |----||-.--'|--|'--''--'
            |----||-|---|--|.------.
  f_flags:  | f  ||t|   |c ||  f   |
            '----''-'---'--''------'

Fortunately no major code costs:

           code          stack          ctx
  before: 37792           2608          620
  after:  37788 (-0.0%)   2608 (+0.0%)  620 (+0.0%)
This commit is contained in:
Christopher Haster
2025-01-09 16:36:59 -06:00
parent 726bf86d21
commit 5f6dbdcb14
3 changed files with 119 additions and 139 deletions
+11 -39
View File
@@ -6584,26 +6584,18 @@ static inline bool lfsr_o_isdesync(uint32_t flags) {
return flags & LFS_O_DESYNC;
}
static inline bool lfsr_o_isckmeta(uint32_t flags) {
return flags & LFS_O_CKMETA;
}
static inline bool lfsr_o_isckdata(uint32_t flags) {
return flags & LFS_O_CKDATA;
}
// internal open flags
static inline uint8_t lfsr_o_type(uint32_t flags) {
return flags >> 24;
return flags >> 28;
}
static inline uint32_t lfsr_o_settype(uint32_t flags, uint8_t type) {
return (flags & ~0xff000000) | ((uint32_t)type << 24);
return (flags & ~0xf0000000) | ((uint32_t)type << 28);
}
static inline bool lfsr_o_isbshrub(uint32_t flags) {
// it turns out that bshrub types share a bit
return flags & 0x01000000;
return flags & 0x10000000;
}
static inline bool lfsr_o_isunflush(uint32_t flags) {
@@ -6622,7 +6614,7 @@ static inline bool lfsr_o_iszombie(uint32_t flags) {
return flags & LFS_o_ZOMBIE;
}
// custom rat flags
// custom attr flags
static inline bool lfsr_a_islazy(uint32_t flags) {
return flags & LFS_A_LAZY;
}
@@ -6662,11 +6654,11 @@ static inline uint32_t lfsr_t_settstate(uint32_t flags, uint8_t tstate) {
}
static inline uint8_t lfsr_t_btype(uint32_t flags) {
return (flags >> 4) & 0xf;
return (flags >> 8) & 0x0f;
}
static inline uint32_t lfsr_t_setbtype(uint32_t flags, uint8_t btype) {
return (flags & ~0x000000f0) | (btype << 4);
return (flags & ~0x00000f00) | (btype << 8);
}
static inline bool lfsr_t_isdirty(uint32_t flags) {
@@ -6678,8 +6670,8 @@ static inline bool lfsr_t_ismutated(uint32_t flags) {
}
static inline uint32_t lfsr_t_swapdirty(uint32_t flags) {
uint32_t x = ((flags >> 9) ^ (flags >> 8)) & 0x1;
return flags ^ (x << 9) ^ (x << 8);
uint32_t x = ((flags >> 25) ^ (flags >> 24)) & 0x1;
return flags ^ (x << 25) ^ (x << 24);
}
// mount flags
@@ -6711,31 +6703,11 @@ static inline bool lfsr_m_isckdatacksums(uint32_t flags) {
}
#endif
static inline bool lfsr_m_isflush(uint32_t flags) {
return flags & LFS_M_FLUSH;
}
static inline bool lfsr_m_issync(uint32_t flags) {
return flags & LFS_M_SYNC;
}
// internal fs flags
static inline bool lfsr_i_isuntidy(uint32_t flags) {
return flags & LFS_i_UNTIDY;
}
static inline bool lfsr_i_iscompact(uint32_t flags) {
return flags & LFS_I_COMPACT;
}
static inline bool lfsr_i_isckmeta(uint32_t flags) {
return flags & LFS_I_CKMETA;
}
static inline bool lfsr_i_isckdata(uint32_t flags) {
return flags & LFS_I_CKDATA;
}
/// opened mdir things ///
@@ -9134,8 +9106,8 @@ enum {
};
static void lfsr_traversal_init(lfsr_traversal_t *t, uint32_t flags) {
t->o.o.flags = (LFS_TYPE_TRAVERSAL << 24)
| (LFSR_TSTATE_MROOTANCHOR << 4)
t->o.o.flags = lfsr_o_settype(0, LFS_TYPE_TRAVERSAL)
| lfsr_t_settstate(0, LFSR_TSTATE_MROOTANCHOR)
| flags;
t->o.o.mdir.mid = -1;
t->o.o.mdir.rbyd.weight = 0;
@@ -11157,7 +11129,7 @@ int lfsr_file_opencfg(lfs_t *lfs, lfsr_file_t *file,
}
// check metadata/data for errors?
if (lfsr_o_isckmeta(flags) || lfsr_o_isckdata(flags)) {
if (lfsr_t_isckmeta(flags) || lfsr_t_isckdata(flags)) {
err = lfsr_file_ck(lfs, file, flags);
if (err) {
goto failed;
+47 -46
View File
@@ -137,15 +137,15 @@ enum lfs_type {
#define LFS_O_FLUSH 0x00000040 // Flush data on every write
#define LFS_O_SYNC 0x00000080 // Sync metadata on every write
#define LFS_O_DESYNC 0x00000100 // Do not sync or recieve file updates
#define LFS_O_CKMETA 0x00010000 // Check metadata checksums
#define LFS_O_CKDATA 0x00020000 // Check metadata + data checksums
#define LFS_O_CKMETA 0x00100000 // Check metadata checksums
#define LFS_O_CKDATA 0x00200000 // Check metadata + data checksums
// internally used flags, don't use these
#define LFS_o_TYPE 0xff000000 // The file's type
#define LFS_o_UNFLUSH 0x00100000 // File's data does not match disk
#define LFS_o_UNSYNC 0x00200000 // File's metadata does not match disk
#define LFS_o_UNCREAT 0x00400000 // File does not exist yet
#define LFS_o_ZOMBIE 0x00800000 // File has been removed
#define LFS_o_TYPE 0xf0000000 // The file's type
#define LFS_o_UNFLUSH 0x01000000 // File's data does not match disk
#define LFS_o_UNSYNC 0x02000000 // File's metadata does not match disk
#define LFS_o_UNCREAT 0x04000000 // File does not exist yet
#define LFS_o_ZOMBIE 0x08000000 // File has been removed
// File seek flags
#define LFS_SEEK_SET 0 // Seek relative to an absolute position
@@ -163,21 +163,21 @@ enum lfs_type {
#define LFS_F_MODE 1 // Format's access mode
#define LFS_F_RDWR 0 // Format the filesystem as read and write
#ifdef LFS_CKPROGS
#define LFS_F_CKPROGS 0x00100000 // Check progs by reading back progged data
#define LFS_F_CKPROGS 0x00000800 // Check progs by reading back progged data
#endif
#ifdef LFS_CKFETCHES
#define LFS_F_CKFETCHES 0x00200000 // Check block checksums before first use
#define LFS_F_CKFETCHES 0x00001000 // Check block checksums before first use
#endif
#ifdef LFS_CKPARITY
#define LFS_F_CKPARITY 0x00400000 // Check metadata tag parity bits
#define LFS_F_CKPARITY 0x00002000 // Check metadata tag parity bits
#endif
#ifdef LFS_CKDATACKSUMS
#define LFS_F_CKDATACKSUMS \
0x08000000 // Check data checksums on reads
0x00008000 // Check data checksums on reads
#endif
#define LFS_F_CKMETA 0x00010000 // Check metadata checksums
#define LFS_F_CKDATA 0x00020000 // Check metadata + data checksums
#define LFS_F_CKMETA 0x00100000 // Check metadata checksums
#define LFS_F_CKDATA 0x00200000 // Check metadata + data checksums
// Filesystem mount flags
#define LFS_M_MODE 1 // Mount's access mode
@@ -186,53 +186,53 @@ enum lfs_type {
#define LFS_M_FLUSH 0x00000040 // Open all files with LFS_O_FLUSH
#define LFS_M_SYNC 0x00000080 // Open all files with LFS_O_SYNC
#ifdef LFS_CKPROGS
#define LFS_M_CKPROGS 0x00100000 // Check progs by reading back progged data
#define LFS_M_CKPROGS 0x00000800 // Check progs by reading back progged data
#endif
#ifdef LFS_CKFETCHES
#define LFS_M_CKFETCHES 0x00200000 // Check block checksums before first use
#define LFS_M_CKFETCHES 0x00001000 // Check block checksums before first use
#endif
#ifdef LFS_CKPARITY
#define LFS_M_CKPARITY 0x00400000 // Check metadata tag parity bits
#define LFS_M_CKPARITY 0x00002000 // Check metadata tag parity bits
#endif
#ifdef LFS_CKDATACKSUMS
#define LFS_M_CKDATACKSUMS \
0x08000000 // Check data checksums on reads
0x00008000 // Check data checksums on reads
#endif
#define LFS_M_MKCONSISTENT \
0x00001000 // Make the filesystem consistent
#define LFS_M_LOOKAHEAD 0x00002000 // Populate lookahead buffer
#define LFS_M_COMPACT 0x00008000 // Compact metadata logs
#define LFS_M_CKMETA 0x00010000 // Check metadata checksums
#define LFS_M_CKDATA 0x00020000 // Check metadata + data checksums
0x00010000 // Make the filesystem consistent
#define LFS_M_LOOKAHEAD 0x00020000 // Populate lookahead buffer
#define LFS_M_COMPACT 0x00080000 // Compact metadata logs
#define LFS_M_CKMETA 0x00100000 // Check metadata checksums
#define LFS_M_CKDATA 0x00200000 // Check metadata + data checksums
// Filesystem info flags
#define LFS_I_RDONLY 0x00000001 // Mounted read only
#define LFS_I_FLUSH 0x00000040 // Mounted with LFS_M_FLUSH
#define LFS_I_SYNC 0x00000080 // Mounted with LFS_M_SYNC
#ifdef LFS_CKPROGS
#define LFS_I_CKPROGS 0x00100000 // Mounted with LFS_M_CKPROGS
#define LFS_I_CKPROGS 0x00000800 // Mounted with LFS_M_CKPROGS
#endif
#ifdef LFS_CKFETCHES
#define LFS_I_CKFETCHES 0x00200000 // Mounted with LFS_M_CKFETCHES
#define LFS_I_CKFETCHES 0x00001000 // Mounted with LFS_M_CKFETCHES
#endif
#ifdef LFS_CKPARITY
#define LFS_I_CKPARITY 0x00400000 // Mounted with LFS_M_CKPARITY
#define LFS_I_CKPARITY 0x00002000 // Mounted with LFS_M_CKPARITY
#endif
#ifdef LFS_CKDATACKSUMS
#define LFS_I_CKDATACKSUMS \
0x08000000 // Mounted with LFS_M_CKDATACKSUMS
0x00008000 // Mounted with LFS_M_CKDATACKSUMS
#endif
#define LFS_I_MKCONSISTENT \
0x00001000 // Filesystem needs mkconsistent to write
#define LFS_I_LOOKAHEAD 0x00002000 // Lookahead buffer is not full
#define LFS_I_COMPACT 0x00008000 // Filesystem may have uncompacted metadata
#define LFS_I_CKMETA 0x00010000 // Metadata checksums not checked recently
#define LFS_I_CKDATA 0x00020000 // Data checksums not checked recently
0x00010000 // Filesystem needs mkconsistent to write
#define LFS_I_LOOKAHEAD 0x00020000 // Lookahead buffer is not full
#define LFS_I_COMPACT 0x00080000 // Filesystem may have uncompacted metadata
#define LFS_I_CKMETA 0x00100000 // Metadata checksums not checked recently
#define LFS_I_CKDATA 0x00200000 // Data checksums not checked recently
// internally used flags, don't use these
#define LFS_i_UNTIDY 0x00001000 // Filesystem may have orphaned stickynotes
#define LFS_i_UNTIDY 0x00010000 // Filesystem may have orphaned stickynotes
// Block types
@@ -243,28 +243,29 @@ enum lfs_btype {
};
// Traversal flags
#define LFS_T_MTREEONLY 0x00000800 // Only traverse the mtree
#define LFS_T_MTREEONLY 0x00000010 // Only traverse the mtree
#define LFS_T_MKCONSISTENT \
0x00001000 // Make the filesystem consistent
#define LFS_T_LOOKAHEAD 0x00002000 // Populate lookahead buffer
#define LFS_T_COMPACT 0x00008000 // Compact metadata logs
#define LFS_T_CKMETA 0x00010000 // Check metadata checksums
#define LFS_T_CKDATA 0x00020000 // Check metadata + data checksums
0x00010000 // Make the filesystem consistent
#define LFS_T_LOOKAHEAD 0x00020000 // Populate lookahead buffer
#define LFS_T_COMPACT 0x00080000 // Compact metadata logs
#define LFS_T_CKMETA 0x00100000 // Check metadata checksums
#define LFS_T_CKDATA 0x00200000 // Check metadata + data checksums
// internally used flags, don't use these
#define LFS_t_TSTATE 0x0000000f // The traversal's current tstate
#define LFS_t_BTYPE 0x000000f0 // The traversal's current btype
#define LFS_t_DIRTY 0x00000100 // Filesystem modified during traversal
#define LFS_t_MUTATED 0x00000200 // Filesystem modified by traversal
#define LFS_t_BTYPE 0x00000f00 // The traversal's current btype
#define LFS_t_DIRTY 0x01000000 // Filesystem modified during traversal
#define LFS_t_MUTATED 0x02000000 // Filesystem modified by traversal
#define LFS_t_ZOMBIE 0x08000000 // File has been removed
// GC flags
#define LFS_GC_MKCONSISTENT \
0x00001000 // Make the filesystem consistent
0x00010000 // Make the filesystem consistent
#define LFS_GC_LOOKAHEAD \
0x00002000 // Populate lookahead buffer
#define LFS_GC_COMPACT 0x00008000 // Compact metadata logs
#define LFS_GC_CKMETA 0x00010000 // Check metadata checksums
#define LFS_GC_CKDATA 0x00020000 // Check metadata + data checksums
0x00020000 // Populate lookahead buffer
#define LFS_GC_COMPACT 0x00080000 // Compact metadata logs
#define LFS_GC_CKMETA 0x00100000 // Check metadata checksums
#define LFS_GC_CKDATA 0x00200000 // Check metadata + data checksums
// Configuration provided during initialization of the littlefs
+61 -54
View File
@@ -33,19 +33,19 @@ FLAGS = [
('O', 'FLUSH', 0x00000040, "Flush data on every write" ),
('O', 'SYNC', 0x00000080, "Sync metadata on every write" ),
('O', 'DESYNC', 0x00000100, "Do not sync or recieve file updates" ),
('O', 'CKMETA', 0x00010000, "Check metadata checksums" ),
('O', 'CKDATA', 0x00020000, "Check metadata + data checksums" ),
('O', 'CKMETA', 0x00100000, "Check metadata checksums" ),
('O', 'CKDATA', 0x00200000, "Check metadata + data checksums" ),
('o', 'TYPE', 0xff000000, "The file's type" ),
('^', 'REG', 0x01000000, "Type = regular-file" ),
('^', 'DIR', 0x02000000, "Type = directory" ),
('^', 'BOOKMARK', 0x04000000, "Type = bookmark" ),
('^', 'STICKYNOTE',0x05000000, "Type = stickynote" ),
('^', 'TRAVERSAL', 0x09000000, "Type = traversal" ),
('o', 'UNFLUSH', 0x00100000, "File's data does not match disk" ),
('o', 'UNSYNC', 0x00200000, "File's metadata does not match disk" ),
('o', 'UNCREAT', 0x00400000, "File does not exist yet" ),
('o', 'ZOMBIE', 0x00800000, "File has been removed" ),
('o', 'TYPE', 0xf0000000, "The file's type" ),
('^', 'REG', 0x10000000, "Type = regular-file" ),
('^', 'DIR', 0x20000000, "Type = directory" ),
('^', 'BOOKMARK', 0x40000000, "Type = bookmark" ),
('^', 'STICKYNOTE',0x50000000, "Type = stickynote" ),
('^', 'TRAVERSAL', 0x90000000, "Type = traversal" ),
('o', 'UNFLUSH', 0x01000000, "File's data does not match disk" ),
('o', 'UNSYNC', 0x02000000, "File's metadata does not match disk" ),
('o', 'UNCREAT', 0x04000000, "File does not exist yet" ),
('o', 'ZOMBIE', 0x08000000, "File has been removed" ),
# Custom attribute flags
('A', 'MODE', 3, "The attr's access mode" ),
@@ -57,14 +57,14 @@ FLAGS = [
# Filesystem format flags
('F', 'MODE', 1, "Format's access mode" ),
('^', 'RDWR', 0, "Format the filesystem as read and write" ),
('F', 'CKPROGS', 0x00100000, "Check progs by reading back progged data" ),
('F', 'CKFETCHES', 0x00200000, "Check block checksums before first use" ),
('F', 'CKPARITY', 0x00400000, "Check metadata tag parity bits" ),
('F', 'CKPROGS', 0x00000800, "Check progs by reading back progged data" ),
('F', 'CKFETCHES', 0x00001000, "Check block checksums before first use" ),
('F', 'CKPARITY', 0x00002000, "Check metadata tag parity bits" ),
('F', 'CKDATACKSUMS',
0x08000000, "Check data checksums on reads" ),
0x00008000, "Check data checksums on reads" ),
('F', 'CKMETA', 0x00010000, "Check metadata checksums" ),
('F', 'CKDATA', 0x00020000, "Check metadata + data checksums" ),
('F', 'CKMETA', 0x00100000, "Check metadata checksums" ),
('F', 'CKDATA', 0x00200000, "Check metadata + data checksums" ),
# Filesystem mount flags
('M', 'MODE', 1, "Mount's access mode" ),
@@ -72,55 +72,61 @@ FLAGS = [
('^', 'RDONLY', 1, "Mount the filesystem as read only" ),
('M', 'FLUSH', 0x00000040, "Open all files with LFS_O_FLUSH" ),
('M', 'SYNC', 0x00000080, "Open all files with LFS_O_SYNC" ),
('M', 'CKPROGS', 0x00100000, "Check progs by reading back progged data" ),
('M', 'CKFETCHES', 0x00200000, "Check block checksums before first use" ),
('M', 'CKPARITY', 0x00400000, "Check metadata tag parity bits" ),
('M', 'CKPROGS', 0x00000800, "Check progs by reading back progged data" ),
('M', 'CKFETCHES', 0x00001000, "Check block checksums before first use" ),
('M', 'CKPARITY', 0x00002000, "Check metadata tag parity bits" ),
('M', 'CKDATACKSUMS',
0x08000000, "Check data checksums on reads" ),
0x00008000, "Check data checksums on reads" ),
('M', 'MKCONSISTENT',
0x00001000, "Make the filesystem consistent" ),
('M', 'LOOKAHEAD', 0x00002000, "Populate lookahead buffer" ),
('M', 'COMPACT', 0x00008000, "Compact metadata logs" ),
('M', 'CKMETA', 0x00010000, "Check metadata checksums" ),
('M', 'CKDATA', 0x00020000, "Check metadata + data checksums" ),
0x00010000, "Make the filesystem consistent" ),
('M', 'LOOKAHEAD', 0x00020000, "Populate lookahead buffer" ),
('M', 'COMPACT', 0x00080000, "Compact metadata logs" ),
('M', 'CKMETA', 0x00100000, "Check metadata checksums" ),
('M', 'CKDATA', 0x00200000, "Check metadata + data checksums" ),
('m', 'UNTIDY', 0x00001000, "Filesystem may have orphaned stickynotes" ),
('m', 'UNTIDY', 0x00010000, "Filesystem may have orphaned stickynotes" ),
# GC flags
('GC', 'MKCONSISTENT',
0x00001000, "Make the filesystem consistent" ),
('GC', 'LOOKAHEAD',0x00002000, "Populate lookahead buffer" ),
('GC', 'COMPACT', 0x00008000, "Compact metadata logs" ),
('GC', 'CKMETA', 0x00010000, "Check metadata checksums" ),
('GC', 'CKDATA', 0x00020000, "Check metadata + data checksums" ),
0x00010000, "Make the filesystem consistent" ),
('GC', 'LOOKAHEAD',0x00020000, "Populate lookahead buffer" ),
('GC', 'COMPACT', 0x00080000, "Compact metadata logs" ),
('GC', 'CKMETA', 0x00100000, "Check metadata checksums" ),
('GC', 'CKDATA', 0x00200000, "Check metadata + data checksums" ),
# Filesystem info flags
('I', 'RDONLY', 0x00000001, "Mounted read only" ),
('I', 'FLUSH', 0x00000040, "Mounted with LFS_M_FLUSH" ),
('I', 'SYNC', 0x00000080, "Mounted with LFS_M_SYNC" ),
('I', 'CKPROGS', 0x00100000, "Mounted with LFS_M_CKPROGS" ),
('I', 'CKFETCHES', 0x00200000, "Mounted with LFS_M_CKFETCHES" ),
('I', 'CKPARITY', 0x00400000, "Mounted with LFS_M_CKPARITY" ),
('I', 'CKPROGS', 0x00000800, "Mounted with LFS_M_CKPROGS" ),
('I', 'CKFETCHES', 0x00001000, "Mounted with LFS_M_CKFETCHES" ),
('I', 'CKPARITY', 0x00002000, "Mounted with LFS_M_CKPARITY" ),
('I', 'CKDATACKSUMS',
0x08000000, "Mounted with LFS_M_CKDATACKSUMS" ),
0x00008000, "Mounted with LFS_M_CKDATACKSUMS" ),
('I', 'MKCONSISTENT',
0x00001000, "Filesystem needs mkconsistent to write" ),
('I', 'LOOKAHEAD', 0x00002000, "Lookahead buffer is not full" ),
('I', 'COMPACT', 0x00008000, "Filesystem may have uncompacted metadata" ),
('I', 'CKMETA', 0x00010000, "Metadata checksums not checked recently" ),
('I', 'CKDATA', 0x00020000, "Data checksums not checked recently" ),
0x00010000, "Filesystem needs mkconsistent to write" ),
('I', 'LOOKAHEAD', 0x00020000, "Lookahead buffer is not full" ),
('I', 'COMPACT', 0x00080000, "Filesystem may have uncompacted metadata" ),
('I', 'CKMETA', 0x00100000, "Metadata checksums not checked recently" ),
('I', 'CKDATA', 0x00200000, "Data checksums not checked recently" ),
# Traversal flags
('T', 'MTREEONLY', 0x00000800, "Only traverse the mtree" ),
('T', 'MTREEONLY', 0x00000010, "Only traverse the mtree" ),
('T', 'MKCONSISTENT',
0x00001000, "Make the filesystem consistent" ),
('T', 'LOOKAHEAD', 0x00002000, "Populate lookahead buffer" ),
('T', 'COMPACT', 0x00008000, "Compact metadata logs" ),
('T', 'CKMETA', 0x00010000, "Check metadata checksums" ),
('T', 'CKDATA', 0x00020000, "Check metadata + data checksums" ),
0x00010000, "Make the filesystem consistent" ),
('T', 'LOOKAHEAD', 0x00020000, "Populate lookahead buffer" ),
('T', 'COMPACT', 0x00080000, "Compact metadata logs" ),
('T', 'CKMETA', 0x00100000, "Check metadata checksums" ),
('T', 'CKDATA', 0x00200000, "Check metadata + data checksums" ),
('t', 'TYPE', 0xf0000000, "The file's type" ),
('^', 'REG', 0x10000000, "Type = regular-file" ),
('^', 'DIR', 0x20000000, "Type = directory" ),
('^', 'BOOKMARK', 0x40000000, "Type = bookmark" ),
('^', 'STICKYNOTE',0x50000000, "Type = stickynote" ),
('^', 'TRAVERSAL', 0x90000000, "Type = traversal" ),
('t', 'TSTATE', 0x0000000f, "The traversal's current tstate" ),
('^', 'MROOTANCHOR',
0x00000000, "Tstate = mroot-anchor" ),
@@ -132,12 +138,13 @@ FLAGS = [
('^', 'OMDIRS', 0x00000006, "Tstate = open-mdirs" ),
('^', 'OBTREE', 0x00000007, "Tstate = open-btree" ),
('^', 'DONE', 0x00000008, "Tstate = done" ),
('t', 'BTYPE', 0x000000f0, "The traversal's current btype" ),
('^', 'MDIR', 0x00000010, "Btype = mdir" ),
('^', 'BTREE', 0x00000020, "Btype = btree" ),
('^', 'DATA', 0x00000030, "Btype = data" ),
('t', 'DIRTY', 0x00000100, "Filesystem modified during traversal" ),
('t', 'MUTATED', 0x00000200, "Filesystem modified by traversal" ),
('t', 'BTYPE', 0x00000f00, "The traversal's current btype" ),
('^', 'MDIR', 0x00000100, "Btype = mdir" ),
('^', 'BTREE', 0x00000200, "Btype = btree" ),
('^', 'DATA', 0x00000300, "Btype = data" ),
('t', 'DIRTY', 0x01000000, "Filesystem modified during traversal" ),
('t', 'MUTATED', 0x02000000, "Filesystem modified by traversal" ),
('t', 'ZOMBIE', 0x08000000, "File has been removed" ),
# Read-compat flags
('RCOMPAT', 'NONSTANDARD',