-
Notifications
You must be signed in to change notification settings - Fork 804
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fall in assert when write file size bigger than block size. #6
Comments
I had a similar issue when the block_size value was not a multiple of the prog_size. |
Large files should be checked by this test (block size = 512B, file size = 262144B). I think @Roceh is right, block_size needs to be a multiple of the prog_size. I should probably add an assert for this. EDIT: I've added an assert here. What is the geometry of your block device (read size, prog size, erase size)? Out of curiousity, what form of storage are you guys running into where the block size isn't a multiple of the program size? |
Hi, #define LFS_RBUF_SIZE 128 // Read bufffer size static uint8_t read_buf[LFS_RBUF_SIZE]; static const struct lfs_config cfg = .read_size = LFS_RBUF_SIZE, .read_buffer = read_buf, |
Hi @zhabl, that looks correct. Unfortunately, I can't seem to reproduce the assert. Running the tests seem happy enough with your config, even after modifying the tests to use static memory: CFLAGS="-DLFS_READ_SIZE=128 -DLFS_PROG_SIZE=128 -DLFS_BLOCK_SIZE=4096 -DLFS_BLOCK_COUNT=512 -DLFS_LOOKAHEAD=128" make test_dirs test_files What filesystem operations did you run before you hit the assert? Do you have a code snippet? That specific assert could be caused by malformed data on the disk. littlefs would notice if data was corrupted during a write, but afterwards littlefs wouldn't notice if something else corrupts the data (such as another program or a rogue filesystem structure). Have you been able to read/write/erase directly to the W25Q16 chip without successfully? If may be also worthwhile to try reformatting the disk with lfs_format to get rid of any old filesystem structures left over from previous configurations. |
Hi geky now, head = first block number of the file. I am not sure what this dose, lfs_cache_read() read the first 4 bytes of the block, then hit the assert. Here are part of memory dump of w25q16. Block 2. Block 7. |
Hmm, I'm still not able to reproduce the bug. I put together a quick test that writes a single byte every mount, but it seems to work fine on the setup I have. I'm wondering if this is a compiler/architecture issue, maybe around the ctz or popcount instructions. What compiler and architecture are you using? Also what is the hash of littlefs that you are using? If it's an issue with the static inline uint32_t lfs_ctz(uint32_t a) {
uint32_t r = 32;
a &= -a;
if (a) r -= 1;
if (a & 0x0000ffff) r -= 16;
if (a & 0x00ff00ff) r -= 8;
if (a & 0x0f0f0f0f) r -= 4;
if (a & 0x33333333) r -= 2;
if (a & 0x55555555) r -= 1;
return r;
}
static inline uint32_t lfs_npw2(uint32_t a) {
uint32_t r = 0;
uint32_t s;
s = (a > 0xffff) << 4; a >>= s; r |= s;
s = (a > 0xff ) << 3; a >>= s; r |= s;
s = (a > 0xf ) << 2; a >>= s; r |= s;
s = (a > 0x3 ) << 1; a >>= s; r |= s;
return r | (a >> 1);
}
static inline uint32_t lfs_popc(uint32_t a) {
a = a - ((a >> 1) & 0x55555555);
a = (a & 0x33333333) + ((a >> 2) & 0x33333333);
return (((a + (a >> 4)) & 0xf0f0f0f) * 0x1010101) >> 24;
} Here's some explanation on what's going on. The ctz skip-list looks like this:
The number of pointers is based on the equation In the code snippet you posted, we should be appending Since the logic is working on a different setup, I suspect it may be an issue with the compiler/architecture specific instructions and I'd be interested to know which compiler/architecture you're on. |
Yes!,it works after i replaced that three functions. You are right,this is an issue of compiler. |
Oh that's interesting. Did you have to change the implementations of |
I have not change the implementations of lfs_ctz/lfs_popc, Keil compiler provide compatibility of GNU build-in functions, may be not fully compatible. A software implementation of lfs_ctz/lfs_popc is needed. |
Could you not provide malloc/free/assert through their standard names? |
Yes i can provide these functions throuth standard names , but they should have 'private' names , easy to turn off assertion when release. |
That's a good point. I will add wrappers for assert/malloc/free when I get a chance. |
Hi:
It seems that file data has been read out and copied to 'head'.
line 1162, lfs.c
assert(head >= 2 && head <= lfs->cfg->block_count);
The text was updated successfully, but these errors were encountered: