rdonly: Initial draft of LFS3_RDONLY
This is the new readonly flag, to be consistent with LFS3_M_RDONLY and
friends.
Note this overlaps with LFS3_YES_RDONLY in a weird way, where
LFS3_YES_RDONLY is basically just an alias for LFS3_RDONLY. For most
flags, LFS3_THING enables the _option_ of using LFS3_M_THING, with
LFS3_YES_THING implying LFS3_M_THING in all mount calls. But
LFS3_RDONLY _disables_ the option of using LFS3_M_RDWR, so it's a bit
different...
Do we really need two flags for the same thing? Not sure. But most users
probably expect LFS3_RDONLY coming from other filesystems.
Worst case this can be revisited in the planned config API rework.
---
As for the readonly code size, this is just the first draft and limited
to mostly ifdefing out all prog/write logic paths. There's some TODOs in
the code that may save a bit more (rbyd.eoff, file.b.shrub_ for
example). But the results are looking ok:
code stack ctx
v2.11.0 rdonly: 6270 448 580
v3-alpha rdonly: 10776 (+71.9%) 840 (+87.5%) 524 (-9.7%)
It's interesting to note most of the additional code/stack cost come
from filesystem traversal. In v2, the threaded linked-list made rdonly
traversal _incredibly_ cheap. But the extra rdwr baggage of turning
littlefs into a fully connected graph made it something to be avoided
in v3.
This hits v3 with the double whammy of:
1. Filesystem traversal is more complicated since we need to keep track
of which btree and where in the btree we are
2. Everything needs to be tracked explicitly due to the new inverted
state-machine driven API (no callbacks)
Note that even if we disabled the traversal APIs, lfs3_fs_usage, cksum
checking, etc, we'd still need to traverse to rebuild gstate. Otherwise
we risk showing grmed files after a powerloss.
---
This did affect the default build a little bit, due to moving things
around for nicer ifdef groupings:
code stack ctx
default before: 37300 2280 636
default after: 37304 (+0.0%) 2280 (+0.0%) 636 (+0.0%)
This commit is contained in:
@@ -114,12 +114,24 @@ enum lfs3_type {
|
||||
// File open flags
|
||||
#define LFS3_O_MODE 3 // The file's access mode
|
||||
#define LFS3_O_RDONLY 0 // Open a file as read only
|
||||
#ifndef LFS3_RDONLY
|
||||
#define LFS3_O_WRONLY 1 // Open a file as write only
|
||||
#endif
|
||||
#ifndef LFS3_RDONLY
|
||||
#define LFS3_O_RDWR 2 // Open a file as read and write
|
||||
#endif
|
||||
#ifndef LFS3_RDONLY
|
||||
#define LFS3_O_CREAT 0x00000004 // Create a file if it does not exist
|
||||
#endif
|
||||
#ifndef LFS3_RDONLY
|
||||
#define LFS3_O_EXCL 0x00000008 // Fail if a file already exists
|
||||
#endif
|
||||
#ifndef LFS3_RDONLY
|
||||
#define LFS3_O_TRUNC 0x00000010 // Truncate the existing file to zero size
|
||||
#endif
|
||||
#ifndef LFS3_RDONLY
|
||||
#define LFS3_O_APPEND 0x00000020 // Move to end of file on every write
|
||||
#endif
|
||||
#define LFS3_O_FLUSH 0x00000040 // Flush data on every write
|
||||
#define LFS3_O_SYNC 0x00000080 // Sync metadata on every write
|
||||
#define LFS3_O_DESYNC 0x04000000 // Do not sync or recieve file updates
|
||||
@@ -143,11 +155,16 @@ enum lfs3_type {
|
||||
// Custom attribute flags
|
||||
#define LFS3_A_MODE 3 // The attr's access mode
|
||||
#define LFS3_A_RDONLY 0 // Open an attr as read only
|
||||
#ifndef LFS3_RDONLY
|
||||
#define LFS3_A_WRONLY 1 // Open an attr as write only
|
||||
#endif
|
||||
#ifndef LFS3_RDONLY
|
||||
#define LFS3_A_RDWR 2 // Open an attr as read and write
|
||||
#endif
|
||||
#define LFS3_A_LAZY 0x04 // Only write attr if file changed
|
||||
|
||||
// Filesystem format flags
|
||||
#ifndef LFS3_RDONLY
|
||||
#define LFS3_F_MODE 1 // Format's access mode
|
||||
#define LFS3_F_RDWR 0 // Format the filesystem as read and write
|
||||
#ifdef LFS3_REVDBG
|
||||
@@ -174,20 +191,23 @@ enum lfs3_type {
|
||||
|
||||
#define LFS3_F_CKMETA 0x00001000 // Check metadata checksums
|
||||
#define LFS3_F_CKDATA 0x00002000 // Check metadata + data checksums
|
||||
#endif
|
||||
|
||||
// Filesystem mount flags
|
||||
#define LFS3_M_MODE 1 // Mount's access mode
|
||||
#ifndef LFS3_RDONLY
|
||||
#define LFS3_M_RDWR 0 // Mount the filesystem as read and write
|
||||
#endif
|
||||
#define LFS3_M_RDONLY 1 // Mount the filesystem as read only
|
||||
#define LFS3_M_FLUSH 0x00000040 // Open all files with LFS3_O_FLUSH
|
||||
#define LFS3_M_SYNC 0x00000080 // Open all files with LFS3_O_SYNC
|
||||
#ifdef LFS3_REVDBG
|
||||
#if !defined(LFS3_RDONLY) && defined(LFS3_REVDBG)
|
||||
#define LFS3_M_REVDBG 0x00000010 // Add debug info to revision counts
|
||||
#endif
|
||||
#ifdef LFS3_REVNOISE
|
||||
#if !defined(LFS3_RDONLY) && defined(LFS3_REVNOISE)
|
||||
#define LFS3_M_REVNOISE 0x00000020 // Add noise to revision counts
|
||||
#endif
|
||||
#ifdef LFS3_CKPROGS
|
||||
#if !defined(LFS3_RDONLY) && defined(LFS3_CKPROGS)
|
||||
#define LFS3_M_CKPROGS 0x00080000 // Check progs by reading back progged data
|
||||
#endif
|
||||
#ifdef LFS3_CKFETCHES
|
||||
@@ -203,11 +223,17 @@ enum lfs3_type {
|
||||
0x00800000 // Check data checksums on reads
|
||||
#endif
|
||||
|
||||
#ifndef LFS3_RDONLY
|
||||
#define LFS3_M_MKCONSISTENT \
|
||||
0x00000100 // Make the filesystem consistent
|
||||
#endif
|
||||
#ifndef LFS3_RDONLY
|
||||
#define LFS3_M_LOOKAHEAD \
|
||||
0x00000200 // Populate lookahead buffer
|
||||
#endif
|
||||
#ifndef LFS3_RDONLY
|
||||
#define LFS3_M_COMPACT 0x00000800 // Compact metadata logs
|
||||
#endif
|
||||
#define LFS3_M_CKMETA 0x00001000 // Check metadata checksums
|
||||
#define LFS3_M_CKDATA 0x00002000 // Check metadata + data checksums
|
||||
|
||||
@@ -215,13 +241,13 @@ enum lfs3_type {
|
||||
#define LFS3_I_RDONLY 0x00000001 // Mounted read only
|
||||
#define LFS3_I_FLUSH 0x00000040 // Mounted with LFS3_M_FLUSH
|
||||
#define LFS3_I_SYNC 0x00000080 // Mounted with LFS3_M_SYNC
|
||||
#ifdef LFS3_REVDBG
|
||||
#if !defined(LFS3_RDONLY) && defined(LFS3_REVDBG)
|
||||
#define LFS3_I_REVDBG 0x00000010 // Mounted with LFS3_M_REVDBG
|
||||
#endif
|
||||
#ifdef LFS3_REVNOISE
|
||||
#if !defined(LFS3_RDONLY) && defined(LFS3_REVNOISE)
|
||||
#define LFS3_I_REVNOISE 0x00000020 // Mounted with LFS3_M_REVNOISE
|
||||
#endif
|
||||
#ifdef LFS3_CKPROGS
|
||||
#if !defined(LFS3_RDONLY) && defined(LFS3_CKPROGS)
|
||||
#define LFS3_I_CKPROGS 0x00080000 // Mounted with LFS3_M_CKPROGS
|
||||
#endif
|
||||
#ifdef LFS3_CKFETCHES
|
||||
@@ -237,11 +263,17 @@ enum lfs3_type {
|
||||
0x00800000 // Mounted with LFS3_M_CKDATACKSUMREADS
|
||||
#endif
|
||||
|
||||
#ifndef LFS3_RDONLY
|
||||
#define LFS3_I_MKCONSISTENT \
|
||||
0x00000100 // Filesystem needs mkconsistent to write
|
||||
#endif
|
||||
#ifndef LFS3_RDONLY
|
||||
#define LFS3_I_LOOKAHEAD \
|
||||
0x00000200 // Lookahead buffer is not full
|
||||
#endif
|
||||
#ifndef LFS3_RDONLY
|
||||
#define LFS3_I_COMPACT 0x00000800 // Filesystem may have uncompacted metadata
|
||||
#endif
|
||||
#define LFS3_I_CKMETA 0x00001000 // Metadata checksums not checked recently
|
||||
#define LFS3_I_CKDATA 0x00002000 // Data checksums not checked recently
|
||||
|
||||
@@ -260,15 +292,23 @@ enum lfs3_btype {
|
||||
|
||||
// Traversal flags
|
||||
#define LFS3_T_MODE 1 // The traversal's access mode
|
||||
#ifndef LFS3_RDONLY
|
||||
#define LFS3_T_RDWR 0 // Open traversal as read and write
|
||||
#endif
|
||||
#define LFS3_T_RDONLY 1 // Open traversal as read only
|
||||
#define LFS3_T_MTREEONLY \
|
||||
0x00000002 // Only traverse the mtree
|
||||
#ifndef LFS3_RDONLY
|
||||
#define LFS3_T_MKCONSISTENT \
|
||||
0x00000100 // Make the filesystem consistent
|
||||
#endif
|
||||
#ifndef LFS3_RDONLY
|
||||
#define LFS3_T_LOOKAHEAD \
|
||||
0x00000200 // Populate lookahead buffer
|
||||
#endif
|
||||
#ifndef LFS3_RDONLY
|
||||
#define LFS3_T_COMPACT 0x00000800 // Compact metadata logs
|
||||
#endif
|
||||
#define LFS3_T_CKMETA 0x00001000 // Check metadata checksums
|
||||
#define LFS3_T_CKDATA 0x00002000 // Check metadata + data checksums
|
||||
|
||||
@@ -281,11 +321,17 @@ enum lfs3_btype {
|
||||
#define LFS3_t_MUTATED 0x01000000 // Filesystem modified by traversal
|
||||
|
||||
// GC flags
|
||||
#ifndef LFS3_RDONLY
|
||||
#define LFS3_GC_MKCONSISTENT \
|
||||
0x00000100 // Make the filesystem consistent
|
||||
#endif
|
||||
#ifndef LFS3_RDONLY
|
||||
#define LFS3_GC_LOOKAHEAD \
|
||||
0x00000200 // Populate lookahead buffer
|
||||
#endif
|
||||
#ifndef LFS3_RDONLY
|
||||
#define LFS3_GC_COMPACT 0x00000800 // Compact metadata logs
|
||||
#endif
|
||||
#define LFS3_GC_CKMETA 0x00001000 // Check metadata checksums
|
||||
#define LFS3_GC_CKDATA 0x00002000 // Check metadata + data checksums
|
||||
|
||||
@@ -301,21 +347,27 @@ struct lfs3_config {
|
||||
int (*read)(const struct lfs3_config *c, lfs3_block_t block,
|
||||
lfs3_off_t off, void *buffer, lfs3_size_t size);
|
||||
|
||||
#ifndef LFS3_RDONLY
|
||||
// Program a region in a block. The block must have previously
|
||||
// been erased. Negative error codes are propagated to the user.
|
||||
// May return LFS3_ERR_CORRUPT if the block should be considered bad.
|
||||
int (*prog)(const struct lfs3_config *c, lfs3_block_t block,
|
||||
lfs3_off_t off, const void *buffer, lfs3_size_t size);
|
||||
#endif
|
||||
|
||||
#ifndef LFS3_RDONLY
|
||||
// Erase a block. A block must be erased before being programmed.
|
||||
// The state of an erased block is undefined. Negative error codes
|
||||
// are propagated to the user.
|
||||
// May return LFS3_ERR_CORRUPT if the block should be considered bad.
|
||||
int (*erase)(const struct lfs3_config *c, lfs3_block_t block);
|
||||
#endif
|
||||
|
||||
#ifndef LFS3_RDONLY
|
||||
// Sync the state of the underlying block device. Negative error codes
|
||||
// are propagated to the user.
|
||||
int (*sync)(const struct lfs3_config *c);
|
||||
#endif
|
||||
|
||||
#ifdef LFS3_THREADSAFE
|
||||
// Lock the underlying block device. Negative error codes
|
||||
@@ -331,9 +383,11 @@ struct lfs3_config {
|
||||
// multiple of this value.
|
||||
lfs3_size_t read_size;
|
||||
|
||||
#ifndef LFS3_RDONLY
|
||||
// Minimum size of a program in bytes. All program operations will be a
|
||||
// multiple of this value.
|
||||
lfs3_size_t prog_size;
|
||||
#endif
|
||||
|
||||
// Size of an erasable block in bytes. This does not impact ram consumption
|
||||
// and may be larger than the physical erase size. Must be a multiple of
|
||||
@@ -343,6 +397,7 @@ struct lfs3_config {
|
||||
// Number of erasable blocks on the device.
|
||||
lfs3_size_t block_count;
|
||||
|
||||
#ifndef LFS3_RDONLY
|
||||
// Number of erase cycles before metadata blocks are relocated for
|
||||
// wear-leveling. Suggested values are in the range 16-1024. Larger values
|
||||
// relocate less frequently, improving average performance, at the cost
|
||||
@@ -352,27 +407,32 @@ struct lfs3_config {
|
||||
// 0 results in pure copy-on-write, which may be counter-productive. Set
|
||||
// to -1 to disable block-level wear-leveling.
|
||||
int32_t block_recycles;
|
||||
#endif
|
||||
|
||||
// Size of the read cache in bytes. Larger caches can improve
|
||||
// performance by storing more data and reducing the number of disk
|
||||
// accesses. Must be a multiple of the read size.
|
||||
lfs3_size_t rcache_size;
|
||||
|
||||
#ifndef LFS3_RDONLY
|
||||
// Size of the program cache in bytes. Larger caches can improve
|
||||
// performance by storing more data and reducing the number of disk
|
||||
// accesses. Must be a multiple of the program size.
|
||||
lfs3_size_t pcache_size;
|
||||
#endif
|
||||
|
||||
// Size of file caches in bytes. In addition to filesystem-wide
|
||||
// read/prog caches, each file gets its own cache to reduce disk
|
||||
// accesses.
|
||||
lfs3_size_t file_cache_size;
|
||||
|
||||
#ifndef LFS3_RDONLY
|
||||
// Size of the lookahead buffer in bytes. A larger lookahead buffer
|
||||
// increases the number of blocks found during an allocation pass. The
|
||||
// lookahead buffer is stored as a compact bitmap, so each byte of RAM
|
||||
// can track 8 blocks.
|
||||
lfs3_size_t lookahead_size;
|
||||
#endif
|
||||
|
||||
#ifdef LFS3_GC
|
||||
// Flags indicating what gc work to do during lfs3_gc calls.
|
||||
@@ -393,6 +453,7 @@ struct lfs3_config {
|
||||
lfs3_soff_t gc_steps;
|
||||
#endif
|
||||
|
||||
#ifndef LFS3_RDONLY
|
||||
// Threshold for metadata compaction during gc in bytes. Metadata logs
|
||||
// that exceed this threshold will be compacted during gc operations.
|
||||
// Defaults to ~88% block_size when zero, though this default may change
|
||||
@@ -403,45 +464,59 @@ struct lfs3_config {
|
||||
//
|
||||
// Set to -1 to disable metadata compaction during gc.
|
||||
lfs3_size_t gc_compact_thresh;
|
||||
#endif
|
||||
|
||||
// Optional statically allocated rcache buffer. Must be rcache_size. By
|
||||
// default lfs3_malloc is used to allocate this buffer.
|
||||
void *rcache_buffer;
|
||||
|
||||
#ifndef LFS3_RDONLY
|
||||
// Optional statically allocated pcache buffer. Must be pcache_size. By
|
||||
// default lfs3_malloc is used to allocate this buffer.
|
||||
void *pcache_buffer;
|
||||
#endif
|
||||
|
||||
#ifndef LFS3_RDONLY
|
||||
// Optional statically allocated lookahead buffer. Must be lookahead_size.
|
||||
// By default lfs3_malloc is used to allocate this buffer.
|
||||
void *lookahead_buffer;
|
||||
#endif
|
||||
|
||||
#ifndef LFS3_RDONLY
|
||||
// Optional upper limit on length of file names in bytes. No downside for
|
||||
// larger names except the size of the info struct which is controlled by
|
||||
// the LFS3_NAME_MAX define. Defaults to LFS3_NAME_MAX when zero. Stored in
|
||||
// superblock and must be respected by other littlefs drivers.
|
||||
lfs3_size_t name_limit;
|
||||
#endif
|
||||
|
||||
#ifndef LFS3_RDONLY
|
||||
// Optional upper limit on files in bytes. No downside for larger files
|
||||
// but must be <= LFS3_FILE_MAX. Defaults to LFS3_FILE_MAX when zero. Stored
|
||||
// in superblock and must be respected by other littlefs drivers.
|
||||
lfs3_size_t file_limit;
|
||||
#endif
|
||||
|
||||
// TODO these are pretty low-level details, should we have reasonable
|
||||
// defaults? need to benchmark.
|
||||
|
||||
#ifndef LFS3_RDONLY
|
||||
// Maximum size of inlined trees (shrubs) in bytes. Shrubs reduce B-tree
|
||||
// root overhead, but may impact metadata-related performance. Must be <=
|
||||
// blocksize/4.
|
||||
//
|
||||
// 0 disables shrubs.
|
||||
lfs3_size_t inline_size;
|
||||
#endif
|
||||
|
||||
#ifndef LFS3_RDONLY
|
||||
// Maximum size of a non-block B-tree leaf in bytes. Smaller values may
|
||||
// make small random-writes cheaper, but increase metadata overhead. Must
|
||||
// be <= block_size/4.
|
||||
lfs3_size_t fragment_size;
|
||||
#endif
|
||||
|
||||
#ifndef LFS3_RDONLY
|
||||
// Threshold for compacting multiple fragments into a block. Smaller
|
||||
// values will crystallize more eagerly, reducing disk usage, but
|
||||
// increasing the cost of random-writes.
|
||||
@@ -449,7 +524,9 @@ struct lfs3_config {
|
||||
// 0 only writes blocks, minimizing disk usage, while -1 or any value >
|
||||
// block_size only writes fragments, minimizing random-write cost.
|
||||
lfs3_size_t crystal_thresh;
|
||||
#endif
|
||||
|
||||
#ifndef LFS3_RDONLY
|
||||
// Threshold for breaking a block into fragments. Smaller values will
|
||||
// fragment more lazily, reducing random-write cost, but risk higher
|
||||
// disk usage.
|
||||
@@ -462,6 +539,7 @@ struct lfs3_config {
|
||||
// 0 will never fragment a block once compacted, while -1 will fragment
|
||||
// as soon as a block drops below crystal_thresh.
|
||||
lfs3_size_t fragment_thresh;
|
||||
#endif
|
||||
};
|
||||
|
||||
// File info structure
|
||||
@@ -604,6 +682,7 @@ typedef struct lfs3_rbyd {
|
||||
// sign(trunk)=0 => normal rbyd
|
||||
// sign(trunk)=1 => shrub rbyd
|
||||
lfs3_size_t trunk;
|
||||
// TODO can we actually get rid of eoff when LFS3_RDONLY?
|
||||
// sign(eoff) => perturb bit
|
||||
// eoff=0, trunk=0 => not yet committed
|
||||
// eoff=0, trunk>0 => not yet fetched
|
||||
@@ -641,6 +720,7 @@ typedef struct lfs3_bshrub {
|
||||
// sign(trunk)=1 => bshrub
|
||||
// sign(trunk)=0 => btree
|
||||
lfs3_shrub_t shrub;
|
||||
// TODO can we actually get rid of shrub_ when LFS3_RDONLY?
|
||||
lfs3_shrub_t shrub_;
|
||||
} lfs3_bshrub_t;
|
||||
|
||||
@@ -730,10 +810,12 @@ typedef struct lfs3 {
|
||||
lfs3_size_t name_limit;
|
||||
lfs3_off_t file_limit;
|
||||
|
||||
int8_t recycle_bits;
|
||||
uint8_t mbits;
|
||||
#ifndef LFS3_RDONLY
|
||||
int8_t recycle_bits;
|
||||
uint8_t rattr_estimate;
|
||||
uint8_t mattr_estimate;
|
||||
#endif
|
||||
|
||||
// linked-list of opened mdirs
|
||||
lfs3_omdir_t *omdirs;
|
||||
@@ -748,14 +830,16 @@ typedef struct lfs3 {
|
||||
uint8_t *buffer;
|
||||
} rcache;
|
||||
|
||||
#ifndef LFS3_RDONLY
|
||||
struct lfs3_pcache {
|
||||
lfs3_block_t block;
|
||||
lfs3_size_t off;
|
||||
lfs3_size_t size;
|
||||
uint8_t *buffer;
|
||||
} pcache;
|
||||
#endif
|
||||
|
||||
#ifdef LFS3_CKMETAPARITY
|
||||
#if !defined(LFS3_RDONLY) && defined(LFS3_CKMETAPARITY)
|
||||
struct {
|
||||
lfs3_block_t block;
|
||||
// sign(off) => tail parity
|
||||
@@ -763,6 +847,7 @@ typedef struct lfs3 {
|
||||
} ptail;
|
||||
#endif
|
||||
|
||||
#ifndef LFS3_RDONLY
|
||||
struct lfs3_lookahead {
|
||||
lfs3_block_t window;
|
||||
lfs3_block_t off;
|
||||
@@ -770,14 +855,21 @@ typedef struct lfs3 {
|
||||
lfs3_block_t ckpoint;
|
||||
uint8_t *buffer;
|
||||
} lookahead;
|
||||
#endif
|
||||
|
||||
// global state
|
||||
uint32_t gcksum;
|
||||
#ifndef LFS3_RDONLY
|
||||
uint32_t gcksum_p;
|
||||
#endif
|
||||
// TODO can we actually get rid of grm_d when LFS3_RDONLY?
|
||||
uint32_t gcksum_d;
|
||||
|
||||
lfs3_grm_t grm;
|
||||
#ifndef LFS3_RDONLY
|
||||
uint8_t grm_p[LFS3_GRM_DSIZE];
|
||||
#endif
|
||||
// TODO can we actually get rid of grm_d when LFS3_RDONLY?
|
||||
uint8_t grm_d[LFS3_GRM_DSIZE];
|
||||
|
||||
#ifdef LFS3_GC
|
||||
@@ -791,7 +883,7 @@ typedef struct lfs3 {
|
||||
|
||||
/// Filesystem functions ///
|
||||
|
||||
#ifndef LFS3_READONLY
|
||||
#ifndef LFS3_RDONLY
|
||||
// Format a block device with the littlefs
|
||||
//
|
||||
// Requires a littlefs object and config struct. This clobbers the littlefs
|
||||
@@ -822,7 +914,7 @@ int lfs3_unmount(lfs3_t *lfs3);
|
||||
|
||||
/// General operations ///
|
||||
|
||||
#ifndef LFS3_READONLY
|
||||
#ifndef LFS3_RDONLY
|
||||
// Removes a file or directory
|
||||
//
|
||||
// If removing a directory, the directory must be empty.
|
||||
@@ -830,7 +922,7 @@ int lfs3_unmount(lfs3_t *lfs3);
|
||||
int lfs3_remove(lfs3_t *lfs3, const char *path);
|
||||
#endif
|
||||
|
||||
#ifndef LFS3_READONLY
|
||||
#ifndef LFS3_RDONLY
|
||||
// Rename or move a file or directory
|
||||
//
|
||||
// If the destination exists, it must match the source in type.
|
||||
@@ -859,7 +951,7 @@ lfs3_ssize_t lfs3_getattr(lfs3_t *lfs3, const char *path, uint8_t type,
|
||||
// Returns the size of the attribute, or a negative error code on failure.
|
||||
lfs3_ssize_t lfs3_sizeattr(lfs3_t *lfs3, const char *path, uint8_t type);
|
||||
|
||||
#ifndef LFS3_READONLY
|
||||
#ifndef LFS3_RDONLY
|
||||
// Set a custom attributes
|
||||
//
|
||||
// Returns a negative error code on failure.
|
||||
@@ -867,7 +959,7 @@ int lfs3_setattr(lfs3_t *lfs3, const char *path, uint8_t type,
|
||||
const void *buffer, lfs3_size_t size);
|
||||
#endif
|
||||
|
||||
#ifndef LFS3_READONLY
|
||||
#ifndef LFS3_RDONLY
|
||||
// Removes a custom attribute
|
||||
//
|
||||
// Returns a negative error code on failure.
|
||||
@@ -967,7 +1059,7 @@ int lfs3_file_resync(lfs3_t *lfs3, lfs3_file_t *file);
|
||||
lfs3_ssize_t lfs3_file_read(lfs3_t *lfs3, lfs3_file_t *file,
|
||||
void *buffer, lfs3_size_t size);
|
||||
|
||||
#ifndef LFS3_READONLY
|
||||
#ifndef LFS3_RDONLY
|
||||
// Write data to file
|
||||
//
|
||||
// Takes a buffer and size indicating the data to write. The file will not
|
||||
@@ -985,7 +1077,7 @@ lfs3_ssize_t lfs3_file_write(lfs3_t *lfs3, lfs3_file_t *file,
|
||||
lfs3_soff_t lfs3_file_seek(lfs3_t *lfs3, lfs3_file_t *file,
|
||||
lfs3_soff_t off, uint8_t whence);
|
||||
|
||||
#ifndef LFS3_READONLY
|
||||
#ifndef LFS3_RDONLY
|
||||
// Truncate/grow the size of the file to the specified size
|
||||
//
|
||||
// If size is larger than the current file size, a hole is created, appearing
|
||||
@@ -995,7 +1087,7 @@ lfs3_soff_t lfs3_file_seek(lfs3_t *lfs3, lfs3_file_t *file,
|
||||
int lfs3_file_truncate(lfs3_t *lfs3, lfs3_file_t *file, lfs3_off_t size);
|
||||
#endif
|
||||
|
||||
#ifndef LFS3_READONLY
|
||||
#ifndef LFS3_RDONLY
|
||||
// Truncate/grow the file, but from the front
|
||||
//
|
||||
// If size is larger than the current file size, a hole is created, appearing
|
||||
@@ -1038,7 +1130,7 @@ int lfs3_file_ckdata(lfs3_t *lfs3, lfs3_file_t *file);
|
||||
|
||||
/// Directory operations ///
|
||||
|
||||
#ifndef LFS3_READONLY
|
||||
#ifndef LFS3_RDONLY
|
||||
// Create a directory
|
||||
//
|
||||
// Returns a negative error code on failure.
|
||||
@@ -1133,7 +1225,7 @@ int lfs3_fs_stat(lfs3_t *lfs3, struct lfs3_fsinfo *fsinfo);
|
||||
// Returns the number of allocated blocks, or a negative error code on failure.
|
||||
lfs3_ssize_t lfs3_fs_usage(lfs3_t *lfs3);
|
||||
|
||||
#ifndef LFS3_READONLY
|
||||
#ifndef LFS3_RDONLY
|
||||
// Attempt to make the filesystem consistent and ready for writing
|
||||
//
|
||||
// Calling this function is not required, consistency will be implicitly
|
||||
@@ -1145,21 +1237,17 @@ lfs3_ssize_t lfs3_fs_usage(lfs3_t *lfs3);
|
||||
int lfs3_fs_mkconsistent(lfs3_t *lfs3);
|
||||
#endif
|
||||
|
||||
#ifndef LFS3_READONLY
|
||||
// Check the filesystem for metadata errors
|
||||
//
|
||||
// Returns LFS3_ERR_CORRUPT if a checksum mismatch is found, or a negative
|
||||
// error code on failure.
|
||||
int lfs3_fs_ckmeta(lfs3_t *lfs3);
|
||||
#endif
|
||||
|
||||
#ifndef LFS3_READONLY
|
||||
// Check the filesystem for metadata + data errors
|
||||
//
|
||||
// Returns LFS3_ERR_CORRUPT if a checksum mismatch is found, or a negative
|
||||
// error code on failure.
|
||||
int lfs3_fs_ckdata(lfs3_t *lfs3);
|
||||
#endif
|
||||
|
||||
// Get the current filesystem checksum
|
||||
//
|
||||
@@ -1201,7 +1289,7 @@ int lfs3_fs_gc(lfs3_t *lfs3);
|
||||
// Returns a negative error code on failure.
|
||||
int lfs3_fs_unck(lfs3_t *lfs3, uint32_t flags);
|
||||
|
||||
#ifndef LFS3_READONLY
|
||||
#ifndef LFS3_RDONLY
|
||||
// Change the number of blocks used by the filesystem
|
||||
//
|
||||
// This changes the number of blocks we are currently using and updates
|
||||
|
||||
@@ -191,6 +191,12 @@
|
||||
|
||||
|
||||
// Some ifdef conveniences
|
||||
#ifdef LFS3_RDONLY
|
||||
#define LFS3_IFDEF_RDONLY(a, b) (a)
|
||||
#else
|
||||
#define LFS3_IFDEF_RDONLY(a, b) (b)
|
||||
#endif
|
||||
|
||||
#ifdef LFS3_REVDBG
|
||||
#define LFS3_IFDEF_REVDBG(a, b) (a)
|
||||
#else
|
||||
|
||||
Reference in New Issue
Block a user