Merge pull request #480 from maximevince/master
Add LFS_READONLY define, to allow smaller builds providing read-only mode
This commit is contained in:
+16
@@ -208,6 +208,22 @@ jobs:
|
|||||||
script:
|
script:
|
||||||
- make test TFLAGS+="-k --valgrind"
|
- make test TFLAGS+="-k --valgrind"
|
||||||
|
|
||||||
|
# test compilation in read-only mode
|
||||||
|
- stage: test
|
||||||
|
env:
|
||||||
|
- NAME=littlefs-readonly
|
||||||
|
- CC="arm-linux-gnueabi-gcc --static -mthumb"
|
||||||
|
- CFLAGS="-Werror -DLFS_READONLY"
|
||||||
|
if: branch !~ -prefix$
|
||||||
|
install:
|
||||||
|
- *install-common
|
||||||
|
- sudo apt-get install
|
||||||
|
gcc-arm-linux-gnueabi
|
||||||
|
libc6-dev-armel-cross
|
||||||
|
- arm-linux-gnueabi-gcc --version
|
||||||
|
# report-size will compile littlefs and report the size
|
||||||
|
script: [*report-size]
|
||||||
|
|
||||||
# self-host with littlefs-fuse for fuzz test
|
# self-host with littlefs-fuse for fuzz test
|
||||||
- stage: test
|
- stage: test
|
||||||
env:
|
env:
|
||||||
|
|||||||
@@ -140,6 +140,7 @@ static int lfs_bd_cmp(lfs_t *lfs,
|
|||||||
return LFS_CMP_EQ;
|
return LFS_CMP_EQ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static int lfs_bd_flush(lfs_t *lfs,
|
static int lfs_bd_flush(lfs_t *lfs,
|
||||||
lfs_cache_t *pcache, lfs_cache_t *rcache, bool validate) {
|
lfs_cache_t *pcache, lfs_cache_t *rcache, bool validate) {
|
||||||
if (pcache->block != LFS_BLOCK_NULL && pcache->block != LFS_BLOCK_INLINE) {
|
if (pcache->block != LFS_BLOCK_NULL && pcache->block != LFS_BLOCK_INLINE) {
|
||||||
@@ -172,7 +173,9 @@ static int lfs_bd_flush(lfs_t *lfs,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static int lfs_bd_sync(lfs_t *lfs,
|
static int lfs_bd_sync(lfs_t *lfs,
|
||||||
lfs_cache_t *pcache, lfs_cache_t *rcache, bool validate) {
|
lfs_cache_t *pcache, lfs_cache_t *rcache, bool validate) {
|
||||||
lfs_cache_drop(lfs, rcache);
|
lfs_cache_drop(lfs, rcache);
|
||||||
@@ -186,7 +189,9 @@ static int lfs_bd_sync(lfs_t *lfs,
|
|||||||
LFS_ASSERT(err <= 0);
|
LFS_ASSERT(err <= 0);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static int lfs_bd_prog(lfs_t *lfs,
|
static int lfs_bd_prog(lfs_t *lfs,
|
||||||
lfs_cache_t *pcache, lfs_cache_t *rcache, bool validate,
|
lfs_cache_t *pcache, lfs_cache_t *rcache, bool validate,
|
||||||
lfs_block_t block, lfs_off_t off,
|
lfs_block_t block, lfs_off_t off,
|
||||||
@@ -232,13 +237,16 @@ static int lfs_bd_prog(lfs_t *lfs,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static int lfs_bd_erase(lfs_t *lfs, lfs_block_t block) {
|
static int lfs_bd_erase(lfs_t *lfs, lfs_block_t block) {
|
||||||
LFS_ASSERT(block < lfs->cfg->block_count);
|
LFS_ASSERT(block < lfs->cfg->block_count);
|
||||||
int err = lfs->cfg->erase(lfs->cfg, block);
|
int err = lfs->cfg->erase(lfs->cfg, block);
|
||||||
LFS_ASSERT(err <= 0);
|
LFS_ASSERT(err <= 0);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/// Small type-level utilities ///
|
/// Small type-level utilities ///
|
||||||
@@ -392,10 +400,12 @@ static void lfs_ctz_fromle32(struct lfs_ctz *ctz) {
|
|||||||
ctz->size = lfs_fromle32(ctz->size);
|
ctz->size = lfs_fromle32(ctz->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static void lfs_ctz_tole32(struct lfs_ctz *ctz) {
|
static void lfs_ctz_tole32(struct lfs_ctz *ctz) {
|
||||||
ctz->head = lfs_tole32(ctz->head);
|
ctz->head = lfs_tole32(ctz->head);
|
||||||
ctz->size = lfs_tole32(ctz->size);
|
ctz->size = lfs_tole32(ctz->size);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline void lfs_superblock_fromle32(lfs_superblock_t *superblock) {
|
static inline void lfs_superblock_fromle32(lfs_superblock_t *superblock) {
|
||||||
superblock->version = lfs_fromle32(superblock->version);
|
superblock->version = lfs_fromle32(superblock->version);
|
||||||
@@ -442,6 +452,7 @@ static inline void lfs_mlist_append(lfs_t *lfs, struct lfs_mlist *mlist) {
|
|||||||
|
|
||||||
|
|
||||||
/// Internal operations predeclared here ///
|
/// Internal operations predeclared here ///
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir,
|
static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir,
|
||||||
const struct lfs_mattr *attrs, int attrcount);
|
const struct lfs_mattr *attrs, int attrcount);
|
||||||
static int lfs_dir_compact(lfs_t *lfs,
|
static int lfs_dir_compact(lfs_t *lfs,
|
||||||
@@ -458,10 +469,13 @@ static lfs_stag_t lfs_fs_parent(lfs_t *lfs, const lfs_block_t dir[2],
|
|||||||
lfs_mdir_t *parent);
|
lfs_mdir_t *parent);
|
||||||
static int lfs_fs_relocate(lfs_t *lfs,
|
static int lfs_fs_relocate(lfs_t *lfs,
|
||||||
const lfs_block_t oldpair[2], lfs_block_t newpair[2]);
|
const lfs_block_t oldpair[2], lfs_block_t newpair[2]);
|
||||||
|
#endif
|
||||||
int lfs_fs_traverseraw(lfs_t *lfs,
|
int lfs_fs_traverseraw(lfs_t *lfs,
|
||||||
int (*cb)(void *data, lfs_block_t block), void *data,
|
int (*cb)(void *data, lfs_block_t block), void *data,
|
||||||
bool includeorphans);
|
bool includeorphans);
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static int lfs_fs_forceconsistency(lfs_t *lfs);
|
static int lfs_fs_forceconsistency(lfs_t *lfs);
|
||||||
|
#endif
|
||||||
static int lfs_deinit(lfs_t *lfs);
|
static int lfs_deinit(lfs_t *lfs);
|
||||||
#ifdef LFS_MIGRATE
|
#ifdef LFS_MIGRATE
|
||||||
static int lfs1_traverse(lfs_t *lfs,
|
static int lfs1_traverse(lfs_t *lfs,
|
||||||
@@ -469,6 +483,7 @@ static int lfs1_traverse(lfs_t *lfs,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// Block allocator ///
|
/// Block allocator ///
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static int lfs_alloc_lookahead(void *p, lfs_block_t block) {
|
static int lfs_alloc_lookahead(void *p, lfs_block_t block) {
|
||||||
lfs_t *lfs = (lfs_t*)p;
|
lfs_t *lfs = (lfs_t*)p;
|
||||||
lfs_block_t off = ((block - lfs->free.off)
|
lfs_block_t off = ((block - lfs->free.off)
|
||||||
@@ -480,6 +495,7 @@ static int lfs_alloc_lookahead(void *p, lfs_block_t block) {
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// indicate allocated blocks have been committed into the filesystem, this
|
// indicate allocated blocks have been committed into the filesystem, this
|
||||||
// is to prevent blocks from being garbage collected in the middle of a
|
// is to prevent blocks from being garbage collected in the middle of a
|
||||||
@@ -496,6 +512,7 @@ static void lfs_alloc_drop(lfs_t *lfs) {
|
|||||||
lfs_alloc_ack(lfs);
|
lfs_alloc_ack(lfs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) {
|
static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) {
|
||||||
while (true) {
|
while (true) {
|
||||||
while (lfs->free.i != lfs->free.size) {
|
while (lfs->free.i != lfs->free.size) {
|
||||||
@@ -541,6 +558,7 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// Metadata pair and directory operations ///
|
/// Metadata pair and directory operations ///
|
||||||
static lfs_stag_t lfs_dir_getslice(lfs_t *lfs, const lfs_mdir_t *dir,
|
static lfs_stag_t lfs_dir_getslice(lfs_t *lfs, const lfs_mdir_t *dir,
|
||||||
@@ -673,6 +691,7 @@ static int lfs_dir_getread(lfs_t *lfs, const lfs_mdir_t *dir,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static int lfs_dir_traverse_filter(void *p,
|
static int lfs_dir_traverse_filter(void *p,
|
||||||
lfs_tag_t tag, const void *buffer) {
|
lfs_tag_t tag, const void *buffer) {
|
||||||
lfs_tag_t *filtertag = p;
|
lfs_tag_t *filtertag = p;
|
||||||
@@ -700,7 +719,9 @@ static int lfs_dir_traverse_filter(void *p,
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static int lfs_dir_traverse(lfs_t *lfs,
|
static int lfs_dir_traverse(lfs_t *lfs,
|
||||||
const lfs_mdir_t *dir, lfs_off_t off, lfs_tag_t ptag,
|
const lfs_mdir_t *dir, lfs_off_t off, lfs_tag_t ptag,
|
||||||
const struct lfs_mattr *attrs, int attrcount,
|
const struct lfs_mattr *attrs, int attrcount,
|
||||||
@@ -794,6 +815,7 @@ static int lfs_dir_traverse(lfs_t *lfs,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static lfs_stag_t lfs_dir_fetchmatch(lfs_t *lfs,
|
static lfs_stag_t lfs_dir_fetchmatch(lfs_t *lfs,
|
||||||
lfs_mdir_t *dir, const lfs_block_t pair[2],
|
lfs_mdir_t *dir, const lfs_block_t pair[2],
|
||||||
@@ -1233,6 +1255,7 @@ struct lfs_commit {
|
|||||||
lfs_off_t end;
|
lfs_off_t end;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static int lfs_dir_commitprog(lfs_t *lfs, struct lfs_commit *commit,
|
static int lfs_dir_commitprog(lfs_t *lfs, struct lfs_commit *commit,
|
||||||
const void *buffer, lfs_size_t size) {
|
const void *buffer, lfs_size_t size) {
|
||||||
int err = lfs_bd_prog(lfs,
|
int err = lfs_bd_prog(lfs,
|
||||||
@@ -1247,7 +1270,9 @@ static int lfs_dir_commitprog(lfs_t *lfs, struct lfs_commit *commit,
|
|||||||
commit->off += size;
|
commit->off += size;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static int lfs_dir_commitattr(lfs_t *lfs, struct lfs_commit *commit,
|
static int lfs_dir_commitattr(lfs_t *lfs, struct lfs_commit *commit,
|
||||||
lfs_tag_t tag, const void *buffer) {
|
lfs_tag_t tag, const void *buffer) {
|
||||||
// check if we fit
|
// check if we fit
|
||||||
@@ -1292,7 +1317,9 @@ static int lfs_dir_commitattr(lfs_t *lfs, struct lfs_commit *commit,
|
|||||||
commit->ptag = tag & 0x7fffffff;
|
commit->ptag = tag & 0x7fffffff;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static int lfs_dir_commitcrc(lfs_t *lfs, struct lfs_commit *commit) {
|
static int lfs_dir_commitcrc(lfs_t *lfs, struct lfs_commit *commit) {
|
||||||
// align to program units
|
// align to program units
|
||||||
const lfs_off_t end = lfs_alignup(commit->off + 2*sizeof(uint32_t),
|
const lfs_off_t end = lfs_alignup(commit->off + 2*sizeof(uint32_t),
|
||||||
@@ -1392,7 +1419,9 @@ static int lfs_dir_commitcrc(lfs_t *lfs, struct lfs_commit *commit) {
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static int lfs_dir_alloc(lfs_t *lfs, lfs_mdir_t *dir) {
|
static int lfs_dir_alloc(lfs_t *lfs, lfs_mdir_t *dir) {
|
||||||
// allocate pair of dir blocks (backwards, so we write block 1 first)
|
// allocate pair of dir blocks (backwards, so we write block 1 first)
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
@@ -1430,7 +1459,9 @@ static int lfs_dir_alloc(lfs_t *lfs, lfs_mdir_t *dir) {
|
|||||||
// don't write out yet, let caller take care of that
|
// don't write out yet, let caller take care of that
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static int lfs_dir_drop(lfs_t *lfs, lfs_mdir_t *dir, lfs_mdir_t *tail) {
|
static int lfs_dir_drop(lfs_t *lfs, lfs_mdir_t *dir, lfs_mdir_t *tail) {
|
||||||
// steal state
|
// steal state
|
||||||
int err = lfs_dir_getgstate(lfs, tail, &lfs->gdelta);
|
int err = lfs_dir_getgstate(lfs, tail, &lfs->gdelta);
|
||||||
@@ -1449,7 +1480,9 @@ static int lfs_dir_drop(lfs_t *lfs, lfs_mdir_t *dir, lfs_mdir_t *tail) {
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static int lfs_dir_split(lfs_t *lfs,
|
static int lfs_dir_split(lfs_t *lfs,
|
||||||
lfs_mdir_t *dir, const struct lfs_mattr *attrs, int attrcount,
|
lfs_mdir_t *dir, const struct lfs_mattr *attrs, int attrcount,
|
||||||
lfs_mdir_t *source, uint16_t split, uint16_t end) {
|
lfs_mdir_t *source, uint16_t split, uint16_t end) {
|
||||||
@@ -1482,7 +1515,9 @@ static int lfs_dir_split(lfs_t *lfs,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static int lfs_dir_commit_size(void *p, lfs_tag_t tag, const void *buffer) {
|
static int lfs_dir_commit_size(void *p, lfs_tag_t tag, const void *buffer) {
|
||||||
lfs_size_t *size = p;
|
lfs_size_t *size = p;
|
||||||
(void)buffer;
|
(void)buffer;
|
||||||
@@ -1490,17 +1525,23 @@ static int lfs_dir_commit_size(void *p, lfs_tag_t tag, const void *buffer) {
|
|||||||
*size += lfs_tag_dsize(tag);
|
*size += lfs_tag_dsize(tag);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
struct lfs_dir_commit_commit {
|
struct lfs_dir_commit_commit {
|
||||||
lfs_t *lfs;
|
lfs_t *lfs;
|
||||||
struct lfs_commit *commit;
|
struct lfs_commit *commit;
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static int lfs_dir_commit_commit(void *p, lfs_tag_t tag, const void *buffer) {
|
static int lfs_dir_commit_commit(void *p, lfs_tag_t tag, const void *buffer) {
|
||||||
struct lfs_dir_commit_commit *commit = p;
|
struct lfs_dir_commit_commit *commit = p;
|
||||||
return lfs_dir_commitattr(commit->lfs, commit->commit, tag, buffer);
|
return lfs_dir_commitattr(commit->lfs, commit->commit, tag, buffer);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static int lfs_dir_compact(lfs_t *lfs,
|
static int lfs_dir_compact(lfs_t *lfs,
|
||||||
lfs_mdir_t *dir, const struct lfs_mattr *attrs, int attrcount,
|
lfs_mdir_t *dir, const struct lfs_mattr *attrs, int attrcount,
|
||||||
lfs_mdir_t *source, uint16_t begin, uint16_t end) {
|
lfs_mdir_t *source, uint16_t begin, uint16_t end) {
|
||||||
@@ -1755,7 +1796,9 @@ relocate:
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir,
|
static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir,
|
||||||
const struct lfs_mattr *attrs, int attrcount) {
|
const struct lfs_mattr *attrs, int attrcount) {
|
||||||
// check for any inline files that aren't RAM backed and
|
// check for any inline files that aren't RAM backed and
|
||||||
@@ -1943,9 +1986,11 @@ compact:
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/// Top level directory operations ///
|
/// Top level directory operations ///
|
||||||
|
#ifndef LFS_READONLY
|
||||||
int lfs_mkdir(lfs_t *lfs, const char *path) {
|
int lfs_mkdir(lfs_t *lfs, const char *path) {
|
||||||
LFS_TRACE("lfs_mkdir(%p, \"%s\")", (void*)lfs, path);
|
LFS_TRACE("lfs_mkdir(%p, \"%s\")", (void*)lfs, path);
|
||||||
// deorphan if we haven't yet, needed at most once after poweron
|
// deorphan if we haven't yet, needed at most once after poweron
|
||||||
@@ -2044,6 +2089,7 @@ int lfs_mkdir(lfs_t *lfs, const char *path) {
|
|||||||
LFS_TRACE("lfs_mkdir -> %d", 0);
|
LFS_TRACE("lfs_mkdir -> %d", 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path) {
|
int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path) {
|
||||||
LFS_TRACE("lfs_dir_open(%p, %p, \"%s\")", (void*)lfs, (void*)dir, path);
|
LFS_TRACE("lfs_dir_open(%p, %p, \"%s\")", (void*)lfs, (void*)dir, path);
|
||||||
@@ -2273,6 +2319,7 @@ static int lfs_ctz_find(lfs_t *lfs,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static int lfs_ctz_extend(lfs_t *lfs,
|
static int lfs_ctz_extend(lfs_t *lfs,
|
||||||
lfs_cache_t *pcache, lfs_cache_t *rcache,
|
lfs_cache_t *pcache, lfs_cache_t *rcache,
|
||||||
lfs_block_t head, lfs_size_t size,
|
lfs_block_t head, lfs_size_t size,
|
||||||
@@ -2370,6 +2417,7 @@ relocate:
|
|||||||
lfs_cache_drop(lfs, pcache);
|
lfs_cache_drop(lfs, pcache);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int lfs_ctz_traverse(lfs_t *lfs,
|
static int lfs_ctz_traverse(lfs_t *lfs,
|
||||||
const lfs_cache_t *pcache, lfs_cache_t *rcache,
|
const lfs_cache_t *pcache, lfs_cache_t *rcache,
|
||||||
@@ -2425,6 +2473,9 @@ int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file,
|
|||||||
(void*)cfg, cfg->buffer, (void*)cfg->attrs, cfg->attr_count);
|
(void*)cfg, cfg->buffer, (void*)cfg->attrs, cfg->attr_count);
|
||||||
LFS_ASSERT(!lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file));
|
LFS_ASSERT(!lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file));
|
||||||
|
|
||||||
|
#ifdef LFS_READONLY
|
||||||
|
LFS_ASSERT((flags & 3) == LFS_O_RDONLY);
|
||||||
|
#else
|
||||||
// deorphan if we haven't yet, needed at most once after poweron
|
// deorphan if we haven't yet, needed at most once after poweron
|
||||||
if ((flags & LFS_O_RDWR) != LFS_O_RDONLY) {
|
if ((flags & LFS_O_RDWR) != LFS_O_RDONLY) {
|
||||||
int err = lfs_fs_forceconsistency(lfs);
|
int err = lfs_fs_forceconsistency(lfs);
|
||||||
@@ -2433,6 +2484,7 @@ int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// setup simple file details
|
// setup simple file details
|
||||||
int err;
|
int err;
|
||||||
@@ -2453,6 +2505,11 @@ int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file,
|
|||||||
file->type = LFS_TYPE_REG;
|
file->type = LFS_TYPE_REG;
|
||||||
lfs_mlist_append(lfs, (struct lfs_mlist *)file);
|
lfs_mlist_append(lfs, (struct lfs_mlist *)file);
|
||||||
|
|
||||||
|
#ifdef LFS_READONLY
|
||||||
|
if (tag == LFS_ERR_NOENT) {
|
||||||
|
err = LFS_ERR_NOENT;
|
||||||
|
goto cleanup;
|
||||||
|
#else
|
||||||
if (tag == LFS_ERR_NOENT) {
|
if (tag == LFS_ERR_NOENT) {
|
||||||
if (!(flags & LFS_O_CREAT)) {
|
if (!(flags & LFS_O_CREAT)) {
|
||||||
err = LFS_ERR_NOENT;
|
err = LFS_ERR_NOENT;
|
||||||
@@ -2480,13 +2537,16 @@ int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file,
|
|||||||
} else if (flags & LFS_O_EXCL) {
|
} else if (flags & LFS_O_EXCL) {
|
||||||
err = LFS_ERR_EXIST;
|
err = LFS_ERR_EXIST;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
#endif
|
||||||
} else if (lfs_tag_type3(tag) != LFS_TYPE_REG) {
|
} else if (lfs_tag_type3(tag) != LFS_TYPE_REG) {
|
||||||
err = LFS_ERR_ISDIR;
|
err = LFS_ERR_ISDIR;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
#ifndef LFS_READONLY
|
||||||
} else if (flags & LFS_O_TRUNC) {
|
} else if (flags & LFS_O_TRUNC) {
|
||||||
// truncate if requested
|
// truncate if requested
|
||||||
tag = LFS_MKTAG(LFS_TYPE_INLINESTRUCT, file->id, 0);
|
tag = LFS_MKTAG(LFS_TYPE_INLINESTRUCT, file->id, 0);
|
||||||
file->flags |= LFS_F_DIRTY;
|
file->flags |= LFS_F_DIRTY;
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
// try to load what's on disk, if it's inlined we'll fix it later
|
// try to load what's on disk, if it's inlined we'll fix it later
|
||||||
tag = lfs_dir_get(lfs, &file->m, LFS_MKTAG(0x700, 0x3ff, 0),
|
tag = lfs_dir_get(lfs, &file->m, LFS_MKTAG(0x700, 0x3ff, 0),
|
||||||
@@ -2500,7 +2560,8 @@ int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file,
|
|||||||
|
|
||||||
// fetch attrs
|
// fetch attrs
|
||||||
for (unsigned i = 0; i < file->cfg->attr_count; i++) {
|
for (unsigned i = 0; i < file->cfg->attr_count; i++) {
|
||||||
if ((file->flags & LFS_O_RDWR) != LFS_O_WRONLY) {
|
// if opened for read / read-write operations
|
||||||
|
if ((file->flags & LFS_O_RDONLY) == LFS_O_RDONLY) {
|
||||||
lfs_stag_t res = lfs_dir_get(lfs, &file->m,
|
lfs_stag_t res = lfs_dir_get(lfs, &file->m,
|
||||||
LFS_MKTAG(0x7ff, 0x3ff, 0),
|
LFS_MKTAG(0x7ff, 0x3ff, 0),
|
||||||
LFS_MKTAG(LFS_TYPE_USERATTR + file->cfg->attrs[i].type,
|
LFS_MKTAG(LFS_TYPE_USERATTR + file->cfg->attrs[i].type,
|
||||||
@@ -2512,7 +2573,9 @@ int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((file->flags & LFS_O_RDWR) != LFS_O_RDONLY) {
|
#ifndef LFS_READONLY
|
||||||
|
// if opened for write / read-write operations
|
||||||
|
if ((file->flags & LFS_O_WRONLY) == LFS_O_WRONLY) {
|
||||||
if (file->cfg->attrs[i].size > lfs->attr_max) {
|
if (file->cfg->attrs[i].size > lfs->attr_max) {
|
||||||
err = LFS_ERR_NOSPC;
|
err = LFS_ERR_NOSPC;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@@ -2520,6 +2583,7 @@ int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file,
|
|||||||
|
|
||||||
file->flags |= LFS_F_DIRTY;
|
file->flags |= LFS_F_DIRTY;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate buffer if needed
|
// allocate buffer if needed
|
||||||
@@ -2564,7 +2628,9 @@ int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file,
|
|||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
// clean up lingering resources
|
// clean up lingering resources
|
||||||
|
#ifndef LFS_READONLY
|
||||||
file->flags |= LFS_F_ERRED;
|
file->flags |= LFS_F_ERRED;
|
||||||
|
#endif
|
||||||
lfs_file_close(lfs, file);
|
lfs_file_close(lfs, file);
|
||||||
LFS_TRACE("lfs_file_opencfg -> %d", err);
|
LFS_TRACE("lfs_file_opencfg -> %d", err);
|
||||||
return err;
|
return err;
|
||||||
@@ -2584,7 +2650,11 @@ int lfs_file_close(lfs_t *lfs, lfs_file_t *file) {
|
|||||||
LFS_TRACE("lfs_file_close(%p, %p)", (void*)lfs, (void*)file);
|
LFS_TRACE("lfs_file_close(%p, %p)", (void*)lfs, (void*)file);
|
||||||
LFS_ASSERT(file->flags & LFS_F_OPENED);
|
LFS_ASSERT(file->flags & LFS_F_OPENED);
|
||||||
|
|
||||||
|
#ifdef LFS_READONLY
|
||||||
|
int err = 0;
|
||||||
|
#else
|
||||||
int err = lfs_file_sync(lfs, file);
|
int err = lfs_file_sync(lfs, file);
|
||||||
|
#endif
|
||||||
|
|
||||||
// remove from list of mdirs
|
// remove from list of mdirs
|
||||||
lfs_mlist_remove(lfs, (struct lfs_mlist*)file);
|
lfs_mlist_remove(lfs, (struct lfs_mlist*)file);
|
||||||
@@ -2599,6 +2669,8 @@ int lfs_file_close(lfs_t *lfs, lfs_file_t *file) {
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static int lfs_file_relocate(lfs_t *lfs, lfs_file_t *file) {
|
static int lfs_file_relocate(lfs_t *lfs, lfs_file_t *file) {
|
||||||
LFS_ASSERT(file->flags & LFS_F_OPENED);
|
LFS_ASSERT(file->flags & LFS_F_OPENED);
|
||||||
|
|
||||||
@@ -2669,7 +2741,9 @@ relocate:
|
|||||||
lfs_cache_drop(lfs, &lfs->pcache);
|
lfs_cache_drop(lfs, &lfs->pcache);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static int lfs_file_outline(lfs_t *lfs, lfs_file_t *file) {
|
static int lfs_file_outline(lfs_t *lfs, lfs_file_t *file) {
|
||||||
file->off = file->pos;
|
file->off = file->pos;
|
||||||
lfs_alloc_ack(lfs);
|
lfs_alloc_ack(lfs);
|
||||||
@@ -2681,7 +2755,9 @@ static int lfs_file_outline(lfs_t *lfs, lfs_file_t *file) {
|
|||||||
file->flags &= ~LFS_F_INLINE;
|
file->flags &= ~LFS_F_INLINE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static int lfs_file_flush(lfs_t *lfs, lfs_file_t *file) {
|
static int lfs_file_flush(lfs_t *lfs, lfs_file_t *file) {
|
||||||
LFS_ASSERT(file->flags & LFS_F_OPENED);
|
LFS_ASSERT(file->flags & LFS_F_OPENED);
|
||||||
|
|
||||||
@@ -2761,7 +2837,9 @@ relocate:
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
int lfs_file_sync(lfs_t *lfs, lfs_file_t *file) {
|
int lfs_file_sync(lfs_t *lfs, lfs_file_t *file) {
|
||||||
LFS_TRACE("lfs_file_sync(%p, %p)", (void*)lfs, (void*)file);
|
LFS_TRACE("lfs_file_sync(%p, %p)", (void*)lfs, (void*)file);
|
||||||
LFS_ASSERT(file->flags & LFS_F_OPENED);
|
LFS_ASSERT(file->flags & LFS_F_OPENED);
|
||||||
@@ -2779,6 +2857,7 @@ int lfs_file_sync(lfs_t *lfs, lfs_file_t *file) {
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ((file->flags & LFS_F_DIRTY) &&
|
if ((file->flags & LFS_F_DIRTY) &&
|
||||||
!lfs_pair_isnull(file->m.pair)) {
|
!lfs_pair_isnull(file->m.pair)) {
|
||||||
// update dir entry
|
// update dir entry
|
||||||
@@ -2818,17 +2897,21 @@ int lfs_file_sync(lfs_t *lfs, lfs_file_t *file) {
|
|||||||
LFS_TRACE("lfs_file_sync -> %d", 0);
|
LFS_TRACE("lfs_file_sync -> %d", 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file,
|
lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file,
|
||||||
void *buffer, lfs_size_t size) {
|
void *buffer, lfs_size_t size) {
|
||||||
LFS_TRACE("lfs_file_read(%p, %p, %p, %"PRIu32")",
|
LFS_TRACE("lfs_file_read(%p, %p, %p, %"PRIu32")",
|
||||||
(void*)lfs, (void*)file, buffer, size);
|
(void*)lfs, (void*)file, buffer, size);
|
||||||
LFS_ASSERT(file->flags & LFS_F_OPENED);
|
LFS_ASSERT(file->flags & LFS_F_OPENED);
|
||||||
|
#ifndef LFS_READONLY
|
||||||
LFS_ASSERT((file->flags & LFS_O_RDWR) != LFS_O_WRONLY);
|
LFS_ASSERT((file->flags & LFS_O_RDWR) != LFS_O_WRONLY);
|
||||||
|
#endif
|
||||||
|
|
||||||
uint8_t *data = buffer;
|
uint8_t *data = buffer;
|
||||||
lfs_size_t nsize = size;
|
lfs_size_t nsize = size;
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
if (file->flags & LFS_F_WRITING) {
|
if (file->flags & LFS_F_WRITING) {
|
||||||
// flush out any writes
|
// flush out any writes
|
||||||
int err = lfs_file_flush(lfs, file);
|
int err = lfs_file_flush(lfs, file);
|
||||||
@@ -2837,6 +2920,7 @@ lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (file->pos >= file->ctz.size) {
|
if (file->pos >= file->ctz.size) {
|
||||||
// eof if past end
|
// eof if past end
|
||||||
@@ -2899,6 +2983,7 @@ lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file,
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
|
lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
|
||||||
const void *buffer, lfs_size_t size) {
|
const void *buffer, lfs_size_t size) {
|
||||||
LFS_TRACE("lfs_file_write(%p, %p, %p, %"PRIu32")",
|
LFS_TRACE("lfs_file_write(%p, %p, %p, %"PRIu32")",
|
||||||
@@ -3029,6 +3114,7 @@ relocate:
|
|||||||
LFS_TRACE("lfs_file_write -> %"PRId32, size);
|
LFS_TRACE("lfs_file_write -> %"PRId32, size);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
lfs_soff_t lfs_file_seek(lfs_t *lfs, lfs_file_t *file,
|
lfs_soff_t lfs_file_seek(lfs_t *lfs, lfs_file_t *file,
|
||||||
lfs_soff_t off, int whence) {
|
lfs_soff_t off, int whence) {
|
||||||
@@ -3036,12 +3122,14 @@ lfs_soff_t lfs_file_seek(lfs_t *lfs, lfs_file_t *file,
|
|||||||
(void*)lfs, (void*)file, off, whence);
|
(void*)lfs, (void*)file, off, whence);
|
||||||
LFS_ASSERT(file->flags & LFS_F_OPENED);
|
LFS_ASSERT(file->flags & LFS_F_OPENED);
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
// write out everything beforehand, may be noop if rdonly
|
// write out everything beforehand, may be noop if rdonly
|
||||||
int err = lfs_file_flush(lfs, file);
|
int err = lfs_file_flush(lfs, file);
|
||||||
if (err) {
|
if (err) {
|
||||||
LFS_TRACE("lfs_file_seek -> %d", err);
|
LFS_TRACE("lfs_file_seek -> %d", err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// find new pos
|
// find new pos
|
||||||
lfs_off_t npos = file->pos;
|
lfs_off_t npos = file->pos;
|
||||||
@@ -3065,6 +3153,7 @@ lfs_soff_t lfs_file_seek(lfs_t *lfs, lfs_file_t *file,
|
|||||||
return npos;
|
return npos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
int lfs_file_truncate(lfs_t *lfs, lfs_file_t *file, lfs_off_t size) {
|
int lfs_file_truncate(lfs_t *lfs, lfs_file_t *file, lfs_off_t size) {
|
||||||
LFS_TRACE("lfs_file_truncate(%p, %p, %"PRIu32")",
|
LFS_TRACE("lfs_file_truncate(%p, %p, %"PRIu32")",
|
||||||
(void*)lfs, (void*)file, size);
|
(void*)lfs, (void*)file, size);
|
||||||
@@ -3128,6 +3217,7 @@ int lfs_file_truncate(lfs_t *lfs, lfs_file_t *file, lfs_off_t size) {
|
|||||||
LFS_TRACE("lfs_file_truncate -> %d", 0);
|
LFS_TRACE("lfs_file_truncate -> %d", 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
lfs_soff_t lfs_file_tell(lfs_t *lfs, lfs_file_t *file) {
|
lfs_soff_t lfs_file_tell(lfs_t *lfs, lfs_file_t *file) {
|
||||||
LFS_TRACE("lfs_file_tell(%p, %p)", (void*)lfs, (void*)file);
|
LFS_TRACE("lfs_file_tell(%p, %p)", (void*)lfs, (void*)file);
|
||||||
@@ -3153,15 +3243,17 @@ lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file) {
|
|||||||
LFS_TRACE("lfs_file_size(%p, %p)", (void*)lfs, (void*)file);
|
LFS_TRACE("lfs_file_size(%p, %p)", (void*)lfs, (void*)file);
|
||||||
LFS_ASSERT(file->flags & LFS_F_OPENED);
|
LFS_ASSERT(file->flags & LFS_F_OPENED);
|
||||||
(void)lfs;
|
(void)lfs;
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
if (file->flags & LFS_F_WRITING) {
|
if (file->flags & LFS_F_WRITING) {
|
||||||
LFS_TRACE("lfs_file_size -> %"PRId32,
|
LFS_TRACE("lfs_file_size -> %"PRId32,
|
||||||
lfs_max(file->pos, file->ctz.size));
|
lfs_max(file->pos, file->ctz.size));
|
||||||
return lfs_max(file->pos, file->ctz.size);
|
return lfs_max(file->pos, file->ctz.size);
|
||||||
} else {
|
}
|
||||||
|
#endif
|
||||||
LFS_TRACE("lfs_file_size -> %"PRId32, file->ctz.size);
|
LFS_TRACE("lfs_file_size -> %"PRId32, file->ctz.size);
|
||||||
return file->ctz.size;
|
return file->ctz.size;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// General fs operations ///
|
/// General fs operations ///
|
||||||
@@ -3179,8 +3271,10 @@ int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info) {
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
int lfs_remove(lfs_t *lfs, const char *path) {
|
int lfs_remove(lfs_t *lfs, const char *path) {
|
||||||
LFS_TRACE("lfs_remove(%p, \"%s\")", (void*)lfs, path);
|
LFS_TRACE("lfs_remove(%p, \"%s\")", (void*)lfs, path);
|
||||||
|
|
||||||
// deorphan if we haven't yet, needed at most once after poweron
|
// deorphan if we haven't yet, needed at most once after poweron
|
||||||
int err = lfs_fs_forceconsistency(lfs);
|
int err = lfs_fs_forceconsistency(lfs);
|
||||||
if (err) {
|
if (err) {
|
||||||
@@ -3259,7 +3353,9 @@ int lfs_remove(lfs_t *lfs, const char *path) {
|
|||||||
LFS_TRACE("lfs_remove -> %d", 0);
|
LFS_TRACE("lfs_remove -> %d", 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
|
int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
|
||||||
LFS_TRACE("lfs_rename(%p, \"%s\", \"%s\")", (void*)lfs, oldpath, newpath);
|
LFS_TRACE("lfs_rename(%p, \"%s\", \"%s\")", (void*)lfs, oldpath, newpath);
|
||||||
|
|
||||||
@@ -3404,6 +3500,7 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
|
|||||||
LFS_TRACE("lfs_rename -> %d", 0);
|
LFS_TRACE("lfs_rename -> %d", 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
lfs_ssize_t lfs_getattr(lfs_t *lfs, const char *path,
|
lfs_ssize_t lfs_getattr(lfs_t *lfs, const char *path,
|
||||||
uint8_t type, void *buffer, lfs_size_t size) {
|
uint8_t type, void *buffer, lfs_size_t size) {
|
||||||
@@ -3446,6 +3543,7 @@ lfs_ssize_t lfs_getattr(lfs_t *lfs, const char *path,
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static int lfs_commitattr(lfs_t *lfs, const char *path,
|
static int lfs_commitattr(lfs_t *lfs, const char *path,
|
||||||
uint8_t type, const void *buffer, lfs_size_t size) {
|
uint8_t type, const void *buffer, lfs_size_t size) {
|
||||||
lfs_mdir_t cwd;
|
lfs_mdir_t cwd;
|
||||||
@@ -3467,7 +3565,9 @@ static int lfs_commitattr(lfs_t *lfs, const char *path,
|
|||||||
return lfs_dir_commit(lfs, &cwd, LFS_MKATTRS(
|
return lfs_dir_commit(lfs, &cwd, LFS_MKATTRS(
|
||||||
{LFS_MKTAG(LFS_TYPE_USERATTR + type, id, size), buffer}));
|
{LFS_MKTAG(LFS_TYPE_USERATTR + type, id, size), buffer}));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
int lfs_setattr(lfs_t *lfs, const char *path,
|
int lfs_setattr(lfs_t *lfs, const char *path,
|
||||||
uint8_t type, const void *buffer, lfs_size_t size) {
|
uint8_t type, const void *buffer, lfs_size_t size) {
|
||||||
LFS_TRACE("lfs_setattr(%p, \"%s\", %"PRIu8", %p, %"PRIu32")",
|
LFS_TRACE("lfs_setattr(%p, \"%s\", %"PRIu8", %p, %"PRIu32")",
|
||||||
@@ -3481,13 +3581,16 @@ int lfs_setattr(lfs_t *lfs, const char *path,
|
|||||||
LFS_TRACE("lfs_setattr -> %d", err);
|
LFS_TRACE("lfs_setattr -> %d", err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
int lfs_removeattr(lfs_t *lfs, const char *path, uint8_t type) {
|
int lfs_removeattr(lfs_t *lfs, const char *path, uint8_t type) {
|
||||||
LFS_TRACE("lfs_removeattr(%p, \"%s\", %"PRIu8")", (void*)lfs, path, type);
|
LFS_TRACE("lfs_removeattr(%p, \"%s\", %"PRIu8")", (void*)lfs, path, type);
|
||||||
int err = lfs_commitattr(lfs, path, type, NULL, 0x3ff);
|
int err = lfs_commitattr(lfs, path, type, NULL, 0x3ff);
|
||||||
LFS_TRACE("lfs_removeattr -> %d", err);
|
LFS_TRACE("lfs_removeattr -> %d", err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/// Filesystem operations ///
|
/// Filesystem operations ///
|
||||||
@@ -3615,6 +3718,7 @@ static int lfs_deinit(lfs_t *lfs) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
|
int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
|
||||||
LFS_TRACE("lfs_format(%p, %p {.context=%p, "
|
LFS_TRACE("lfs_format(%p, %p {.context=%p, "
|
||||||
".read=%p, .prog=%p, .erase=%p, .sync=%p, "
|
".read=%p, .prog=%p, .erase=%p, .sync=%p, "
|
||||||
@@ -3632,6 +3736,7 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
|
|||||||
cfg->block_cycles, cfg->cache_size, cfg->lookahead_size,
|
cfg->block_cycles, cfg->cache_size, cfg->lookahead_size,
|
||||||
cfg->read_buffer, cfg->prog_buffer, cfg->lookahead_buffer,
|
cfg->read_buffer, cfg->prog_buffer, cfg->lookahead_buffer,
|
||||||
cfg->name_max, cfg->file_max, cfg->attr_max);
|
cfg->name_max, cfg->file_max, cfg->attr_max);
|
||||||
|
|
||||||
int err = 0;
|
int err = 0;
|
||||||
{
|
{
|
||||||
err = lfs_init(lfs, cfg);
|
err = lfs_init(lfs, cfg);
|
||||||
@@ -3694,7 +3799,9 @@ cleanup:
|
|||||||
lfs_deinit(lfs);
|
lfs_deinit(lfs);
|
||||||
LFS_TRACE("lfs_format -> %d", err);
|
LFS_TRACE("lfs_format -> %d", err);
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
|
int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
|
||||||
LFS_TRACE("lfs_mount(%p, %p {.context=%p, "
|
LFS_TRACE("lfs_mount(%p, %p {.context=%p, "
|
||||||
@@ -3921,6 +4028,7 @@ int lfs_fs_traverseraw(lfs_t *lfs,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
// iterate over any open files
|
// iterate over any open files
|
||||||
for (lfs_file_t *f = (lfs_file_t*)lfs->mlist; f; f = f->next) {
|
for (lfs_file_t *f = (lfs_file_t*)lfs->mlist; f; f = f->next) {
|
||||||
if (f->type != LFS_TYPE_REG) {
|
if (f->type != LFS_TYPE_REG) {
|
||||||
@@ -3943,6 +4051,7 @@ int lfs_fs_traverseraw(lfs_t *lfs,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -3956,6 +4065,7 @@ int lfs_fs_traverse(lfs_t *lfs,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static int lfs_fs_pred(lfs_t *lfs,
|
static int lfs_fs_pred(lfs_t *lfs,
|
||||||
const lfs_block_t pair[2], lfs_mdir_t *pdir) {
|
const lfs_block_t pair[2], lfs_mdir_t *pdir) {
|
||||||
// iterate over all directory directory entries
|
// iterate over all directory directory entries
|
||||||
@@ -3981,12 +4091,16 @@ static int lfs_fs_pred(lfs_t *lfs,
|
|||||||
|
|
||||||
return LFS_ERR_NOENT;
|
return LFS_ERR_NOENT;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
struct lfs_fs_parent_match {
|
struct lfs_fs_parent_match {
|
||||||
lfs_t *lfs;
|
lfs_t *lfs;
|
||||||
const lfs_block_t pair[2];
|
const lfs_block_t pair[2];
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static int lfs_fs_parent_match(void *data,
|
static int lfs_fs_parent_match(void *data,
|
||||||
lfs_tag_t tag, const void *buffer) {
|
lfs_tag_t tag, const void *buffer) {
|
||||||
struct lfs_fs_parent_match *find = data;
|
struct lfs_fs_parent_match *find = data;
|
||||||
@@ -4005,7 +4119,9 @@ static int lfs_fs_parent_match(void *data,
|
|||||||
lfs_pair_fromle32(child);
|
lfs_pair_fromle32(child);
|
||||||
return (lfs_pair_cmp(child, find->pair) == 0) ? LFS_CMP_EQ : LFS_CMP_LT;
|
return (lfs_pair_cmp(child, find->pair) == 0) ? LFS_CMP_EQ : LFS_CMP_LT;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static lfs_stag_t lfs_fs_parent(lfs_t *lfs, const lfs_block_t pair[2],
|
static lfs_stag_t lfs_fs_parent(lfs_t *lfs, const lfs_block_t pair[2],
|
||||||
lfs_mdir_t *parent) {
|
lfs_mdir_t *parent) {
|
||||||
// use fetchmatch with callback to find pairs
|
// use fetchmatch with callback to find pairs
|
||||||
@@ -4032,7 +4148,9 @@ static lfs_stag_t lfs_fs_parent(lfs_t *lfs, const lfs_block_t pair[2],
|
|||||||
|
|
||||||
return LFS_ERR_NOENT;
|
return LFS_ERR_NOENT;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static int lfs_fs_relocate(lfs_t *lfs,
|
static int lfs_fs_relocate(lfs_t *lfs,
|
||||||
const lfs_block_t oldpair[2], lfs_block_t newpair[2]) {
|
const lfs_block_t oldpair[2], lfs_block_t newpair[2]) {
|
||||||
// update internal root
|
// update internal root
|
||||||
@@ -4127,14 +4245,18 @@ static int lfs_fs_relocate(lfs_t *lfs,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static void lfs_fs_preporphans(lfs_t *lfs, int8_t orphans) {
|
static void lfs_fs_preporphans(lfs_t *lfs, int8_t orphans) {
|
||||||
LFS_ASSERT(lfs_tag_size(lfs->gstate.tag) > 0 || orphans >= 0);
|
LFS_ASSERT(lfs_tag_size(lfs->gstate.tag) > 0 || orphans >= 0);
|
||||||
lfs->gstate.tag += orphans;
|
lfs->gstate.tag += orphans;
|
||||||
lfs->gstate.tag = ((lfs->gstate.tag & ~LFS_MKTAG(0x800, 0, 0)) |
|
lfs->gstate.tag = ((lfs->gstate.tag & ~LFS_MKTAG(0x800, 0, 0)) |
|
||||||
((uint32_t)lfs_gstate_hasorphans(&lfs->gstate) << 31));
|
((uint32_t)lfs_gstate_hasorphans(&lfs->gstate) << 31));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static void lfs_fs_prepmove(lfs_t *lfs,
|
static void lfs_fs_prepmove(lfs_t *lfs,
|
||||||
uint16_t id, const lfs_block_t pair[2]) {
|
uint16_t id, const lfs_block_t pair[2]) {
|
||||||
lfs->gstate.tag = ((lfs->gstate.tag & ~LFS_MKTAG(0x7ff, 0x3ff, 0)) |
|
lfs->gstate.tag = ((lfs->gstate.tag & ~LFS_MKTAG(0x7ff, 0x3ff, 0)) |
|
||||||
@@ -4142,7 +4264,9 @@ static void lfs_fs_prepmove(lfs_t *lfs,
|
|||||||
lfs->gstate.pair[0] = (id != 0x3ff) ? pair[0] : 0;
|
lfs->gstate.pair[0] = (id != 0x3ff) ? pair[0] : 0;
|
||||||
lfs->gstate.pair[1] = (id != 0x3ff) ? pair[1] : 0;
|
lfs->gstate.pair[1] = (id != 0x3ff) ? pair[1] : 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static int lfs_fs_demove(lfs_t *lfs) {
|
static int lfs_fs_demove(lfs_t *lfs) {
|
||||||
if (!lfs_gstate_hasmove(&lfs->gdisk)) {
|
if (!lfs_gstate_hasmove(&lfs->gdisk)) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -4172,7 +4296,9 @@ static int lfs_fs_demove(lfs_t *lfs) {
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static int lfs_fs_deorphan(lfs_t *lfs) {
|
static int lfs_fs_deorphan(lfs_t *lfs) {
|
||||||
if (!lfs_gstate_hasorphans(&lfs->gstate)) {
|
if (!lfs_gstate_hasorphans(&lfs->gstate)) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -4246,7 +4372,9 @@ static int lfs_fs_deorphan(lfs_t *lfs) {
|
|||||||
lfs_fs_preporphans(lfs, -lfs_gstate_getorphans(&lfs->gstate));
|
lfs_fs_preporphans(lfs, -lfs_gstate_getorphans(&lfs->gstate));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
static int lfs_fs_forceconsistency(lfs_t *lfs) {
|
static int lfs_fs_forceconsistency(lfs_t *lfs) {
|
||||||
int err = lfs_fs_demove(lfs);
|
int err = lfs_fs_demove(lfs);
|
||||||
if (err) {
|
if (err) {
|
||||||
@@ -4260,6 +4388,7 @@ static int lfs_fs_forceconsistency(lfs_t *lfs) {
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int lfs_fs_size_count(void *p, lfs_block_t block) {
|
static int lfs_fs_size_count(void *p, lfs_block_t block) {
|
||||||
(void)block;
|
(void)block;
|
||||||
|
|||||||
@@ -123,18 +123,24 @@ enum lfs_type {
|
|||||||
enum lfs_open_flags {
|
enum lfs_open_flags {
|
||||||
// open flags
|
// open flags
|
||||||
LFS_O_RDONLY = 1, // Open a file as read only
|
LFS_O_RDONLY = 1, // Open a file as read only
|
||||||
|
#ifndef LFS_READONLY
|
||||||
LFS_O_WRONLY = 2, // Open a file as write only
|
LFS_O_WRONLY = 2, // Open a file as write only
|
||||||
LFS_O_RDWR = 3, // Open a file as read and write
|
LFS_O_RDWR = 3, // Open a file as read and write
|
||||||
LFS_O_CREAT = 0x0100, // Create a file if it does not exist
|
LFS_O_CREAT = 0x0100, // Create a file if it does not exist
|
||||||
LFS_O_EXCL = 0x0200, // Fail if a file already exists
|
LFS_O_EXCL = 0x0200, // Fail if a file already exists
|
||||||
LFS_O_TRUNC = 0x0400, // Truncate the existing file to zero size
|
LFS_O_TRUNC = 0x0400, // Truncate the existing file to zero size
|
||||||
LFS_O_APPEND = 0x0800, // Move to end of file on every write
|
LFS_O_APPEND = 0x0800, // Move to end of file on every write
|
||||||
|
#endif
|
||||||
|
|
||||||
// internally used flags
|
// internally used flags
|
||||||
|
#ifndef LFS_READONLY
|
||||||
LFS_F_DIRTY = 0x010000, // File does not match storage
|
LFS_F_DIRTY = 0x010000, // File does not match storage
|
||||||
LFS_F_WRITING = 0x020000, // File has been written since last flush
|
LFS_F_WRITING = 0x020000, // File has been written since last flush
|
||||||
|
#endif
|
||||||
LFS_F_READING = 0x040000, // File has been read since last flush
|
LFS_F_READING = 0x040000, // File has been read since last flush
|
||||||
LFS_F_ERRED = 0x080000, // An error occured during write
|
#ifndef LFS_READONLY
|
||||||
|
LFS_F_ERRED = 0x080000, // An error occurred during write
|
||||||
|
#endif
|
||||||
LFS_F_INLINE = 0x100000, // Currently inlined in directory entry
|
LFS_F_INLINE = 0x100000, // Currently inlined in directory entry
|
||||||
LFS_F_OPENED = 0x200000, // File has been opened
|
LFS_F_OPENED = 0x200000, // File has been opened
|
||||||
};
|
};
|
||||||
@@ -399,6 +405,7 @@ typedef struct lfs {
|
|||||||
|
|
||||||
/// Filesystem functions ///
|
/// Filesystem functions ///
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
// Format a block device with the littlefs
|
// Format a block device with the littlefs
|
||||||
//
|
//
|
||||||
// Requires a littlefs object and config struct. This clobbers the littlefs
|
// Requires a littlefs object and config struct. This clobbers the littlefs
|
||||||
@@ -407,6 +414,7 @@ typedef struct lfs {
|
|||||||
//
|
//
|
||||||
// Returns a negative error code on failure.
|
// Returns a negative error code on failure.
|
||||||
int lfs_format(lfs_t *lfs, const struct lfs_config *config);
|
int lfs_format(lfs_t *lfs, const struct lfs_config *config);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Mounts a littlefs
|
// Mounts a littlefs
|
||||||
//
|
//
|
||||||
@@ -426,12 +434,15 @@ int lfs_unmount(lfs_t *lfs);
|
|||||||
|
|
||||||
/// General operations ///
|
/// General operations ///
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
// Removes a file or directory
|
// Removes a file or directory
|
||||||
//
|
//
|
||||||
// If removing a directory, the directory must be empty.
|
// If removing a directory, the directory must be empty.
|
||||||
// Returns a negative error code on failure.
|
// Returns a negative error code on failure.
|
||||||
int lfs_remove(lfs_t *lfs, const char *path);
|
int lfs_remove(lfs_t *lfs, const char *path);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
// Rename or move a file or directory
|
// Rename or move a file or directory
|
||||||
//
|
//
|
||||||
// If the destination exists, it must match the source in type.
|
// If the destination exists, it must match the source in type.
|
||||||
@@ -439,6 +450,7 @@ int lfs_remove(lfs_t *lfs, const char *path);
|
|||||||
//
|
//
|
||||||
// Returns a negative error code on failure.
|
// Returns a negative error code on failure.
|
||||||
int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath);
|
int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Find info about a file or directory
|
// Find info about a file or directory
|
||||||
//
|
//
|
||||||
@@ -461,6 +473,7 @@ int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info);
|
|||||||
lfs_ssize_t lfs_getattr(lfs_t *lfs, const char *path,
|
lfs_ssize_t lfs_getattr(lfs_t *lfs, const char *path,
|
||||||
uint8_t type, void *buffer, lfs_size_t size);
|
uint8_t type, void *buffer, lfs_size_t size);
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
// Set custom attributes
|
// Set custom attributes
|
||||||
//
|
//
|
||||||
// Custom attributes are uniquely identified by an 8-bit type and limited
|
// Custom attributes are uniquely identified by an 8-bit type and limited
|
||||||
@@ -470,13 +483,16 @@ lfs_ssize_t lfs_getattr(lfs_t *lfs, const char *path,
|
|||||||
// Returns a negative error code on failure.
|
// Returns a negative error code on failure.
|
||||||
int lfs_setattr(lfs_t *lfs, const char *path,
|
int lfs_setattr(lfs_t *lfs, const char *path,
|
||||||
uint8_t type, const void *buffer, lfs_size_t size);
|
uint8_t type, const void *buffer, lfs_size_t size);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
// Removes a custom attribute
|
// Removes a custom attribute
|
||||||
//
|
//
|
||||||
// If an attribute is not found, nothing happens.
|
// If an attribute is not found, nothing happens.
|
||||||
//
|
//
|
||||||
// Returns a negative error code on failure.
|
// Returns a negative error code on failure.
|
||||||
int lfs_removeattr(lfs_t *lfs, const char *path, uint8_t type);
|
int lfs_removeattr(lfs_t *lfs, const char *path, uint8_t type);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/// File operations ///
|
/// File operations ///
|
||||||
@@ -525,6 +541,7 @@ int lfs_file_sync(lfs_t *lfs, lfs_file_t *file);
|
|||||||
lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file,
|
lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file,
|
||||||
void *buffer, lfs_size_t size);
|
void *buffer, lfs_size_t size);
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
// Write data to file
|
// Write data to file
|
||||||
//
|
//
|
||||||
// Takes a buffer and size indicating the data to write. The file will not
|
// Takes a buffer and size indicating the data to write. The file will not
|
||||||
@@ -533,6 +550,7 @@ lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file,
|
|||||||
// Returns the number of bytes written, or a negative error code on failure.
|
// Returns the number of bytes written, or a negative error code on failure.
|
||||||
lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
|
lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
|
||||||
const void *buffer, lfs_size_t size);
|
const void *buffer, lfs_size_t size);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Change the position of the file
|
// Change the position of the file
|
||||||
//
|
//
|
||||||
@@ -541,10 +559,12 @@ lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
|
|||||||
lfs_soff_t lfs_file_seek(lfs_t *lfs, lfs_file_t *file,
|
lfs_soff_t lfs_file_seek(lfs_t *lfs, lfs_file_t *file,
|
||||||
lfs_soff_t off, int whence);
|
lfs_soff_t off, int whence);
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
// Truncates the size of the file to the specified size
|
// Truncates the size of the file to the specified size
|
||||||
//
|
//
|
||||||
// Returns a negative error code on failure.
|
// Returns a negative error code on failure.
|
||||||
int lfs_file_truncate(lfs_t *lfs, lfs_file_t *file, lfs_off_t size);
|
int lfs_file_truncate(lfs_t *lfs, lfs_file_t *file, lfs_off_t size);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Return the position of the file
|
// Return the position of the file
|
||||||
//
|
//
|
||||||
@@ -567,10 +587,12 @@ lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file);
|
|||||||
|
|
||||||
/// Directory operations ///
|
/// Directory operations ///
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
// Create a directory
|
// Create a directory
|
||||||
//
|
//
|
||||||
// Returns a negative error code on failure.
|
// Returns a negative error code on failure.
|
||||||
int lfs_mkdir(lfs_t *lfs, const char *path);
|
int lfs_mkdir(lfs_t *lfs, const char *path);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Open a directory
|
// Open a directory
|
||||||
//
|
//
|
||||||
@@ -632,6 +654,7 @@ lfs_ssize_t lfs_fs_size(lfs_t *lfs);
|
|||||||
// Returns a negative error code on failure.
|
// Returns a negative error code on failure.
|
||||||
int lfs_fs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data);
|
int lfs_fs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data);
|
||||||
|
|
||||||
|
#ifndef LFS_READONLY
|
||||||
#ifdef LFS_MIGRATE
|
#ifdef LFS_MIGRATE
|
||||||
// Attempts to migrate a previous version of littlefs
|
// Attempts to migrate a previous version of littlefs
|
||||||
//
|
//
|
||||||
@@ -646,6 +669,7 @@ int lfs_fs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data);
|
|||||||
// Returns a negative error code on failure.
|
// Returns a negative error code on failure.
|
||||||
int lfs_migrate(lfs_t *lfs, const struct lfs_config *cfg);
|
int lfs_migrate(lfs_t *lfs, const struct lfs_config *cfg);
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
Reference in New Issue
Block a user