diff --git a/.travis.yml b/.travis.yml index b2caee86a59..32c21d86d87 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,7 +28,7 @@ script: # compile and find the code size with the smallest configuration - make clean size OBJ="$(ls lfs*.o | tr '\n' ' ')" - CFLAGS+="-DLFS_NO{ASSERT,DEBUG,WARN,ERROR}" + CFLAGS+="-DLFS_NO_ASSERT -DLFS_NO_DEBUG -DLFS_NO_WARN -DLFS_NO_ERROR" | tee sizes # update status if we succeeded, compare with master if possible @@ -135,53 +135,44 @@ jobs: - STAGE=deploy - NAME=deploy script: - # Update tag for version defined in lfs.h + # Find version defined in lfs.h - LFS_VERSION=$(grep -ox '#define LFS_VERSION .*' lfs.h | cut -d ' ' -f3) - LFS_VERSION_MAJOR=$((0xffff & ($LFS_VERSION >> 16))) - LFS_VERSION_MINOR=$((0xffff & ($LFS_VERSION >> 0))) - - LFS_VERSION="v$LFS_VERSION_MAJOR.$LFS_VERSION_MINOR" - - echo "littlefs version $LFS_VERSION" + # Grab latests patch from repo tags, default to 0 + - LFS_VERSION_PATCH=$(curl -f -u "$GEKY_BOT_RELEASES" + 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" - | - curl -u $GEKY_BOT_RELEASES -X POST \ - https://api.github.com/repos/$TRAVIS_REPO_SLUG/git/refs \ - -d "{ - \"ref\": \"refs/tags/$LFS_VERSION\", - \"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") ] + # Check that we're the most recent commit + CURRENT_COMMIT=$(curl -f -u "$GEKY_BOT_RELEASES" \ + https://api.github.com/repos/$TRAVIS_REPO_SLUG/commits/master \ + | jq -re '.sha') + if [ "$TRAVIS_COMMIT" == "$CURRENT_COMMIT" ] then - curl -u $GEKY_BOT_RELEASES -X POST \ + # Build release notes + 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 \ -d "{ \"tag_name\": \"$LFS_VERSION\", - \"name\": \"$LFS_VERSION\" + \"target_commitish\": \"$TRAVIS_COMMIT\", + \"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 # Manage statuses diff --git a/LICENSE.md b/LICENSE.md index 59cd3f8a320..ed69bea4743 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,165 +1,24 @@ -Apache License -Version 2.0, January 2004 -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and -distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright -owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities -that control, are controlled by, or are under common control with that entity. -For the purposes of this definition, "control" means (i) the power, direct or -indirect, to cause the direction or management of such entity, whether by -contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the -outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising -permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including -but not limited to software source code, documentation source, and configuration -files. - -"Object" form shall mean any form resulting from mechanical transformation or -translation of a Source form, including but not limited to compiled object code, -generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made -available under the License, as indicated by a copyright notice that is included -in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that -is based on (or derived from) the Work and for which the editorial revisions, -annotations, elaborations, or other modifications represent, as a whole, an -original work of authorship. For the purposes of this License, Derivative Works -shall not include works that remain separable from, or merely link (or bind by -name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version -of the Work and any modifications or additions to that Work or Derivative Works -thereof, that is intentionally submitted to Licensor for inclusion in the Work -by the copyright owner or by an individual or Legal Entity authorized to submit -on behalf of the copyright owner. For the purposes of this definition, -"submitted" means any form of electronic, verbal, or written communication sent -to the Licensor or its representatives, including but not limited to -communication on electronic mailing lists, source code control systems, and -issue tracking systems that are managed by, or on behalf of, the Licensor for -the purpose of discussing and improving the Work, but excluding communication -that is conspicuously marked or otherwise designated in writing by the copyright -owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf -of whom a Contribution has been received by Licensor and subsequently -incorporated within the Work. - -2. Grant of Copyright License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable copyright license to reproduce, prepare Derivative Works of, -publicly display, publicly perform, sublicense, and distribute the Work and such -Derivative Works in Source or Object form. - -3. Grant of Patent License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable (except as stated in this section) patent license to make, have -made, use, offer to sell, sell, import, and otherwise transfer the Work, where -such license applies only to those patent claims licensable by such Contributor -that are necessarily infringed by their Contribution(s) alone or by combination -of their Contribution(s) with the Work to which such Contribution(s) was -submitted. If You institute patent litigation against any entity (including a -cross-claim or counterclaim in a lawsuit) alleging that the Work or a -Contribution incorporated within the Work constitutes direct or contributory -patent infringement, then any patent licenses granted to You under this License -for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. - -You may reproduce and distribute copies of the Work or Derivative Works thereof -in any medium, with or without modifications, and in Source or Object form, -provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of -this License; and -You must cause any modified files to carry prominent notices stating that You -changed the files; and -You must retain, in the Source form of any Derivative Works that You distribute, -all copyright, patent, trademark, and attribution notices from the Source form -of the Work, excluding those notices that do not pertain to any part of the -Derivative Works; and -If the Work includes a "NOTICE" text file as part of its distribution, then any -Derivative Works that You distribute must include a readable copy of the -attribution notices contained within such NOTICE file, excluding those notices -that do not pertain to any part of the Derivative Works, in at least one of the -following places: within a NOTICE text file distributed as part of the -Derivative Works; within the Source form or documentation, if provided along -with the Derivative Works; or, within a display generated by the Derivative -Works, if and wherever such third-party notices normally appear. The contents of -the NOTICE file are for informational purposes only and do not modify the -License. You may add Your own attribution notices within Derivative Works that -You distribute, alongside or as an addendum to the NOTICE text from the Work, -provided that such additional attribution notices cannot be construed as -modifying the License. -You may add Your own copyright statement to Your modifications and may provide -additional or different license terms and conditions for use, reproduction, or -distribution of Your modifications, or for any such Derivative Works as a whole, -provided Your use, reproduction, and distribution of the Work otherwise complies -with the conditions stated in this License. - -5. Submission of Contributions. - -Unless You explicitly state otherwise, any Contribution intentionally submitted -for inclusion in the Work by You to the Licensor shall be under the terms and -conditions of this License, without any additional terms or conditions. -Notwithstanding the above, nothing herein shall supersede or modify the terms of -any separate license agreement you may have executed with Licensor regarding -such Contributions. - -6. Trademarks. - -This License does not grant permission to use the trade names, trademarks, -service marks, or product names of the Licensor, except as required for -reasonable and customary use in describing the origin of the Work and -reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. - -Unless required by applicable law or agreed to in writing, Licensor provides the -Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, -including, without limitation, any warranties or conditions of TITLE, -NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are -solely responsible for determining the appropriateness of using or -redistributing the Work and assume any risks associated with Your exercise of -permissions under this License. - -8. Limitation of Liability. - -In no event and under no legal theory, whether in tort (including negligence), -contract, or otherwise, unless required by applicable law (such as deliberate -and grossly negligent acts) or agreed to in writing, shall any Contributor be -liable to You for damages, including any direct, indirect, special, incidental, -or consequential damages of any character arising as a result of this License or -out of the use or inability to use the Work (including but not limited to -damages for loss of goodwill, work stoppage, computer failure or malfunction, or -any and all other commercial damages or losses), even if such Contributor has -been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. - -While redistributing the Work or Derivative Works thereof, You may choose to -offer, and charge a fee for, acceptance of support, warranty, indemnity, or -other liability obligations and/or rights consistent with this License. However, -in accepting such obligations, You may act only on Your own behalf and on Your -sole responsibility, not on behalf of any other Contributor, and only if You -agree to indemnify, defend, and hold each Contributor harmless for any liability -incurred by, or claims asserted against, such Contributor by reason of your -accepting any such warranty or additional liability. +Copyright (c) 2017, Arm Limited. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +- Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. +- Neither the name of ARM nor the names of its contributors may be used to + endorse or promote products derived from this software without specific prior + written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +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 +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Makefile b/Makefile index 21cc1c96088..a8b8852f305 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,7 @@ -TARGET = lfs +TARGET = lfs.a +ifneq ($(wildcard test.c main.c),) +override TARGET = lfs +endif CC ?= gcc AR ?= ar @@ -22,7 +25,7 @@ ifdef WORD override CFLAGS += -m$(WORD) endif override CFLAGS += -I. -override CFLAGS += -std=c99 -Wall -pedantic +override CFLAGS += -std=c99 -Wall -pedantic -Wshadow -Wunused-parameter all: $(TARGET) @@ -36,7 +39,9 @@ size: $(OBJ) test: test_format test_dirs test_files test_seek test_truncate \ test_entries test_interspersed test_alloc test_paths test_attrs \ test_move test_orphan test_corrupt + @rm test.c test_%: tests/test_%.sh + ifdef QUIET @./$< | sed -n '/^[-=]/p' else @@ -45,7 +50,7 @@ endif -include $(DEP) -$(TARGET): $(OBJ) +lfs: $(OBJ) $(CC) $(CFLAGS) $^ $(LFLAGS) -o $@ %.a: $(OBJ) diff --git a/README.md b/README.md index e778a6506ef..623ba0ae47e 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,19 @@ The tests assume a Linux environment and can be started with make: 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 [Mbed OS](https://github.com/ARMmbed/mbed-os/tree/master/features/filesystem/littlefs) - diff --git a/emubd/lfs_emubd.c b/emubd/lfs_emubd.c index b1595963dd9..682ad925e26 100644 --- a/emubd/lfs_emubd.c +++ b/emubd/lfs_emubd.c @@ -1,19 +1,8 @@ /* * Block device emulated on standard files * - * Copyright (c) 2017 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright (c) 2017, Arm Limited. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause */ #include "emubd/lfs_emubd.h" @@ -27,6 +16,7 @@ #include #include #include +#include // Block device emulated on existing filesystem @@ -96,7 +86,7 @@ int lfs_emubd_read(const struct lfs_config *cfg, lfs_block_t block, memset(data, 0, size); // Read data - snprintf(emu->child, LFS_NAME_MAX, "%x", block); + snprintf(emu->child, LFS_NAME_MAX, "%" PRIx32, block); FILE *f = fopen(emu->path, "rb"); if (!f && errno != ENOENT) { @@ -135,7 +125,7 @@ int lfs_emubd_prog(const struct lfs_config *cfg, lfs_block_t block, assert(block < cfg->block_count); // Program data - snprintf(emu->child, LFS_NAME_MAX, "%x", block); + snprintf(emu->child, LFS_NAME_MAX, "%" PRIx32, block); FILE *f = fopen(emu->path, "r+b"); if (!f) { @@ -182,7 +172,7 @@ int lfs_emubd_erase(const struct lfs_config *cfg, lfs_block_t block) { assert(block < cfg->block_count); // Erase the block - snprintf(emu->child, LFS_NAME_MAX, "%x", block); + snprintf(emu->child, LFS_NAME_MAX, "%" PRIx32, block); struct stat st; int err = stat(emu->path, &st); if (err && errno != ENOENT) { @@ -250,4 +240,3 @@ int lfs_emubd_sync(const struct lfs_config *cfg) { return 0; } - diff --git a/emubd/lfs_emubd.h b/emubd/lfs_emubd.h index 4f87ccecf10..0fd43875fdf 100644 --- a/emubd/lfs_emubd.h +++ b/emubd/lfs_emubd.h @@ -1,19 +1,8 @@ /* * Block device emulated on standard files * - * Copyright (c) 2017 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright (c) 2017, Arm Limited. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause */ #ifndef LFS_EMUBD_H #define LFS_EMUBD_H @@ -21,6 +10,11 @@ #include "lfs.h" #include "lfs_util.h" +#ifdef __cplusplus +extern "C" +{ +#endif + // Config options #ifndef LFS_EMUBD_READ_SIZE @@ -86,4 +80,8 @@ int lfs_emubd_erase(const struct lfs_config *cfg, lfs_block_t block); int lfs_emubd_sync(const struct lfs_config *cfg); +#ifdef __cplusplus +} /* extern "C" */ +#endif + #endif diff --git a/lfs.c b/lfs.c index 64cb584088f..4eb4821bfff 100644 --- a/lfs.c +++ b/lfs.c @@ -74,12 +74,12 @@ static int lfs_cache_read(lfs_t *lfs, // load to cache, first condition can no longer fail LFS_ASSERT(block < lfs->cfg->block_count); - lfs_size_t size = store ? lfs->cfg->cache_size : lfs->cfg->prog_size; + lfs_size_t nsize = store ? lfs->cfg->cache_size : lfs->cfg->prog_size; rcache->block = block; - rcache->off = lfs_aligndown(off, size); - rcache->size = size; + rcache->off = lfs_aligndown(off, nsize); + rcache->size = nsize; int err = lfs->cfg->read(lfs->cfg, rcache->block, - rcache->off, rcache->buffer, size); + rcache->off, rcache->buffer, nsize); if (err) { return err; } @@ -127,6 +127,19 @@ static int lfs_cache_crc(lfs_t *lfs, return 0; } +static inline void lfs_cache_drop(lfs_t *lfs, lfs_cache_t *rcache) { + // do not zero, cheaper if cache is readonly or only going to be + // written with identical data (during relocates) + (void)lfs; + rcache->block = 0xffffffff; +} + +static inline void lfs_cache_zero(lfs_t *lfs, lfs_cache_t *pcache) { + // zero to avoid information leak + memset(pcache->buffer, 0xff, lfs->cfg->prog_size); + pcache->block = 0xffffffff; +} + static int lfs_cache_flush(lfs_t *lfs, lfs_cache_t *pcache, lfs_cache_t *rcache, bool validate) { if (pcache->block != 0xffffffff) { @@ -140,7 +153,7 @@ static int lfs_cache_flush(lfs_t *lfs, if (validate) { // check data on disk - rcache->block = 0xffffffff; + lfs_cache_drop(lfs, rcache); int res = lfs_cache_cmp(lfs, NULL, rcache, pcache->block, pcache->off, pcache->buffer, diff); if (res < 0) { @@ -152,7 +165,7 @@ static int lfs_cache_flush(lfs_t *lfs, } } - pcache->block = 0xffffffff; + lfs_cache_zero(lfs, pcache); } return 0; @@ -234,7 +247,7 @@ static int lfs_bd_erase(lfs_t *lfs, lfs_block_t block) { } static int lfs_bd_sync(lfs_t *lfs) { - lfs->rcache.block = 0xffffffff; + lfs_cache_drop(lfs, &lfs->rcache); int err = lfs_cache_flush(lfs, &lfs->pcache, &lfs->rcache, false); if (err) { @@ -253,6 +266,7 @@ static int32_t lfs_fs_parent(lfs_t *lfs, const lfs_block_t dir[2], static int lfs_fs_relocate(lfs_t *lfs, const lfs_block_t oldpair[2], lfs_block_t newpair[2]); static int lfs_fs_forceconsistency(lfs_t *lfs); +static int lfs_deinit(lfs_t *lfs); /// Block allocator /// @@ -294,7 +308,8 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) { // check if we have looked at all blocks since last ack if (lfs->free.ack == 0) { - LFS_WARN("No more free space %d", lfs->free.i + lfs->free.off); + LFS_WARN("No more free space %"PRIu32, + lfs->free.i + lfs->free.off); return LFS_ERR_NOSPC; } @@ -517,7 +532,7 @@ static int lfs_commitattr(lfs_t *lfs, struct lfs_commit *commit, // special case for moves return lfs_commitmove(lfs, commit, lfs_tagsize(tag), lfs_tagid(tag), - buffer, NULL); + buffer, NULL); } // check if we fit @@ -549,7 +564,7 @@ static int lfs_commitattr(lfs_t *lfs, struct lfs_commit *commit, for (lfs_off_t i = 0; i < size; i++) { // rely on caching to make this efficient uint8_t dat; - int err = lfs_bd_read(lfs, disk->block, disk->off+i, &dat, 1); + err = lfs_bd_read(lfs, disk->block, disk->off+i, &dat, 1); if (err) { return err; } @@ -723,7 +738,7 @@ static int lfs_dir_alloc(lfs_t *lfs, lfs_mdir_t *dir) { // the revision may be valid int err = lfs_bd_read(lfs, dir->pair[0], 0, &dir->rev, 4); dir->rev = lfs_fromle32(dir->rev); - if (err) { + if (err && err != LFS_ERR_CORRUPT) { return err; } @@ -752,11 +767,16 @@ static int32_t lfs_dir_find(lfs_t *lfs, // find the block with the most recent revision uint32_t rev[2]; for (int i = 0; i < 2; i++) { - int err = lfs_bd_read(lfs, dir->pair[i], 0, &rev[i], sizeof(rev[i])); - if (err) { + int err = lfs_cache_read(lfs, &lfs->pcache, &lfs->rcache, false, + dir->pair[i], 0, &rev[i], sizeof(rev[i])); + rev[i] = lfs_fromle32(rev[i]); + if (err && err != LFS_ERR_CORRUPT) { return err; } - rev[i] = lfs_fromle32(rev[i]); + + if (err == LFS_ERR_CORRUPT) { + rev[i] = rev[(i+1)%2] - 1; + } } if (lfs_scmp(rev[1], rev[0]) > 0) { @@ -788,6 +808,11 @@ static int32_t lfs_dir_find(lfs_t *lfs, int err = lfs_bd_read(lfs, dir->pair[0], off, &tag, sizeof(tag)); if (err) { + if (err == LFS_ERR_CORRUPT) { + // can't continue? + dir->erased = false; + break; + } return err; } @@ -809,9 +834,13 @@ static int32_t lfs_dir_find(lfs_t *lfs, if (lfs_tagtype(tag) == LFS_TYPE_CRC) { // check the crc attr uint32_t dcrc; - int err = lfs_bd_read(lfs, dir->pair[0], + err = lfs_bd_read(lfs, dir->pair[0], off+sizeof(tag), &dcrc, sizeof(dcrc)); if (err) { + if (err == LFS_ERR_CORRUPT) { + dir->erased = false; + break; + } return err; } dcrc = lfs_fromle32(dcrc); @@ -834,7 +863,10 @@ static int32_t lfs_dir_find(lfs_t *lfs, err = lfs_bd_crc(lfs, dir->pair[0], off+sizeof(tag), lfs_tagsize(tag), &crc); if (err) { - return err; + if (err == LFS_ERR_CORRUPT) { + dir->erased = false; + break; + } } if (lfs_tagid(tag) < 0x3ff && lfs_tagid(tag) >= tempcount) { @@ -846,7 +878,10 @@ static int32_t lfs_dir_find(lfs_t *lfs, err = lfs_bd_read(lfs, dir->pair[0], off+sizeof(tag), temptail, sizeof(temptail)); if (err) { - return err; + if (err == LFS_ERR_CORRUPT) { + dir->erased = false; + break; + } } lfs_pairfromle32(temptail); } else if (lfs_tagsubtype(tag) == LFS_TYPE_GLOBALS) { @@ -854,7 +889,10 @@ static int32_t lfs_dir_find(lfs_t *lfs, err = lfs_bd_read(lfs, dir->pair[0], off+sizeof(tag), &templocals, sizeof(templocals)); if (err) { - return err; + if (err == LFS_ERR_CORRUPT) { + dir->erased = false; + break; + } } } else if (lfs_tagsubtype(tag) == LFS_TYPE_DELETE) { LFS_ASSERT(tempcount > 0); @@ -870,6 +908,10 @@ static int32_t lfs_dir_find(lfs_t *lfs, int res = lfs_bd_cmp(lfs, dir->pair[0], off+sizeof(tag), findbuffer, lfs_tagsize(tag)); if (res < 0) { + if (res == LFS_ERR_CORRUPT) { + dir->erased = false; + break; + } return res; } @@ -904,7 +946,8 @@ static int32_t lfs_dir_find(lfs_t *lfs, lfs_pairswap(rev); } - LFS_ERROR("Corrupted dir pair at %d %d", dir->pair[0], dir->pair[1]); + LFS_ERROR("Corrupted dir pair at %"PRIu32" %"PRIu32, + dir->pair[0], dir->pair[1]); return LFS_ERR_CORRUPT; } @@ -1051,7 +1094,7 @@ static int lfs_dir_compact(lfs_t *lfs, split: // commit no longer fits, need to split dir, // drop caches and create tail - lfs->pcache.block = 0xffffffff; + lfs_cache_drop(lfs, &lfs->pcache); if (ack == -1) { // If we can't fit in this block, we won't fit in next block @@ -1081,15 +1124,16 @@ static int lfs_dir_compact(lfs_t *lfs, relocate: //commit was corrupted - LFS_DEBUG("Bad block at %d", dir->pair[1]); + LFS_DEBUG("Bad block at %"PRIu32, + dir->pair[1]); // drop caches and prepare to relocate block relocated = true; - lfs->pcache.block = 0xffffffff; + lfs_cache_drop(lfs, &lfs->pcache); // can't relocate superblock, filesystem is now frozen if (lfs_paircmp(oldpair, (const lfs_block_t[2]){0, 1}) == 0) { - LFS_WARN("Superblock %d has become unwritable", oldpair[1]); + LFS_WARN("Superblock %"PRIu32" has become unwritable", oldpair[1]); return LFS_ERR_CORRUPT; } @@ -1108,7 +1152,7 @@ static int lfs_dir_compact(lfs_t *lfs, lfs_globalzero(&lfs->locals); } else { // update references if we relocated - LFS_DEBUG("Relocating %d %d to %d %d", + LFS_DEBUG("Relocating %"PRIu32" %"PRIu32" to %"PRIu32" %"PRIu32, oldpair[0], oldpair[1], dir->pair[0], dir->pair[1]); int err = lfs_fs_relocate(lfs, oldpair, dir->pair); if (err) { @@ -1174,15 +1218,7 @@ static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir, } } - if (!dir->erased) { -compact: - // fall back to compaction - lfs->pcache.block = 0xffffffff; - int err = lfs_dir_compact(lfs, dir, attrs, dir, 0, dir->count); - if (err) { - return err; - } - } else { + if (dir->erased) { // try to commit struct lfs_commit commit = { .block = dir->pair[0], @@ -1241,6 +1277,14 @@ static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir, // successful commit, update globals lfs_globalxor(&dir->locals, &lfs->locals); lfs_globalzero(&lfs->locals); + } else { +compact: + // fall back to compaction + lfs_cache_drop(lfs, &lfs->pcache); + int err = lfs_dir_compact(lfs, dir, attrs, dir, 0, dir->count); + if (err) { + return err; + } } // update globals that are affected @@ -1583,7 +1627,7 @@ int lfs_dir_seek(lfs_t *lfs, lfs_dir_t *dir, lfs_off_t off) { return LFS_ERR_INVAL; } - int err = lfs_dir_fetch(lfs, &dir->m, dir->m.tail); + err = lfs_dir_fetch(lfs, &dir->m, dir->m.tail); if (err) { return err; } @@ -1752,10 +1796,10 @@ static int lfs_ctzextend(lfs_t *lfs, } relocate: - LFS_DEBUG("Bad block at %d", nblock); + LFS_DEBUG("Bad block at %"PRIu32, nblock); // just clear cache and try a new block - pcache->block = 0xffffffff; + lfs_cache_drop(lfs, pcache); } } @@ -1849,7 +1893,7 @@ int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file, // get next slot and create entry to remember name file->id = file->m.count; - int err = lfs_dir_commit(lfs, &file->m, + err = lfs_dir_commit(lfs, &file->m, LFS_MKATTR(LFS_TYPE_REG, file->id, path, nlen, LFS_MKATTR(LFS_TYPE_INLINESTRUCT, file->id, NULL, 0, NULL))); @@ -1902,7 +1946,6 @@ int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file, } // allocate buffer if needed - file->cache.block = 0xffffffff; if (file->cfg->buffer) { file->cache.buffer = file->cfg->buffer; } else { @@ -1913,6 +1956,9 @@ int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file, } } + // zero to avoid information leak + lfs_cache_zero(lfs, &file->cache); + if (lfs_tagtype(tag) == LFS_TYPE_INLINESTRUCT) { // load inline files file->ctz.head = 0xfffffffe; @@ -2009,7 +2055,7 @@ static int lfs_file_relocate(lfs_t *lfs, lfs_file_t *file) { file->cache.block = lfs->pcache.block; file->cache.off = lfs->pcache.off; file->cache.size = lfs->pcache.size; - lfs->pcache.block = 0xffffffff; + lfs_cache_zero(lfs, &lfs->pcache); file->block = nblock; return 0; @@ -2036,7 +2082,7 @@ static int lfs_file_flush(lfs_t *lfs, lfs_file_t *file) { .pos = file->pos, .cache = lfs->rcache, }; - lfs->rcache.block = 0xffffffff; + lfs_cache_drop(lfs, &lfs->rcache); while (file->pos < file->ctz.size) { // copy over a byte at a time, leave it up to caching @@ -2054,8 +2100,8 @@ static int lfs_file_flush(lfs_t *lfs, lfs_file_t *file) { // keep our reference to the rcache in sync if (lfs->rcache.block != 0xffffffff) { - orig.cache.block = 0xffffffff; - lfs->rcache.block = 0xffffffff; + lfs_cache_drop(lfs, &orig.cache); + lfs_cache_drop(lfs, &lfs->rcache); } } @@ -2073,7 +2119,7 @@ static int lfs_file_flush(lfs_t *lfs, lfs_file_t *file) { break; relocate: - LFS_DEBUG("Bad block at %d", file->block); + LFS_DEBUG("Bad block at %"PRIu32, file->block); err = lfs_file_relocate(lfs, file); if (err) { return err; @@ -2123,7 +2169,7 @@ int lfs_file_sync(lfs_t *lfs, lfs_file_t *file) { // commit file data and attributes lfs_ctztole32(&file->ctz); - int err = lfs_dir_commit(lfs, &file->m, + err = lfs_dir_commit(lfs, &file->m, LFS_MKATTR(type, file->id, buffer, size, LFS_MKATTR(LFS_FROM_ATTRS, file->id, file->cfg->attrs, 0, NULL))); @@ -2284,7 +2330,7 @@ lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file, } // mark cache as dirty since we may have read data into it - file->cache.block = 0xffffffff; + lfs_cache_zero(lfs, &file->cache); } // extend file with new blocks @@ -2482,7 +2528,7 @@ int lfs_remove(lfs_t *lfs, const char *path) { } lfs_pairfromle32(pair); - int err = lfs_dir_fetch(lfs, &dir, pair); + err = lfs_dir_fetch(lfs, &dir, pair); if (err) { return err; } @@ -2504,7 +2550,7 @@ int lfs_remove(lfs_t *lfs, const char *path) { } if (lfs_tagtype(tag) == LFS_TYPE_DIR) { - int err = lfs_fs_pred(lfs, dir.pair, &cwd); + err = lfs_fs_pred(lfs, dir.pair, &cwd); if (err) { return err; } @@ -2571,7 +2617,7 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) { lfs_pairfromle32(prevpair); // must be empty before removal - int err = lfs_dir_fetch(lfs, &prevdir, prevpair); + err = lfs_dir_fetch(lfs, &prevdir, prevpair); if (err) { return err; } @@ -2616,7 +2662,7 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) { } if (prevtag != LFS_ERR_NOENT && lfs_tagtype(prevtag) == LFS_TYPE_DIR) { - int err = lfs_fs_pred(lfs, prevdir.pair, &newcwd); + err = lfs_fs_pred(lfs, prevdir.pair, &newcwd); if (err) { return err; } @@ -2697,6 +2743,7 @@ static inline void lfs_superblocktole32(lfs_superblock_t *superblock) { static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) { lfs->cfg = cfg; + int err = 0; // check that block size is a multiple of cache size is a multiple // of prog and read sizes @@ -2709,27 +2756,31 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) { <= lfs->cfg->block_size); // setup read cache - lfs->rcache.block = 0xffffffff; if (lfs->cfg->read_buffer) { lfs->rcache.buffer = lfs->cfg->read_buffer; } else { lfs->rcache.buffer = lfs_malloc(lfs->cfg->cache_size); if (!lfs->rcache.buffer) { - return LFS_ERR_NOMEM; + err = LFS_ERR_NOMEM; + goto cleanup; } } // setup program cache - lfs->pcache.block = 0xffffffff; if (lfs->cfg->prog_buffer) { lfs->pcache.buffer = lfs->cfg->prog_buffer; } else { lfs->pcache.buffer = lfs_malloc(lfs->cfg->cache_size); if (!lfs->pcache.buffer) { - return LFS_ERR_NOMEM; + err = LFS_ERR_NOMEM; + goto cleanup; } } + // zero to avoid information leaks + lfs_cache_zero(lfs, &lfs->rcache); + lfs_cache_zero(lfs, &lfs->pcache); + // setup lookahead, must be multiple of 32-bits LFS_ASSERT(lfs->cfg->lookahead % 32 == 0); LFS_ASSERT(lfs->cfg->lookahead > 0); @@ -2738,7 +2789,8 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) { } else { lfs->free.buffer = lfs_malloc(lfs->cfg->lookahead/8); if (!lfs->free.buffer) { - return LFS_ERR_NOMEM; + err = LFS_ERR_NOMEM; + goto cleanup; } } @@ -2773,6 +2825,10 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) { lfs_globalzero(&lfs->locals); return 0; + +cleanup: + lfs_deinit(lfs); + return err; } static int lfs_deinit(lfs_t *lfs) { @@ -2809,19 +2865,19 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) { lfs_mdir_t dir; err = lfs_dir_alloc(lfs, &dir); if (err) { - return err; + goto cleanup; } // write root directory lfs_mdir_t root; err = lfs_dir_alloc(lfs, &root); if (err) { - return err; + goto cleanup; } err = lfs_dir_commit(lfs, &root, NULL); if (err) { - return err; + goto cleanup; } lfs->root[0] = root.pair[0]; @@ -2850,16 +2906,18 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) { lfs_pairfromle32(lfs->root); lfs_superblockfromle32(&superblock); if (err) { - return err; + goto cleanup; } // sanity check that fetch works err = lfs_dir_fetch(lfs, &dir, (const lfs_block_t[2]){0, 1}); if (err) { - return err; + goto cleanup; } - return lfs_deinit(lfs); +cleanup: + lfs_deinit(lfs); + return err; } int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) { @@ -2878,7 +2936,7 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) { lfs_mdir_t superdir; err = lfs_dir_fetch(lfs, &superdir, (const lfs_block_t[2]){0, 1}); if (err) { - return err; + goto cleanup; } lfs_superblock_t superblock; @@ -2886,7 +2944,8 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) { LFS_MKTAG(LFS_TYPE_SUPERBLOCK, 0, sizeof(superblock)), &superblock); if (res < 0) { - return res; + err = res; + goto cleanup; } lfs_superblockfromle32(&superblock); @@ -2899,24 +2958,28 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) { uint16_t minor_version = (0xffff & (superblock.version >> 0)); if ((major_version != LFS_DISK_VERSION_MAJOR || minor_version > LFS_DISK_VERSION_MINOR)) { - LFS_ERROR("Invalid version %d.%d", major_version, minor_version); - return LFS_ERR_INVAL; + LFS_ERROR("Invalid version %"PRIu32".%"PRIu32, + major_version, minor_version); + err = LFS_ERR_INVAL; + goto cleanup; } res = lfs_dir_get(lfs, &superdir, 0x7ffff000, LFS_MKTAG(LFS_TYPE_DIRSTRUCT, 0, sizeof(lfs->root)), &lfs->root); if (res < 0) { - return res; + err = res; + goto cleanup; } lfs_pairfromle32(lfs->root); // check superblock configuration if (superblock.attr_max) { if (superblock.attr_max > lfs->attr_max) { - LFS_ERROR("Unsupported attr_max (%d > %d)", + LFS_ERROR("Unsupported attr_max (%"PRIu32" > %"PRIu32")", superblock.attr_max, lfs->attr_max); - return LFS_ERR_INVAL; + err = LFS_ERR_INVAL; + goto cleanup; } lfs->attr_max = superblock.attr_max; @@ -2924,9 +2987,10 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) { if (superblock.name_max) { if (superblock.name_max > lfs->name_max) { - LFS_ERROR("Unsupported name_max (%d > %d)", + LFS_ERROR("Unsupported name_max (%"PRIu32" > %"PRIu32")", superblock.name_max, lfs->name_max); - return LFS_ERR_INVAL; + err = LFS_ERR_INVAL; + goto cleanup; } lfs->name_max = superblock.name_max; @@ -2934,9 +2998,10 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) { if (superblock.inline_max) { if (superblock.inline_max > lfs->inline_max) { - LFS_ERROR("Unsupported inline_max (%d > %d)", + LFS_ERROR("Unsupported inline_max (%"PRIu32" > %"PRIu32")", superblock.inline_max, lfs->inline_max); - return LFS_ERR_INVAL; + err = LFS_ERR_INVAL; + goto cleanup; } lfs->inline_max = superblock.inline_max; @@ -2945,9 +3010,10 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) { // scan for any global updates lfs_mdir_t dir = {.tail = {0, 1}}; while (!lfs_pairisnull(dir.tail)) { - int err = lfs_dir_fetch(lfs, &dir, dir.tail); + err = lfs_dir_fetch(lfs, &dir, dir.tail); if (err) { - return err; + err = LFS_ERR_INVAL; + goto cleanup; } // xor together indirect deletes @@ -2959,13 +3025,17 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) { lfs_globalxor(&lfs->globals, &lfs->locals); lfs_globalzero(&lfs->locals); if (!lfs_pairisnull(lfs->globals.s.movepair)) { - LFS_DEBUG("Found move %d %d %d", + LFS_DEBUG("Found move %"PRIu32" %"PRIu32" %"PRIu32, lfs->globals.s.movepair[0], lfs->globals.s.movepair[1], lfs->globals.s.moveid); } return 0; + +cleanup: + lfs_unmount(lfs); + return err; } int lfs_unmount(lfs_t *lfs) { @@ -3009,7 +3079,7 @@ int lfs_fs_traverse(lfs_t *lfs, lfs_ctzfromle32(&ctz); if (lfs_tagtype(tag) == LFS_TYPE_CTZSTRUCT) { - int err = lfs_ctztraverse(lfs, &lfs->rcache, NULL, + err = lfs_ctztraverse(lfs, &lfs->rcache, NULL, ctz.head, ctz.size, cb, data); if (err) { return err; @@ -3099,7 +3169,8 @@ static int lfs_fs_relocate(lfs_t *lfs, const lfs_block_t oldpair[2], lfs_block_t newpair[2]) { // update internal root if (lfs_paircmp(oldpair, lfs->root) == 0) { - LFS_DEBUG("Relocating root %d %d", newpair[0], newpair[1]); + LFS_DEBUG("Relocating root %"PRIu32" %"PRIu32, + newpair[0], newpair[1]); lfs->root[0] = newpair[0]; lfs->root[1] = newpair[1]; } @@ -3144,7 +3215,7 @@ static int lfs_fs_relocate(lfs_t *lfs, // just replace bad pair, no desync can occur parent.tail[0] = newpair[0]; parent.tail[1] = newpair[1]; - int err = lfs_dir_commit(lfs, &parent, + err = lfs_dir_commit(lfs, &parent, LFS_MKATTR(LFS_TYPE_TAIL + parent.split, 0x3ff, parent.tail, sizeof(parent.tail), NULL)); @@ -3158,7 +3229,7 @@ static int lfs_fs_relocate(lfs_t *lfs, static int lfs_fs_forceconsistency(lfs_t *lfs) { if (!lfs->globals.s.deorphaned) { - LFS_DEBUG("Found orphans %d", + LFS_DEBUG("Found orphans %"PRIu32, lfs->globals.s.deorphaned); // Fix any orphans @@ -3183,7 +3254,7 @@ static int lfs_fs_forceconsistency(lfs_t *lfs) { if (tag == LFS_ERR_NOENT) { // we are an orphan - LFS_DEBUG("Fixing orphan %d %d", + LFS_DEBUG("Fixing orphan %"PRIu32" %"PRIu32, pdir.tail[0], pdir.tail[1]); pdir.tail[0] = dir.tail[0]; @@ -3208,7 +3279,8 @@ static int lfs_fs_forceconsistency(lfs_t *lfs) { if (!lfs_pairsync(pair, pdir.tail)) { // we have desynced - LFS_DEBUG("Fixing half-orphan %d %d", pair[0], pair[1]); + LFS_DEBUG("Fixing half-orphan %"PRIu32" %"PRIu32, + pair[0], pair[1]); pdir.tail[0] = pair[0]; pdir.tail[1] = pair[1]; @@ -3233,7 +3305,7 @@ static int lfs_fs_forceconsistency(lfs_t *lfs) { if (lfs->globals.s.moveid != 0x3ff) { // Fix bad moves - LFS_DEBUG("Fixing move %d %d %d", + LFS_DEBUG("Fixing move %"PRIu32" %"PRIu32" %"PRIu32, lfs->globals.s.movepair[0], lfs->globals.s.movepair[1], lfs->globals.s.moveid); @@ -3291,6 +3363,7 @@ int lfs_fs_setattr(lfs_t *lfs, } static int lfs_fs_size_count(void *p, lfs_block_t block) { + (void)block; lfs_size_t *size = p; *size += 1; return 0; diff --git a/lfs.h b/lfs.h index e7889648683..4ced50ae258 100644 --- a/lfs.h +++ b/lfs.h @@ -1,19 +1,8 @@ /* * The little filesystem * - * Copyright (c) 2017 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright (c) 2017, Arm Limited. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause */ #ifndef LFS_H #define LFS_H @@ -21,6 +10,11 @@ #include #include +#ifdef __cplusplus +extern "C" +{ +#endif + /// Version info /// @@ -481,7 +475,6 @@ int lfs_setattr(lfs_t *lfs, const char *path, int lfs_file_open(lfs_t *lfs, lfs_file_t *file, const char *path, int flags); - // Open a file with extra configuration // // The mode that the file is opened in is determined by the flags, which @@ -653,4 +646,8 @@ int lfs_fs_setattr(lfs_t *lfs, uint8_t type, const void *buffer, lfs_size_t size); +#ifdef __cplusplus +} /* extern "C" */ +#endif + #endif diff --git a/lfs_util.c b/lfs_util.c index 3a2a351b568..9ca0756d96b 100644 --- a/lfs_util.c +++ b/lfs_util.c @@ -1,19 +1,8 @@ /* * lfs util functions * - * Copyright (c) 2017 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright (c) 2017, Arm Limited. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause */ #include "lfs_util.h" diff --git a/lfs_util.h b/lfs_util.h index 6dd28da8816..ed55a1ce8cf 100644 --- a/lfs_util.h +++ b/lfs_util.h @@ -1,19 +1,8 @@ /* * lfs utility functions * - * Copyright (c) 2017 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright (c) 2017, Arm Limited. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause */ #ifndef LFS_UTIL_H #define LFS_UTIL_H @@ -34,6 +23,7 @@ #include #include #include +#include #ifndef LFS_NO_MALLOC #include @@ -45,6 +35,11 @@ #include #endif +#ifdef __cplusplus +extern "C" +{ +#endif + // Macros, may be replaced by system specific wrappers. Arguments to these // macros must not have side-effects as the macros can be removed for a smaller @@ -199,6 +194,7 @@ static inline void *lfs_malloc(size_t size) { #ifndef LFS_NO_MALLOC return malloc(size); #else + (void)size; return NULL; #endif } @@ -207,9 +203,15 @@ static inline void *lfs_malloc(size_t size) { static inline void lfs_free(void *p) { #ifndef LFS_NO_MALLOC free(p); +#else + (void)p; #endif } +#ifdef __cplusplus +} /* extern "C" */ +#endif + #endif #endif diff --git a/tests/test_files.sh b/tests/test_files.sh index b2039a7b1e2..bbecea9285b 100755 --- a/tests/test_files.sh +++ b/tests/test_files.sh @@ -30,7 +30,7 @@ TEST w_test() { tests/test.py << TEST - lfs_size_t size = $1; + size = $1; lfs_size_t chunk = 31; srand(0); lfs_mount(&lfs, &cfg) => 0; @@ -50,7 +50,7 @@ TEST r_test() { tests/test.py << TEST - lfs_size_t size = $1; + size = $1; lfs_size_t chunk = 29; srand(0); lfs_mount(&lfs, &cfg) => 0; diff --git a/tests/test_seek.sh b/tests/test_seek.sh index 3b46892b6ea..0084d42f167 100755 --- a/tests/test_seek.sh +++ b/tests/test_seek.sh @@ -153,7 +153,7 @@ tests/test.py << TEST lfs_file_read(&lfs, &file[0], buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; - lfs_size_t size = lfs_file_size(&lfs, &file[0]); + size = lfs_file_size(&lfs, &file[0]); lfs_file_seek(&lfs, &file[0], 0, LFS_SEEK_CUR) => size; lfs_file_close(&lfs, &file[0]) => 0; @@ -202,7 +202,7 @@ tests/test.py << TEST lfs_file_read(&lfs, &file[0], buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; - lfs_size_t size = lfs_file_size(&lfs, &file[0]); + size = lfs_file_size(&lfs, &file[0]); lfs_file_seek(&lfs, &file[0], 0, LFS_SEEK_CUR) => size; lfs_file_close(&lfs, &file[0]) => 0; @@ -243,7 +243,7 @@ tests/test.py << TEST lfs_file_read(&lfs, &file[0], buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; - lfs_size_t size = lfs_file_size(&lfs, &file[0]); + size = lfs_file_size(&lfs, &file[0]); lfs_file_seek(&lfs, &file[0], 0, LFS_SEEK_CUR) => size; lfs_file_close(&lfs, &file[0]) => 0; @@ -286,7 +286,7 @@ tests/test.py << TEST lfs_file_read(&lfs, &file[0], buffer, size) => size; memcmp(buffer, "kittycatcat", size) => 0; - lfs_size_t size = lfs_file_size(&lfs, &file[0]); + size = lfs_file_size(&lfs, &file[0]); lfs_file_seek(&lfs, &file[0], 0, LFS_SEEK_CUR) => size; lfs_file_close(&lfs, &file[0]) => 0;