Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/littlefs-project/littlefs.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2023-05-23Merge pull request #832 from littlefs-project/remove-sys-typesv2.6.1Christopher Haster
Remove unnecessary sys/types.h include
2023-05-23Merge pull request #819 from benpicco/fix-AVRChristopher Haster
Fix build for AVR
2023-05-23Merge pull request #818 from littlefs-project/convince-github-littlefs-is-cChristopher Haster
Convince GitHub littlefs is a C project
2023-05-17Removed unnecessary sys/types.h includeremove-sys-typesChristopher Haster
Likely included at some point for ssize_t, this is no longer needed and causes some problems for embedded compilers. Currently littlefs doesn't even use size_t/ssize_t in its definition of lfs_size_t/lfs_ssize_t, so I don't think this will ever be required. Found by LDong-Arm, vvn-git
2023-05-05Fix build for AVRBenjamin Valentin
This fixes the overflowing left shift on 8 bit platforms. littlefs2/lfs.c: In function ‘lfs_dir_commitcrc’: littlefs2/lfs.c:1654:51: error: left shift count >= width of type [-Werror=shift-count-overflow] commit->ptag = ntag ^ ((0x80 & ~eperturb) << 24);
2023-05-04Reclassify .toml files as .c files on GitHubconvince-github-littlefs-is-cChristopher Haster
With the new test framework, GitHub really wants to mark littlefs as a python project. telling it to reclassify our test .toml files as C code (which they are 95% of anyways) remedies this. An alternative would be to add syntax=c vim modelines to the test/bench files, which would also render them with C syntax highlighting on GitHub. Unfortunately the interspersed toml metadata mucks this up, making the result not very useful.
2023-05-04Merge pull request #814 from littlefs-project/develv2.6.0Christopher Haster
Minor release: v2.6
2023-05-01Merge pull request #812 from littlefs-project/mkconsistentChristopher Haster
Add lfs_fs_mkconsistent
2023-05-01Merge pull request #811 from littlefs-project/fix-deorphan-repeatedlyChristopher Haster
Fix issue where lfs_fs_deorphan may run more than needed
2023-04-27Added lfs_fs_mkconsistentmkconsistentChristopher Haster
lfs_fs_mkconsistent allows running the internal consistency operations (desuperblock/deorphan/demove) on demand and without any other filesystem changes. This can be useful for front-loading and persisting consistency operations when you don't want to pay for this cost on the first write to the filesystem. Conveniently, this also offers a way to force the on-disk minor version to bump, if that is wanted behavior. Idea from kasper0
2023-04-27Fixed issue where lfs_fs_deorphan may run more than neededfix-deorphan-repeatedlyChristopher Haster
The underlying issue is that lfs_fs_deorphan did not updating gstate correctly. The way it determined if there are any orphans remaining in the filesystem was by subtracting the number of found orphans from an internal counter. This internal counter is a leftover from a previous implementation that allowed leaving the lfs_fs_deorphan loop early if we know the number of expected orphans. This can happen during recursive mdir relocations, but with only a single bit in the gstate, can't happen during mount. If we detect orphans during mount, we set this internal counter to 1, assuming we will find at least one orphan. But this presents a problem, what if we find _no_ orphans? If this happens we never decrement the internal counter of orphans, so we would never clear the bit in the gstate. This leads to a running lfs_fs_deorphan on more-or-less every mutable operation in the filesystem, resulting in an extreme performance hit. The solution here is to not subtract the number of found orphans, but assume that when our lfs_fs_deorphan loop finishes, we will have no orphans, because that's the whole point of lfs_fs_deorphan. Note that the early termination of lfs_fs_deorphan was dropped because it would not actually change the runtime complexity of lfs_fs_deorphan, adds code cost, and risks fragile corner cases such as this one. --- Also added tests to assert we run lfs_fs_deorphan at most once. Found by kasper0 and Ldd309
2023-04-26Merge pull request #805 from littlefs-project/fix-dir-seek-endChristopher Haster
Fix issue where seeking to end-of-directory return LFS_ERR_INVAL
2023-04-26Merge pull request #800 from littlefs-project/fix-boundary-truncatesChristopher Haster
Fix block-boundary truncate issues
2023-04-26Merge remote-tracking branch 'origin/devel' into fix-dir-seek-endfix-dir-seek-endChristopher Haster
2023-04-26Merge remote-tracking branch 'origin/devel' into fix-boundary-truncatesfix-boundary-truncatesChristopher Haster
2023-04-26Merge pull request #802 from littlefs-project/assert-minimum-block-sizeChristopher Haster
Add explicit assert for minimum block size of 128 bytes
2023-04-26Merge pull request #801 from littlefs-project/assert-bool-castChristopher Haster
Add an assert for truthy-preserving bool conversions
2023-04-26Merge pull request #807 from littlefs-project/doc-link-littlefs2-rustChristopher Haster
Add littlefs2 crate to README
2023-04-26Tweaked wording of littlefs2-rust link in README.mddoc-link-littlefs2-rustChristopher Haster
2023-04-26chore: add littlefs2 crate to READMELachezar Lechev
2023-04-26Merge pull request #718 from yomimono/mention-chamelonChristopher Haster
Add "chamelon" to the related projects section.
2023-04-26Merge pull request #572 from tniessen/add-littlefs-disk-img-viewerChristopher Haster
Add littlefs-disk-img-viewer to README
2023-04-26Merge pull request #809 from littlefs-project/brent-cycle-detectionChristopher Haster
Adopt Brent's algorithm for cycle detection
2023-04-26Merge pull request #497 from littlefs-project/crc-rework-2Christopher Haster
Forward-looking erase-state CRCs
2023-04-26Merge pull request #752 from littlefs-project/test-and-bench-runnersChristopher Haster
Add test/bench runners, benchmarks, additional scripts
2023-04-21Added FCRC tags and an explanation of how FCRCs work to SPEC.mdcrc-rework-2Christopher Haster
See SPEC.md for more info. Also considered adding an explanation to DESIGN.md, but there's not a great place for it. Maybe FCRCs are too low-level for the high-level design document. Though may be worth reconsidering if DESIGN.md gets revisited.
2023-04-21Bumped minor version to v2.6 and on-disk minor version to lfs2.1Christopher Haster
2023-04-21Added ability to bump on-disk minor versionChristopher Haster
This just means a rewrite of the superblock entry with the new minor version. Though it's interesting to note, we don't need to rewrite the superblock entry until the first write operation in the filesystem, an optimization that is already in use for the fixing of orphans and in-flight moves. To keep track of any outdated minor version found during lfs_mount, we can carve out a bit from the reserved bits in our gstate. These are currently used for a counter tracking the number of orphans in the filesystem, but this is usually a very small number so this hopefully won't be an issue. In-device gstate tag: [-- 32 --] [1|- 11 -| 10 |1| 9 ] ^----^-----^--^--^-- 1-bit has orphans '-----|--|--|-- 11-bit move type '--|--|-- 10-bit move id '--|-- 1-bit needs superblock '-- 9-bit orphan count
2023-04-21Added compatibility testing on pull-request to GitHub test actionChristopher Haster
This uses the "github.event.pull_request.base.ref" variable as the "lfsp" target for compatibility testing.
2023-04-21Added tests for forwards and backwards disk compatibilityChristopher Haster
This is a bit tricky since we need two different version of littlefs in order to test for most compatibility concerns. Fortunately we already have scripts/changeprefix.py for version-specific symbols, so it's not that hard to link in the previous version of littlefs in CI as a separate set of symbols, "lfsp_" in this case. So that we can at least test the compatibility tests locally, I've added an ifdef against the expected define "LFSP" to define a set of aliases mapping "lfsp_" symbols to "lfs_" symbols. This is manual at the moment, and a bit hacky, but gets the job done. --- Also changed BUILDDIR creation to derive subdirectories from a few Makefile variables. This makes the subdirectories less manual and more flexible for things like LFSP. Note this wasn't possible until BUILDDIR was changed to default to "." when omitted.
2023-04-20Tweaked changeprefix.py to not rename dir component in pathsChristopher Haster
This wasn't implemented correctly anyways, as it would need to recursively rename directories that may not exist. Things would also get a bit complicated if only some files in a directory were renamed. Doable, but not needed for our use case. For now just ignore any directory components. Though this may be worth changing if the source directory structure becomes more complicated in the future (maybe with a -r/--recursive flag?).
2023-04-19Tweaked link to littlefs-disk-img-viewer to go to github repoChristopher Haster
2023-04-18Fixed issue where seeking to end-of-directory return LFS_ERR_INVALChristopher Haster
This was just an oversight. Seeking to the end of the directory should not error, but instead restore the directory to the state where the next read returns 0. Note this matches the behavior of lfs_file_tell/lfs_file_seek. Found by sosthene-nitrokey
2023-04-18Extend dir seek tests to include seeking to end of directoryChristopher Haster
2023-04-18Added explicit assert for minimum block size of 128 bytesassert-minimum-block-sizeChristopher Haster
There was already an assert for this, but because it included the underlying equation for the requirement it was too confusing for users that had no prior knowledge for why the assert could trigger. The math works out such that 128 bytes is a reasonable minimum requirement, so I've added that number as an explicit assert. Hopefully this makes this sort of situation easier to debug. Note that this requirement would need to be increased to 512 bytes if block addresses are ever increased to 64-bits. DESIGN.md goes into more detail why this is.
2023-04-18Added an assert for truthy-preserving bool conversionsassert-bool-castChristopher Haster
This has caught enough people that an explicit assert is warranted. How littlefs, a c99 project, should be integrated with c89 projects is still an open question, but no one deserves to debug this sort of undetected casting issue. Found by johnernberg and XinStellaris
2023-04-18Added ability to revert to inline file in lfs_file_truncateChristopher Haster
Before, once converted to a CTZ skip-list, a file would remain a CTZ skip-list even if truncated back to a size that could be inlined. This was just a shortcut in implementation. And since the fix for boundary truncates needed special handling for size==0, it made sense to extend this special condition to allow reverting to inline files. --- The only case I can think of, where reverting to an inline file would be detrimental, is if it's a readonly file that you would otherwise not need to pay the metadata overhead for. But as a tradeoff, inlining the file would free up the block it was on, so it's unclear if this really is a net loss. If the truncate is followed by a write, reverting to an inline file will always be beneficial. We assume writes will change the data, so in the non-inlined case there's no way to avoid copying the underlying block. Even if we assume padding issues are solved.
2023-04-18Fixed block-boundary truncate issueChristopher Haster
There has been a bug in the filesystem for a while where truncating to a block boundary suffers from an off-by-one mistake that corrupts the internal representation of the CTZ skip-list. This mostly appears when the file_size == block_size, as file_size > block_size includes CTZ skip-list metadata, so the underlying block boundaries appear at slightly different offsets. --- The reason for off-by-one issue is a nuance in lfs_ctz_find that we sort of abuse to get two different behaviors. Consider the situation where this bug occurs: block 0 block 1 .--------. .--------. | abcdef |<-| {ptr0} | | ghijkl | | yzabcd | | mnopqr | | | | stuvwx | | | '--------' '--------' With these 24-byte blocks, there's an ambiguity if we wanted to point to offset 24. We could point before the block boundary, or we could point after the block boundary Before: block 0 block 1 .--------. .--------. | abcdef |<-| {ptr0} | | ghijkl | | yzabcd | | mnopqr | | | | stuvwx | | | '-------^' '--------' '-- off=24 is here After: block 0 block 1 .--------. .--------. | abcdef |<-| {ptr0} | | ghijkl | | yzabcd | | mnopqr | | ^ | | stuvwx | | | | '--------' '-|------' '-- off=24 is here When we want these two offsets depends on the context. We want the offset to be conservative if it represents a size, but eager if it is being used to prepare a block for writing. The workaround/hack is to prefer the eager offset, after the block boundary, but use `size-1` as the argument if we need the conservative offset. This finds the correct block, but is off-by-one in the calculated block-offset. Fortunately we happen to not use the block-offset in the places we need this workaround/hack. --- To get back to the bug, the wrong mode of lfs_ctz_find was used in lfs_file_truncate, leading to internal corruption of the CTZ skip-list. The correct behavior is size-1, with care to avoid underflow. Also I've tweaked the code to make it clear the calculated block-offset goes unused in these situations. Thanks to ghost, ajaybhargav, and others for reporting the issue, colin-foster-advantage for a reproducible test case, and rvanschoren, hgspbs for the initial solution.
2023-04-17Expanded truncate tests to test more corner casesChristopher Haster
Removed the weird alignment requirement from the general truncate tests. This explicitly hid off-by-one truncation errors. These tests now reveal the same issue as the block-sized truncation test while also testing for other potential off-by-one errors.
2023-03-13Add missing iterations in testsSosthène Guédon
2023-01-26Add test scenario for truncating to a block sizeColin Foster
When truncation is done on a file to the block size, there seems to be an error where it points to an incorrect block. Perform a write / truncate / readback operation to verify this issue. Signed-off-by: Colin Foster <colin.foster@in-advantage.com>
2022-12-17Fixed issue where deorphan could get stuck circling between two half-orphansChristopher Haster
This of course should never happen normally, two half-orphans requires two parents, which is disallowed in littlefs for this reason. But it can happen if there is an outdated half-orphan later in the metadata linked-list. The two half-orphans can cause the deorphan step to get stuck, constantly "fixing" the first half-orphan before it has a chance to remove the problematic, outdated half-orphan later in the list. The solution here is to do a full check for half-orphans before restarting the half-orphan loop. This strategy has the potential to visit more metadata blocks unnecessarily, but avoids situations where removing a later half-orphan will eventually cause an earlier half-orphan to resolve itself. Found with heuristic powerloss testing with test_relocations_reentrant_renames after 192 nested powerlosses.
2022-12-17Reverted removal of 1-bit counter threaded through tagsChristopher Haster
Initially I thought the fcrc would be sufficient for all of the end-of-commit context, since indicating that there is a new commit is a simple as invalidating the fcrc. But it turns out there are cases that make this impossible. The surprising, and actually common, case, is that of an fcrc that will end up containing a full commit. This is common as soon as the prog_size is big, as small commits are padded to the prog_size at minimum. .------------------. \ | metadata | | | | | | | +-. |------------------| | | | foward CRC ------------. |------------------| / | | | commit CRC -----' | |------------------| | | padding | | | | | |------------------| \ \ | | metadata | | | | | | +-. | | | | | | +-' |------------------| / | | | commit CRC --------' | |------------------| | | | / '------------------' When the commit + crc is all contained in the fcrc, something silly happens with the math behind crcs. Everything in the commit gets canceled out: crc(m) = m(x) x^|P|-1 mod P(x) m ++ crc(m) = m(x) x^|P|-1 + (m(x) x^|P|-1 mod P(x)) crc(m ++ crc(m)) = (m(x) x^|P|-1 + (m(x) x^|P|-1 mod P(x))) x^|P|-1 mod P(x) crc(m ++ crc(m)) = (m(x) x^|P|-1 + m(x) x^|P|-1) x^|P|-1 mod P(x) crc(m ++ crc(m)) = 0 * x^|P|-1 mod P(x) This is the reason the crc of a message + naive crc is zero. Even with an initializer/bit-fiddling, the crc of the whole commit ends up as some constant. So no manipulation of the commit can change the fcrc... But even if this did work, or we changed this scheme to use two different checksums, it would still require calculating the fcrc of the whole commit to know if we need to tweak the first bit to invalidate the unlikely-but-problematic case where we happen to match the fcrc. This would add a large amount of complexity to the commit code. It's much simpler and cheaper to keep the 1-bit counter in the tag, even if it adds another moving part to the system.
2022-12-17Continued implementation of forward-crcs, adopted new test runnersChristopher Haster
This fixes most of the remaining bugs (except one with multiple padding commits + noop erases in test_badblocks), with some other code tweaks. The biggest change was dropping reliance on end-of-block commits to know when to stop parsing commits. We can just continue to parse tags and rely on the crc for catch bad commits, avoiding a backwards-compatiblity hiccup. So no new commit tag. Also renamed nprogcrc -> fcrc and commitcrc -> ccrc and made naming in the code a bit more consistent.
2022-12-17Switched to separate-tag encoding of forward-looking CRCsChristopher Haster
Previously forward-looking CRCs was just two new CRC types, one for commits with forward-looking CRCs, one without. These both contained the CRC needed to complete the current commit (note that the commit CRC must come last!). [-- 32 --|-- 32 --|-- 32 --|-- 32 --] with: [ crc3 tag | nprog size | nprog crc | commit crc ] without: [ crc2 tag | commit crc ] This meant there had to be several checks for the two possible structure sizes, messying up the implementation. [-- 32 --|-- 32 --|-- 32 --|-- 32 --|-- 32 --] with: [nprogcrc tag| nprog size | nprog crc | commit tag | commit crc ] without: [ commit tag | commit crc ] But we already have a mechanism for storing optional metadata! The different metadata tags! So why not use a separate tage for the forward-looking CRC, separate from the commit CRC? I wasn't sure this would actually help that much, there are still necessary conditions for wether or not a forward-looking CRC is there, but in the end it simplified the code quite nicely, and resulted in a ~200 byte code-cost saving.
2022-12-17Cleaned up a few additional commit corner casesChristopher Haster
- General cleanup from integration, including cleaning up some older commit code - Partial-prog tests do not make sense when prog_size == block_size (there can't be partial-progs!) - Fixed signed-comparison issue in modified filebd
2022-12-17Initial implementation of forward-looking erase-state CRCsChristopher Haster
This change is necessary to handle out-of-order writes found by pjsg's fuzzing work. The problem is that it is possible for (non-NOR) block devices to write pages in any order, or to even write random data in the case of a power-loss. This breaks littlefs's use of the first bit in a page to indicate the erase-state. pjsg notes this behavior is documented in the W25Q here: https://community.cypress.com/docs/DOC-10507 --- The basic idea here is to CRC the next page, and use this "erase-state CRC" to check if the next page is erased and ready to accept programs. .------------------. \ commit | metadata | | | | +---. | | | | |------------------| | | | erase-state CRC -----. | |------------------| | | | | commit CRC ---|-|-' |------------------| / | | padding | | padding (doesn't need CRC) | | | |------------------| \ | next prog | erased? | +-' | | | | | v | / | | | | '------------------' This is made a bit annoying since littlefs doesn't actually store the page (prog_size) in the superblock, since it doesn't need to know the size for any other operation. We can work around this by storing both the CRC and size of the next page when necessary. Another interesting note is that we don't need to any bit tweaking information, since we read the next page every time we would need to know how to clobber the erase-state CRC. And since we only read prog_size, this works really well with our caching, since the caches must be a multiple of prog_size. This also brings back the internal lfs_bd_crc function, in which we can use some optimizations added to lfs_bd_cmp. Needs some cleanup but the idea is passing most relevant tests.
2022-12-17Adopted Brent's algorithm for cycle detectionbrent-cycle-detectionChristopher Haster
The previous cycle detection algorithm (a naive check against the largest possible tail list) is simple and gets the job done, but has the potential to take a very long time on disks with many blocks. Brent's algorithm, on the other hand, takes at most 2x the number of blocks in the tail list. Originally naive cycle detection was chosen over Floyd's algorithm to avoid the extra complexity of managing two desynced traversals for every traversal of the tail list, but Brent's algorithm is very well suited for our use case, requiring only we keep track of an additional mdir pointer on the stack as we traverse.
2022-12-17Added --gdb-pl to test.py for breaking on specific powerlossestest-and-bench-runnersChristopher Haster
This allows debugging strategies such as binary searching for the point of "failure", which may be more complex than simply failing an assert.
2022-12-17Tweaked/fixed a number of small runner things after a bit of useChristopher Haster
- Added support for negative numbers in the leb16 encoding with an optional 'w' prefix. - Changed prettyasserts.py rule to .a.c => .c, allowing other .a.c files in the future. - Updated .gitignore with missing generated files (tags, .csv). - Removed suite-namespacing of test symbols, these are no longer needed. - Changed test define overrides to have higher priority than explicit defines encoded in test ids. So: ./runners/bench_runner bench_dir_open:0f1g12gg2b8c8dgg4e0 -DREAD_SIZE=16 Behaves as expected. Otherwise it's not easy to experiment with known failing test cases. - Fixed issue where the -b flag ignored explicit test/bench ids.