summaryrefslogtreecommitdiffstatshomepage
path: root/lib/littlefs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/littlefs')
-rw-r--r--lib/littlefs/lfs1.c2
-rw-r--r--lib/littlefs/lfs2.c80
-rw-r--r--lib/littlefs/lfs2.h8
-rw-r--r--lib/littlefs/lfs2_util.h16
4 files changed, 69 insertions, 37 deletions
diff --git a/lib/littlefs/lfs1.c b/lib/littlefs/lfs1.c
index 6a3fd67001..ec18dc4702 100644
--- a/lib/littlefs/lfs1.c
+++ b/lib/littlefs/lfs1.c
@@ -2141,7 +2141,7 @@ int lfs1_format(lfs1_t *lfs1, const struct lfs1_config *cfg) {
.d.elen = sizeof(superblock.d) - sizeof(superblock.d.magic) - 4,
.d.nlen = sizeof(superblock.d.magic),
.d.version = LFS1_DISK_VERSION,
- .d.magic = {"littlefs"},
+ .d.magic = {'l', 'i', 't', 't', 'l', 'e', 'f', 's'},
.d.block_size = lfs1->cfg->block_size,
.d.block_count = lfs1->cfg->block_count,
.d.root = {lfs1->root[0], lfs1->root[1]},
diff --git a/lib/littlefs/lfs2.c b/lib/littlefs/lfs2.c
index f9ce2cf290..abdec19d7c 100644
--- a/lib/littlefs/lfs2.c
+++ b/lib/littlefs/lfs2.c
@@ -3932,7 +3932,9 @@ static int lfs2_remove_(lfs2_t *lfs2, const char *path) {
}
lfs2->mlist = dir.next;
- if (lfs2_tag_type3(tag) == LFS2_TYPE_DIR) {
+ if (lfs2_gstate_hasorphans(&lfs2->gstate)) {
+ LFS2_ASSERT(lfs2_tag_type3(tag) == LFS2_TYPE_DIR);
+
// fix orphan
err = lfs2_fs_preporphans(lfs2, -1);
if (err) {
@@ -4076,8 +4078,10 @@ static int lfs2_rename_(lfs2_t *lfs2, const char *oldpath, const char *newpath)
}
lfs2->mlist = prevdir.next;
- if (prevtag != LFS2_ERR_NOENT
- && lfs2_tag_type3(prevtag) == LFS2_TYPE_DIR) {
+ if (lfs2_gstate_hasorphans(&lfs2->gstate)) {
+ LFS2_ASSERT(prevtag != LFS2_ERR_NOENT
+ && lfs2_tag_type3(prevtag) == LFS2_TYPE_DIR);
+
// fix orphan
err = lfs2_fs_preporphans(lfs2, -1);
if (err) {
@@ -5233,40 +5237,64 @@ static int lfs2_fs_gc_(lfs2_t *lfs2) {
#endif
#ifndef LFS2_READONLY
+#ifdef LFS2_SHRINKNONRELOCATING
+static int lfs2_shrink_checkblock(void *data, lfs2_block_t block) {
+ lfs2_size_t threshold = *((lfs2_size_t*)data);
+ if (block >= threshold) {
+ return LFS2_ERR_NOTEMPTY;
+ }
+ return 0;
+}
+#endif
+
static int lfs2_fs_grow_(lfs2_t *lfs2, lfs2_size_t block_count) {
- // shrinking is not supported
- LFS2_ASSERT(block_count >= lfs2->block_count);
+ int err;
- if (block_count > lfs2->block_count) {
- lfs2->block_count = block_count;
+ if (block_count == lfs2->block_count) {
+ return 0;
+ }
- // fetch the root
- lfs2_mdir_t root;
- int err = lfs2_dir_fetch(lfs2, &root, lfs2->root);
+
+#ifndef LFS2_SHRINKNONRELOCATING
+ // shrinking is not supported
+ LFS2_ASSERT(block_count >= lfs2->block_count);
+#endif
+#ifdef LFS2_SHRINKNONRELOCATING
+ if (block_count < lfs2->block_count) {
+ err = lfs2_fs_traverse_(lfs2, lfs2_shrink_checkblock, &block_count, true);
if (err) {
return err;
}
+ }
+#endif
- // update the superblock
- lfs2_superblock_t superblock;
- lfs2_stag_t tag = lfs2_dir_get(lfs2, &root, LFS2_MKTAG(0x7ff, 0x3ff, 0),
- LFS2_MKTAG(LFS2_TYPE_INLINESTRUCT, 0, sizeof(superblock)),
- &superblock);
- if (tag < 0) {
- return tag;
- }
- lfs2_superblock_fromle32(&superblock);
+ lfs2->block_count = block_count;
- superblock.block_count = lfs2->block_count;
+ // fetch the root
+ lfs2_mdir_t root;
+ err = lfs2_dir_fetch(lfs2, &root, lfs2->root);
+ if (err) {
+ return err;
+ }
- lfs2_superblock_tole32(&superblock);
- err = lfs2_dir_commit(lfs2, &root, LFS2_MKATTRS(
- {tag, &superblock}));
- if (err) {
- return err;
- }
+ // update the superblock
+ lfs2_superblock_t superblock;
+ lfs2_stag_t tag = lfs2_dir_get(lfs2, &root, LFS2_MKTAG(0x7ff, 0x3ff, 0),
+ LFS2_MKTAG(LFS2_TYPE_INLINESTRUCT, 0, sizeof(superblock)),
+ &superblock);
+ if (tag < 0) {
+ return tag;
}
+ lfs2_superblock_fromle32(&superblock);
+
+ superblock.block_count = lfs2->block_count;
+ lfs2_superblock_tole32(&superblock);
+ err = lfs2_dir_commit(lfs2, &root, LFS2_MKATTRS(
+ {tag, &superblock}));
+ if (err) {
+ return err;
+ }
return 0;
}
#endif
diff --git a/lib/littlefs/lfs2.h b/lib/littlefs/lfs2.h
index f503fd00bc..77477aaff8 100644
--- a/lib/littlefs/lfs2.h
+++ b/lib/littlefs/lfs2.h
@@ -21,7 +21,7 @@ extern "C"
// Software library version
// Major (top-nibble), incremented on backwards incompatible changes
// Minor (bottom-nibble), incremented on feature additions
-#define LFS2_VERSION 0x0002000a
+#define LFS2_VERSION 0x0002000b
#define LFS2_VERSION_MAJOR (0xffff & (LFS2_VERSION >> 16))
#define LFS2_VERSION_MINOR (0xffff & (LFS2_VERSION >> 0))
@@ -766,7 +766,11 @@ int lfs2_fs_gc(lfs2_t *lfs2);
// Grows the filesystem to a new size, updating the superblock with the new
// block count.
//
-// Note: This is irreversible.
+// If LFS2_SHRINKNONRELOCATING is defined, this function will also accept
+// block_counts smaller than the current configuration, after checking
+// that none of the blocks that are being removed are in use.
+// Note that littlefs's pseudorandom block allocation means that
+// this is very unlikely to work in the general case.
//
// Returns a negative error code on failure.
int lfs2_fs_grow(lfs2_t *lfs2, lfs2_size_t block_count);
diff --git a/lib/littlefs/lfs2_util.h b/lib/littlefs/lfs2_util.h
index 3b191f6885..12c82a630b 100644
--- a/lib/littlefs/lfs2_util.h
+++ b/lib/littlefs/lfs2_util.h
@@ -195,10 +195,10 @@ static inline uint32_t lfs2_fromle32(uint32_t a) {
(defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
return __builtin_bswap32(a);
#else
- return (((uint8_t*)&a)[0] << 0) |
- (((uint8_t*)&a)[1] << 8) |
- (((uint8_t*)&a)[2] << 16) |
- (((uint8_t*)&a)[3] << 24);
+ return ((uint32_t)((uint8_t*)&a)[0] << 0) |
+ ((uint32_t)((uint8_t*)&a)[1] << 8) |
+ ((uint32_t)((uint8_t*)&a)[2] << 16) |
+ ((uint32_t)((uint8_t*)&a)[3] << 24);
#endif
}
@@ -218,10 +218,10 @@ static inline uint32_t lfs2_frombe32(uint32_t a) {
(defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
return a;
#else
- return (((uint8_t*)&a)[0] << 24) |
- (((uint8_t*)&a)[1] << 16) |
- (((uint8_t*)&a)[2] << 8) |
- (((uint8_t*)&a)[3] << 0);
+ return ((uint32_t)((uint8_t*)&a)[0] << 24) |
+ ((uint32_t)((uint8_t*)&a)[1] << 16) |
+ ((uint32_t)((uint8_t*)&a)[2] << 8) |
+ ((uint32_t)((uint8_t*)&a)[3] << 0);
#endif
}