Compare commits

..

2 Commits

Author SHA1 Message Date
Christopher Haster
f6e3193051 Added file config structure and lfs_file_opencfg
The optional config structure options up the possibility of adding
file-level configuration in a backwards compatible manner.

Also bumped minor version to v1.5
2018-07-16 15:39:10 -05:00
Damien George
97711d78c4 Added possibility to open multiple files with LFS_NO_MALLOC enabled. 2018-07-16 15:37:45 -05:00
5 changed files with 84 additions and 99 deletions

View File

@@ -134,44 +134,53 @@ jobs:
- STAGE=deploy - STAGE=deploy
- NAME=deploy - NAME=deploy
script: script:
# Find version defined in lfs.h # Update tag for version defined in lfs.h
- LFS_VERSION=$(grep -ox '#define LFS_VERSION .*' lfs.h | cut -d ' ' -f3) - LFS_VERSION=$(grep -ox '#define LFS_VERSION .*' lfs.h | cut -d ' ' -f3)
- LFS_VERSION_MAJOR=$((0xffff & ($LFS_VERSION >> 16))) - LFS_VERSION_MAJOR=$((0xffff & ($LFS_VERSION >> 16)))
- LFS_VERSION_MINOR=$((0xffff & ($LFS_VERSION >> 0))) - LFS_VERSION_MINOR=$((0xffff & ($LFS_VERSION >> 0)))
# Grab latests patch from repo tags, default to 0 - LFS_VERSION="v$LFS_VERSION_MAJOR.$LFS_VERSION_MINOR"
- LFS_VERSION_PATCH=$(curl -f -u "$GEKY_BOT_RELEASES" - echo "littlefs version $LFS_VERSION"
https://api.github.com/repos/$TRAVIS_REPO_SLUG/git/refs
| jq 'map(.ref | match(
"refs/tags/v'"$LFS_VERSION_MAJOR"'\\.'"$LFS_VERSION_MINOR"'\\.(.*)$")
.captures[].string | tonumber + 1) | max // 0')
# We have our new version
- LFS_VERSION="v$LFS_VERSION_MAJOR.$LFS_VERSION_MINOR.$LFS_VERSION_PATCH"
- echo "VERSION $LFS_VERSION"
- | - |
# Check that we're the most recent commit curl -u $GEKY_BOT_RELEASES -X POST \
CURRENT_COMMIT=$(curl -f -u "$GEKY_BOT_RELEASES" \ https://api.github.com/repos/$TRAVIS_REPO_SLUG/git/refs \
https://api.github.com/repos/$TRAVIS_REPO_SLUG/commits/master \ -d "{
| jq -re '.sha') \"ref\": \"refs/tags/$LFS_VERSION\",
if [ "$TRAVIS_COMMIT" == "$CURRENT_COMMIT" ] \"sha\": \"$TRAVIS_COMMIT\"
}"
- |
curl -f -u $GEKY_BOT_RELEASES -X PATCH \
https://api.github.com/repos/$TRAVIS_REPO_SLUG/git/refs/tags/$LFS_VERSION \
-d "{
\"sha\": \"$TRAVIS_COMMIT\"
}"
# Create release notes from commits
- LFS_PREV_VERSION="v$LFS_VERSION_MAJOR.$(($LFS_VERSION_MINOR-1))"
- |
if [ $(git tag -l "$LFS_PREV_VERSION") ]
then then
# Build release notes curl -u $GEKY_BOT_RELEASES -X POST \
PREV=$(git tag --sort=-v:refname -l "v*" | head -1)
if [ ! -z "$PREV" ]
then
echo "PREV $PREV"
CHANGES=$'### Changes\n\n'$( \
git log --oneline $PREV.. --grep='^Merge' --invert-grep)
printf "CHANGES\n%s\n\n" "$CHANGES"
fi
# Create the release
curl -f -u "$GEKY_BOT_RELEASES" -X POST \
https://api.github.com/repos/$TRAVIS_REPO_SLUG/releases \ https://api.github.com/repos/$TRAVIS_REPO_SLUG/releases \
-d "{ -d "{
\"tag_name\": \"$LFS_VERSION\", \"tag_name\": \"$LFS_VERSION\",
\"target_commitish\": \"$TRAVIS_COMMIT\", \"name\": \"$LFS_VERSION\"
\"name\": \"${LFS_VERSION%.0}\",
\"body\": $(jq -sR '.' <<< "$CHANGES")
}" }"
RELEASE=$(
curl -f -u $GEKY_BOT_RELEASES \
https://api.github.com/repos/$TRAVIS_REPO_SLUG/releases/tags/$LFS_VERSION
)
CHANGES=$(
git log --oneline $LFS_PREV_VERSION.. --grep='^Merge' --invert-grep
)
curl -f -u $GEKY_BOT_RELEASES -X PATCH \
https://api.github.com/repos/$TRAVIS_REPO_SLUG/releases/$(
jq -r '.id' <<< "$RELEASE"
) \
-d "$(
jq -s '{
"body": ((.[0] // "" | sub("(?<=\n)#+ Changes.*"; ""; "mi"))
+ "### Changes\n\n" + .[1])
}' <(jq '.body' <<< "$RELEASE") <(jq -sR '.' <<< "$CHANGES")
)"
fi fi
# Manage statuses # Manage statuses

View File

@@ -22,3 +22,15 @@ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---
*Note*:
Individual files contain the following tag instead of the full license text.
SPDX-License-Identifier: BSD-3-Clause
This enables machine processing of license information based on the SPDX
License Identifiers that are here available: http://spdx.org/licenses/

View File

@@ -146,19 +146,6 @@ The tests assume a Linux environment and can be started with make:
make test make test
``` ```
## License
The littlefs is provided under the [BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html)
license. See [LICENSE.md](LICENSE.md) for more information. Contributions to
this project are accepted under the same license.
Individual files contain the following tag instead of the full license text.
SPDX-License-Identifier: BSD-3-Clause
This enables machine processing of license information based on the SPDX
License Identifiers that are here available: http://spdx.org/licenses/
## Related projects ## Related projects
[Mbed OS](https://github.com/ARMmbed/mbed-os/tree/master/features/filesystem/littlefs) - [Mbed OS](https://github.com/ARMmbed/mbed-os/tree/master/features/filesystem/littlefs) -

89
lfs.c
View File

@@ -417,14 +417,11 @@ static int lfs_dir_alloc(lfs_t *lfs, lfs_dir_t *dir) {
// rather than clobbering one of the blocks we just pretend // rather than clobbering one of the blocks we just pretend
// the revision may be valid // the revision may be valid
int err = lfs_bd_read(lfs, dir->pair[0], 0, &dir->d.rev, 4); int err = lfs_bd_read(lfs, dir->pair[0], 0, &dir->d.rev, 4);
if (err && err != LFS_ERR_CORRUPT) { dir->d.rev = lfs_fromle32(dir->d.rev);
if (err) {
return err; return err;
} }
if (err != LFS_ERR_CORRUPT) {
dir->d.rev = lfs_fromle32(dir->d.rev);
}
// set defaults // set defaults
dir->d.rev += 1; dir->d.rev += 1;
dir->d.size = sizeof(dir->d)+4; dir->d.size = sizeof(dir->d)+4;
@@ -448,9 +445,6 @@ static int lfs_dir_fetch(lfs_t *lfs,
int err = lfs_bd_read(lfs, tpair[i], 0, &test, sizeof(test)); int err = lfs_bd_read(lfs, tpair[i], 0, &test, sizeof(test));
lfs_dir_fromle32(&test); lfs_dir_fromle32(&test);
if (err) { if (err) {
if (err == LFS_ERR_CORRUPT) {
continue;
}
return err; return err;
} }
@@ -470,9 +464,6 @@ static int lfs_dir_fetch(lfs_t *lfs,
err = lfs_bd_crc(lfs, tpair[i], sizeof(test), err = lfs_bd_crc(lfs, tpair[i], sizeof(test),
(0x7fffffff & test.size) - sizeof(test), &crc); (0x7fffffff & test.size) - sizeof(test), &crc);
if (err) { if (err) {
if (err == LFS_ERR_CORRUPT) {
continue;
}
return err; return err;
} }
@@ -2016,21 +2007,6 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
/// Filesystem operations /// /// Filesystem operations ///
static void lfs_deinit(lfs_t *lfs) {
// free allocated memory
if (!lfs->cfg->read_buffer) {
lfs_free(lfs->rcache.buffer);
}
if (!lfs->cfg->prog_buffer) {
lfs_free(lfs->pcache.buffer);
}
if (!lfs->cfg->lookahead_buffer) {
lfs_free(lfs->free.buffer);
}
}
static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) { static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
lfs->cfg = cfg; lfs->cfg = cfg;
@@ -2040,7 +2016,7 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
} else { } else {
lfs->rcache.buffer = lfs_malloc(lfs->cfg->read_size); lfs->rcache.buffer = lfs_malloc(lfs->cfg->read_size);
if (!lfs->rcache.buffer) { if (!lfs->rcache.buffer) {
goto cleanup; return LFS_ERR_NOMEM;
} }
} }
@@ -2050,7 +2026,7 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
} else { } else {
lfs->pcache.buffer = lfs_malloc(lfs->cfg->prog_size); lfs->pcache.buffer = lfs_malloc(lfs->cfg->prog_size);
if (!lfs->pcache.buffer) { if (!lfs->pcache.buffer) {
goto cleanup; return LFS_ERR_NOMEM;
} }
} }
@@ -2066,7 +2042,7 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
} else { } else {
lfs->free.buffer = lfs_malloc(lfs->cfg->lookahead/8); lfs->free.buffer = lfs_malloc(lfs->cfg->lookahead/8);
if (!lfs->free.buffer) { if (!lfs->free.buffer) {
goto cleanup; return LFS_ERR_NOMEM;
} }
} }
@@ -2086,10 +2062,23 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
lfs->deorphaned = false; lfs->deorphaned = false;
return 0; return 0;
}
cleanup: static int lfs_deinit(lfs_t *lfs) {
lfs_deinit(lfs); // free allocated memory
return LFS_ERR_NOMEM; if (!lfs->cfg->read_buffer) {
lfs_free(lfs->rcache.buffer);
}
if (!lfs->cfg->prog_buffer) {
lfs_free(lfs->pcache.buffer);
}
if (!lfs->cfg->lookahead_buffer) {
lfs_free(lfs->free.buffer);
}
return 0;
} }
int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) { int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
@@ -2109,19 +2098,19 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
lfs_dir_t superdir; lfs_dir_t superdir;
err = lfs_dir_alloc(lfs, &superdir); err = lfs_dir_alloc(lfs, &superdir);
if (err) { if (err) {
goto cleanup; return err;
} }
// write root directory // write root directory
lfs_dir_t root; lfs_dir_t root;
err = lfs_dir_alloc(lfs, &root); err = lfs_dir_alloc(lfs, &root);
if (err) { if (err) {
goto cleanup; return err;
} }
err = lfs_dir_commit(lfs, &root, NULL, 0); err = lfs_dir_commit(lfs, &root, NULL, 0);
if (err) { if (err) {
goto cleanup; return err;
} }
lfs->root[0] = root.pair[0]; lfs->root[0] = root.pair[0];
@@ -2152,28 +2141,24 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
&superblock.d, sizeof(superblock.d)} &superblock.d, sizeof(superblock.d)}
}, 1); }, 1);
if (err && err != LFS_ERR_CORRUPT) { if (err && err != LFS_ERR_CORRUPT) {
goto cleanup; return err;
} }
valid = valid || !err; valid = valid || !err;
} }
if (!valid) { if (!valid) {
err = LFS_ERR_CORRUPT; return LFS_ERR_CORRUPT;
goto cleanup;
} }
// sanity check that fetch works // sanity check that fetch works
err = lfs_dir_fetch(lfs, &superdir, (const lfs_block_t[2]){0, 1}); err = lfs_dir_fetch(lfs, &superdir, (const lfs_block_t[2]){0, 1});
if (err) { if (err) {
goto cleanup; return err;
} }
lfs_alloc_ack(lfs); lfs_alloc_ack(lfs);
return lfs_deinit(lfs);
cleanup:
lfs_deinit(lfs);
return err;
} }
int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) { int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
@@ -2193,7 +2178,7 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
lfs_superblock_t superblock; lfs_superblock_t superblock;
err = lfs_dir_fetch(lfs, &dir, (const lfs_block_t[2]){0, 1}); err = lfs_dir_fetch(lfs, &dir, (const lfs_block_t[2]){0, 1});
if (err && err != LFS_ERR_CORRUPT) { if (err && err != LFS_ERR_CORRUPT) {
goto cleanup; return err;
} }
if (!err) { if (!err) {
@@ -2201,7 +2186,7 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
&superblock.d, sizeof(superblock.d)); &superblock.d, sizeof(superblock.d));
lfs_superblock_fromle32(&superblock.d); lfs_superblock_fromle32(&superblock.d);
if (err) { if (err) {
goto cleanup; return err;
} }
lfs->root[0] = superblock.d.root[0]; lfs->root[0] = superblock.d.root[0];
@@ -2210,8 +2195,7 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
if (err || memcmp(superblock.d.magic, "littlefs", 8) != 0) { if (err || memcmp(superblock.d.magic, "littlefs", 8) != 0) {
LFS_ERROR("Invalid superblock at %d %d", 0, 1); LFS_ERROR("Invalid superblock at %d %d", 0, 1);
err = LFS_ERR_CORRUPT; return LFS_ERR_CORRUPT;
goto cleanup;
} }
uint16_t major_version = (0xffff & (superblock.d.version >> 16)); uint16_t major_version = (0xffff & (superblock.d.version >> 16));
@@ -2219,21 +2203,14 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
if ((major_version != LFS_DISK_VERSION_MAJOR || if ((major_version != LFS_DISK_VERSION_MAJOR ||
minor_version > LFS_DISK_VERSION_MINOR)) { minor_version > LFS_DISK_VERSION_MINOR)) {
LFS_ERROR("Invalid version %d.%d", major_version, minor_version); LFS_ERROR("Invalid version %d.%d", major_version, minor_version);
err = LFS_ERR_INVAL; return LFS_ERR_INVAL;
goto cleanup;
} }
return 0; return 0;
cleanup:
lfs_deinit(lfs);
return err;
} }
int lfs_unmount(lfs_t *lfs) { int lfs_unmount(lfs_t *lfs) {
lfs_deinit(lfs); return lfs_deinit(lfs);
return 0;
} }

2
lfs.h
View File

@@ -21,7 +21,7 @@ extern "C"
// Software library version // Software library version
// Major (top-nibble), incremented on backwards incompatible changes // Major (top-nibble), incremented on backwards incompatible changes
// Minor (bottom-nibble), incremented on feature additions // Minor (bottom-nibble), incremented on feature additions
#define LFS_VERSION 0x00010006 #define LFS_VERSION 0x00010005
#define LFS_VERSION_MAJOR (0xffff & (LFS_VERSION >> 16)) #define LFS_VERSION_MAJOR (0xffff & (LFS_VERSION >> 16))
#define LFS_VERSION_MINOR (0xffff & (LFS_VERSION >> 0)) #define LFS_VERSION_MINOR (0xffff & (LFS_VERSION >> 0))