mirror of
				https://github.com/eledio-devices/thirdparty-littlefs.git
				synced 2025-10-31 16:14:16 +01:00 
			
		
		
		
	Reduced when custom attributse are written to strictly when files are dirty
This is a bit of a complicated area for the custom-attribute API without
much precedent. littlefs allows users to provide custom attributes in
the lfs_file_config struct, which get written along with other file
metadata.
Sounds great on paper, but the devil is in the details. When does the
metadata actually get written?
What about this case?
    lfs_file_opencfg(lfs, file, "path", LFS_O_WRONLY, cfg_with_attrs);
    lfs_file_close(lfs, file); // does not write metadata
This normally doesn't write out metadata! We've opened the file for
writing, but made no changes, so normally littlefs doesn't bother to
commit anything to disk.
Before, as a courtesy, littlefs marked the file as dirty if it noticed
the file was opened for writing with custom attributes, but this is
inaccurate could to leave to problems after a file is synced:
    lfs_file_opencfg(lfs, file, "path", LFS_O_WRONLY, cfg_with_attrs);
    lfs_file_sync(lfs, file);
    change_attrs();
    lfs_file_close(lfs, file); // does not write metadata
Unfortunately, it isn't easy to know when metadata needs to be written.
Custom attributes are provided as read-only pointers to buffers which
may be updated without additional filesystem calls, this means we don't
know if custom attributes have actually changed on the device side. If
they haven't changed, writing out metadata on every sync would be
wasteful.
Another solution would be to compare our device-side attributes with
the disk-side attributes every sync, but that would be even more
expensive.
---
So for now, the simpliest and most efficient solution wins. Custom
attributes attached to open files, are not written unless the file data
itself changes.
Note that explicit calls to lfs_setattr always update on-disk
attributes, and opening a file with LFS_O_CREATE | LFS_O_TRUNC will also
always update the on-disk attributes (though not with just LFS_O_CREAT!).
There are a few ways we could provide an API that manually forces a write
of custom attributes, such as lfs_file_setattr, though without dynamic
memory, providing these APIs gets a bit complicated. So for now we will
see if users run into issues with the current scheme.
			
			
This commit is contained in:
		
							
								
								
									
										8
									
								
								lfs.c
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								lfs.c
									
									
									
									
									
								
							| @@ -2506,11 +2506,12 @@ static int lfs_file_rawopencfg(lfs_t *lfs, lfs_file_t *file, | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         // get next slot and create entry to remember name |         // get next slot and create entry to remember name | ||||||
|         // TODO commit with attrs? |  | ||||||
|         err = lfs_dir_commit(lfs, &file->m, LFS_MKATTRS( |         err = lfs_dir_commit(lfs, &file->m, LFS_MKATTRS( | ||||||
|                 {LFS_MKTAG(LFS_TYPE_CREATE, file->id, 0), NULL}, |                 {LFS_MKTAG(LFS_TYPE_CREATE, file->id, 0), NULL}, | ||||||
|                 {LFS_MKTAG(LFS_TYPE_REG, file->id, nlen), path}, |                 {LFS_MKTAG(LFS_TYPE_REG, file->id, nlen), path}, | ||||||
|                 {LFS_MKTAG(LFS_TYPE_INLINESTRUCT, file->id, 0), NULL})); |                 {LFS_MKTAG(LFS_TYPE_INLINESTRUCT, file->id, 0), NULL}, | ||||||
|  |                 {LFS_MKTAG(LFS_FROM_USERATTRS, file->id, | ||||||
|  |                     file->cfg->attr_count), file->cfg->attrs})); | ||||||
|         if (err) { |         if (err) { | ||||||
|             err = LFS_ERR_NAMETOOLONG; |             err = LFS_ERR_NAMETOOLONG; | ||||||
|             goto cleanup; |             goto cleanup; | ||||||
| @@ -2563,9 +2564,6 @@ static int lfs_file_rawopencfg(lfs_t *lfs, lfs_file_t *file, | |||||||
|                 err = LFS_ERR_NOSPC; |                 err = LFS_ERR_NOSPC; | ||||||
|                 goto cleanup; |                 goto cleanup; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             // TODO remove this? |  | ||||||
|             file->flags |= LFS_F_DIRTY; |  | ||||||
|         } |         } | ||||||
| #endif | #endif | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -16,41 +16,41 @@ code = ''' | |||||||
|     lfs_getattr(&lfs, "hello", 'A', buffer,    4) => 4; |     lfs_getattr(&lfs, "hello", 'A', buffer,    4) => 4; | ||||||
|     lfs_getattr(&lfs, "hello", 'B', buffer+4,  6) => 6; |     lfs_getattr(&lfs, "hello", 'B', buffer+4,  6) => 6; | ||||||
|     lfs_getattr(&lfs, "hello", 'C', buffer+10, 5) => 5; |     lfs_getattr(&lfs, "hello", 'C', buffer+10, 5) => 5; | ||||||
|     memcmp(buffer,    "aaaa",   4) => 0; |     assert(memcmp(buffer,    "aaaa",   4) == 0); | ||||||
|     memcmp(buffer+4,  "bbbbbb", 6) => 0; |     assert(memcmp(buffer+4,  "bbbbbb", 6) == 0); | ||||||
|     memcmp(buffer+10, "ccccc",  5) => 0; |     assert(memcmp(buffer+10, "ccccc",  5) == 0); | ||||||
|  |  | ||||||
|     lfs_setattr(&lfs, "hello", 'B', "", 0) => 0; |     lfs_setattr(&lfs, "hello", 'B', "", 0) => 0; | ||||||
|     lfs_getattr(&lfs, "hello", 'A', buffer,    4) => 4; |     lfs_getattr(&lfs, "hello", 'A', buffer,    4) => 4; | ||||||
|     lfs_getattr(&lfs, "hello", 'B', buffer+4,  6) => 0; |     lfs_getattr(&lfs, "hello", 'B', buffer+4,  6) => 0; | ||||||
|     lfs_getattr(&lfs, "hello", 'C', buffer+10, 5) => 5; |     lfs_getattr(&lfs, "hello", 'C', buffer+10, 5) => 5; | ||||||
|     memcmp(buffer,    "aaaa",         4) => 0; |     assert(memcmp(buffer,    "aaaa",         4) == 0); | ||||||
|     memcmp(buffer+4,  "\0\0\0\0\0\0", 6) => 0; |     assert(memcmp(buffer+4,  "\0\0\0\0\0\0", 6) == 0); | ||||||
|     memcmp(buffer+10, "ccccc",        5) => 0; |     assert(memcmp(buffer+10, "ccccc",        5) == 0); | ||||||
|  |  | ||||||
|     lfs_removeattr(&lfs, "hello", 'B') => 0; |     lfs_removeattr(&lfs, "hello", 'B') => 0; | ||||||
|     lfs_getattr(&lfs, "hello", 'A', buffer,    4) => 4; |     lfs_getattr(&lfs, "hello", 'A', buffer,    4) => 4; | ||||||
|     lfs_getattr(&lfs, "hello", 'B', buffer+4,  6) => LFS_ERR_NOATTR; |     lfs_getattr(&lfs, "hello", 'B', buffer+4,  6) => LFS_ERR_NOATTR; | ||||||
|     lfs_getattr(&lfs, "hello", 'C', buffer+10, 5) => 5; |     lfs_getattr(&lfs, "hello", 'C', buffer+10, 5) => 5; | ||||||
|     memcmp(buffer,    "aaaa",         4) => 0; |     assert(memcmp(buffer,    "aaaa",         4) == 0); | ||||||
|     memcmp(buffer+4,  "\0\0\0\0\0\0", 6) => 0; |     assert(memcmp(buffer+4,  "\0\0\0\0\0\0", 6) == 0); | ||||||
|     memcmp(buffer+10, "ccccc",        5) => 0; |     assert(memcmp(buffer+10, "ccccc",        5) == 0); | ||||||
|  |  | ||||||
|     lfs_setattr(&lfs, "hello", 'B', "dddddd", 6) => 0; |     lfs_setattr(&lfs, "hello", 'B', "dddddd", 6) => 0; | ||||||
|     lfs_getattr(&lfs, "hello", 'A', buffer,    4) => 4; |     lfs_getattr(&lfs, "hello", 'A', buffer,    4) => 4; | ||||||
|     lfs_getattr(&lfs, "hello", 'B', buffer+4,  6) => 6; |     lfs_getattr(&lfs, "hello", 'B', buffer+4,  6) => 6; | ||||||
|     lfs_getattr(&lfs, "hello", 'C', buffer+10, 5) => 5; |     lfs_getattr(&lfs, "hello", 'C', buffer+10, 5) => 5; | ||||||
|     memcmp(buffer,    "aaaa",   4) => 0; |     assert(memcmp(buffer,    "aaaa",   4) == 0); | ||||||
|     memcmp(buffer+4,  "dddddd", 6) => 0; |     assert(memcmp(buffer+4,  "dddddd", 6) == 0); | ||||||
|     memcmp(buffer+10, "ccccc",  5) => 0; |     assert(memcmp(buffer+10, "ccccc",  5) == 0); | ||||||
|  |  | ||||||
|     lfs_setattr(&lfs, "hello", 'B', "eee", 3) => 0; |     lfs_setattr(&lfs, "hello", 'B', "eee", 3) => 0; | ||||||
|     lfs_getattr(&lfs, "hello", 'A', buffer,    4) => 4; |     lfs_getattr(&lfs, "hello", 'A', buffer,    4) => 4; | ||||||
|     lfs_getattr(&lfs, "hello", 'B', buffer+4,  6) => 3; |     lfs_getattr(&lfs, "hello", 'B', buffer+4,  6) => 3; | ||||||
|     lfs_getattr(&lfs, "hello", 'C', buffer+10, 5) => 5; |     lfs_getattr(&lfs, "hello", 'C', buffer+10, 5) => 5; | ||||||
|     memcmp(buffer,    "aaaa",      4) => 0; |     assert(memcmp(buffer,    "aaaa",      4) == 0); | ||||||
|     memcmp(buffer+4,  "eee\0\0\0", 6) => 0; |     assert(memcmp(buffer+4,  "eee\0\0\0", 6) == 0); | ||||||
|     memcmp(buffer+10, "ccccc",     5) => 0; |     assert(memcmp(buffer+10, "ccccc",     5) == 0); | ||||||
|  |  | ||||||
|     lfs_setattr(&lfs, "hello", 'A', buffer, LFS_ATTR_MAX+1) => LFS_ERR_NOSPC; |     lfs_setattr(&lfs, "hello", 'A', buffer, LFS_ATTR_MAX+1) => LFS_ERR_NOSPC; | ||||||
|     lfs_setattr(&lfs, "hello", 'B', "fffffffff", 9) => 0; |     lfs_setattr(&lfs, "hello", 'B', "fffffffff", 9) => 0; | ||||||
| @@ -65,13 +65,13 @@ code = ''' | |||||||
|     lfs_getattr(&lfs, "hello", 'A', buffer,    4) => 4; |     lfs_getattr(&lfs, "hello", 'A', buffer,    4) => 4; | ||||||
|     lfs_getattr(&lfs, "hello", 'B', buffer+4,  9) => 9; |     lfs_getattr(&lfs, "hello", 'B', buffer+4,  9) => 9; | ||||||
|     lfs_getattr(&lfs, "hello", 'C', buffer+13, 5) => 5; |     lfs_getattr(&lfs, "hello", 'C', buffer+13, 5) => 5; | ||||||
|     memcmp(buffer,    "aaaa",      4) => 0; |     assert(memcmp(buffer,    "aaaa",      4) == 0); | ||||||
|     memcmp(buffer+4,  "fffffffff", 9) => 0; |     assert(memcmp(buffer+4,  "fffffffff", 9) == 0); | ||||||
|     memcmp(buffer+13, "ccccc",     5) => 0; |     assert(memcmp(buffer+13, "ccccc",     5) == 0); | ||||||
|  |  | ||||||
|     lfs_file_open(&lfs, &file, "hello/hello", LFS_O_RDONLY) => 0; |     lfs_file_open(&lfs, &file, "hello/hello", LFS_O_RDONLY) => 0; | ||||||
|     lfs_file_read(&lfs, &file, buffer, sizeof(buffer)) => strlen("hello"); |     lfs_file_read(&lfs, &file, buffer, sizeof(buffer)) => strlen("hello"); | ||||||
|     memcmp(buffer, "hello", strlen("hello")) => 0; |     assert(memcmp(buffer, "hello", strlen("hello")) == 0); | ||||||
|     lfs_file_close(&lfs, &file); |     lfs_file_close(&lfs, &file); | ||||||
|     lfs_unmount(&lfs) => 0; |     lfs_unmount(&lfs) => 0; | ||||||
| ''' | ''' | ||||||
| @@ -94,41 +94,41 @@ code = ''' | |||||||
|     lfs_getattr(&lfs, "/", 'A', buffer,    4) => 4; |     lfs_getattr(&lfs, "/", 'A', buffer,    4) => 4; | ||||||
|     lfs_getattr(&lfs, "/", 'B', buffer+4,  6) => 6; |     lfs_getattr(&lfs, "/", 'B', buffer+4,  6) => 6; | ||||||
|     lfs_getattr(&lfs, "/", 'C', buffer+10, 5) => 5; |     lfs_getattr(&lfs, "/", 'C', buffer+10, 5) => 5; | ||||||
|     memcmp(buffer,    "aaaa",   4) => 0; |     assert(memcmp(buffer,    "aaaa",   4) == 0); | ||||||
|     memcmp(buffer+4,  "bbbbbb", 6) => 0; |     assert(memcmp(buffer+4,  "bbbbbb", 6) == 0); | ||||||
|     memcmp(buffer+10, "ccccc",  5) => 0; |     assert(memcmp(buffer+10, "ccccc",  5) == 0); | ||||||
|  |  | ||||||
|     lfs_setattr(&lfs, "/", 'B', "", 0) => 0; |     lfs_setattr(&lfs, "/", 'B', "", 0) => 0; | ||||||
|     lfs_getattr(&lfs, "/", 'A', buffer,    4) => 4; |     lfs_getattr(&lfs, "/", 'A', buffer,    4) => 4; | ||||||
|     lfs_getattr(&lfs, "/", 'B', buffer+4,  6) => 0; |     lfs_getattr(&lfs, "/", 'B', buffer+4,  6) => 0; | ||||||
|     lfs_getattr(&lfs, "/", 'C', buffer+10, 5) => 5; |     lfs_getattr(&lfs, "/", 'C', buffer+10, 5) => 5; | ||||||
|     memcmp(buffer,    "aaaa",         4) => 0; |     assert(memcmp(buffer,    "aaaa",         4) == 0); | ||||||
|     memcmp(buffer+4,  "\0\0\0\0\0\0", 6) => 0; |     assert(memcmp(buffer+4,  "\0\0\0\0\0\0", 6) == 0); | ||||||
|     memcmp(buffer+10, "ccccc",        5) => 0; |     assert(memcmp(buffer+10, "ccccc",        5) == 0); | ||||||
|  |  | ||||||
|     lfs_removeattr(&lfs, "/", 'B') => 0; |     lfs_removeattr(&lfs, "/", 'B') => 0; | ||||||
|     lfs_getattr(&lfs, "/", 'A', buffer,    4) => 4; |     lfs_getattr(&lfs, "/", 'A', buffer,    4) => 4; | ||||||
|     lfs_getattr(&lfs, "/", 'B', buffer+4,  6) => LFS_ERR_NOATTR; |     lfs_getattr(&lfs, "/", 'B', buffer+4,  6) => LFS_ERR_NOATTR; | ||||||
|     lfs_getattr(&lfs, "/", 'C', buffer+10, 5) => 5; |     lfs_getattr(&lfs, "/", 'C', buffer+10, 5) => 5; | ||||||
|     memcmp(buffer,    "aaaa",         4) => 0; |     assert(memcmp(buffer,    "aaaa",         4) == 0); | ||||||
|     memcmp(buffer+4,  "\0\0\0\0\0\0", 6) => 0; |     assert(memcmp(buffer+4,  "\0\0\0\0\0\0", 6) == 0); | ||||||
|     memcmp(buffer+10, "ccccc",        5) => 0; |     assert(memcmp(buffer+10, "ccccc",        5) == 0); | ||||||
|  |  | ||||||
|     lfs_setattr(&lfs, "/", 'B', "dddddd", 6) => 0; |     lfs_setattr(&lfs, "/", 'B', "dddddd", 6) => 0; | ||||||
|     lfs_getattr(&lfs, "/", 'A', buffer,    4) => 4; |     lfs_getattr(&lfs, "/", 'A', buffer,    4) => 4; | ||||||
|     lfs_getattr(&lfs, "/", 'B', buffer+4,  6) => 6; |     lfs_getattr(&lfs, "/", 'B', buffer+4,  6) => 6; | ||||||
|     lfs_getattr(&lfs, "/", 'C', buffer+10, 5) => 5; |     lfs_getattr(&lfs, "/", 'C', buffer+10, 5) => 5; | ||||||
|     memcmp(buffer,    "aaaa",   4) => 0; |     assert(memcmp(buffer,    "aaaa",   4) == 0); | ||||||
|     memcmp(buffer+4,  "dddddd", 6) => 0; |     assert(memcmp(buffer+4,  "dddddd", 6) == 0); | ||||||
|     memcmp(buffer+10, "ccccc",  5) => 0; |     assert(memcmp(buffer+10, "ccccc",  5) == 0); | ||||||
|  |  | ||||||
|     lfs_setattr(&lfs, "/", 'B', "eee", 3) => 0; |     lfs_setattr(&lfs, "/", 'B', "eee", 3) => 0; | ||||||
|     lfs_getattr(&lfs, "/", 'A', buffer,    4) => 4; |     lfs_getattr(&lfs, "/", 'A', buffer,    4) => 4; | ||||||
|     lfs_getattr(&lfs, "/", 'B', buffer+4,  6) => 3; |     lfs_getattr(&lfs, "/", 'B', buffer+4,  6) => 3; | ||||||
|     lfs_getattr(&lfs, "/", 'C', buffer+10, 5) => 5; |     lfs_getattr(&lfs, "/", 'C', buffer+10, 5) => 5; | ||||||
|     memcmp(buffer,    "aaaa",      4) => 0; |     assert(memcmp(buffer,    "aaaa",      4) == 0); | ||||||
|     memcmp(buffer+4,  "eee\0\0\0", 6) => 0; |     assert(memcmp(buffer+4,  "eee\0\0\0", 6) == 0); | ||||||
|     memcmp(buffer+10, "ccccc",     5) => 0; |     assert(memcmp(buffer+10, "ccccc",     5) == 0); | ||||||
|  |  | ||||||
|     lfs_setattr(&lfs, "/", 'A', buffer, LFS_ATTR_MAX+1) => LFS_ERR_NOSPC; |     lfs_setattr(&lfs, "/", 'A', buffer, LFS_ATTR_MAX+1) => LFS_ERR_NOSPC; | ||||||
|     lfs_setattr(&lfs, "/", 'B', "fffffffff", 9) => 0; |     lfs_setattr(&lfs, "/", 'B', "fffffffff", 9) => 0; | ||||||
| @@ -142,13 +142,13 @@ code = ''' | |||||||
|     lfs_getattr(&lfs, "/", 'A', buffer,    4) => 4; |     lfs_getattr(&lfs, "/", 'A', buffer,    4) => 4; | ||||||
|     lfs_getattr(&lfs, "/", 'B', buffer+4,  9) => 9; |     lfs_getattr(&lfs, "/", 'B', buffer+4,  9) => 9; | ||||||
|     lfs_getattr(&lfs, "/", 'C', buffer+13, 5) => 5; |     lfs_getattr(&lfs, "/", 'C', buffer+13, 5) => 5; | ||||||
|     memcmp(buffer,    "aaaa",      4) => 0; |     assert(memcmp(buffer,    "aaaa",      4) == 0); | ||||||
|     memcmp(buffer+4,  "fffffffff", 9) => 0; |     assert(memcmp(buffer+4,  "fffffffff", 9) == 0); | ||||||
|     memcmp(buffer+13, "ccccc",     5) => 0; |     assert(memcmp(buffer+13, "ccccc",     5) == 0); | ||||||
|  |  | ||||||
|     lfs_file_open(&lfs, &file, "hello/hello", LFS_O_RDONLY) => 0; |     lfs_file_open(&lfs, &file, "hello/hello", LFS_O_RDONLY) => 0; | ||||||
|     lfs_file_read(&lfs, &file, buffer, sizeof(buffer)) => strlen("hello"); |     lfs_file_read(&lfs, &file, buffer, sizeof(buffer)) => strlen("hello"); | ||||||
|     memcmp(buffer, "hello", strlen("hello")) => 0; |     assert(memcmp(buffer, "hello", strlen("hello")) == 0); | ||||||
|     lfs_file_close(&lfs, &file); |     lfs_file_close(&lfs, &file); | ||||||
|     lfs_unmount(&lfs) => 0; |     lfs_unmount(&lfs) => 0; | ||||||
| ''' | ''' | ||||||
| @@ -176,48 +176,52 @@ code = ''' | |||||||
|     memcpy(buffer,    "aaaa",   4); |     memcpy(buffer,    "aaaa",   4); | ||||||
|     memcpy(buffer+4,  "bbbbbb", 6); |     memcpy(buffer+4,  "bbbbbb", 6); | ||||||
|     memcpy(buffer+10, "ccccc",  5); |     memcpy(buffer+10, "ccccc",  5); | ||||||
|  |     lfs_file_write(&lfs, &file, "hi", 2) => 2; | ||||||
|     lfs_file_close(&lfs, &file) => 0; |     lfs_file_close(&lfs, &file) => 0; | ||||||
|     memset(buffer, 0, 15); |     memset(buffer, 0, 15); | ||||||
|     lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_RDONLY, &cfg1) => 0; |     lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_RDONLY, &cfg1) => 0; | ||||||
|     lfs_file_close(&lfs, &file) => 0; |     lfs_file_close(&lfs, &file) => 0; | ||||||
|     memcmp(buffer,    "aaaa",   4) => 0; |     assert(memcmp(buffer,    "aaaa",   4) == 0); | ||||||
|     memcmp(buffer+4,  "bbbbbb", 6) => 0; |     assert(memcmp(buffer+4,  "bbbbbb", 6) == 0); | ||||||
|     memcmp(buffer+10, "ccccc",  5) => 0; |     assert(memcmp(buffer+10, "ccccc",  5) == 0); | ||||||
|  |  | ||||||
|     attrs1[1].size = 0; |     attrs1[1].size = 0; | ||||||
|     lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_WRONLY, &cfg1) => 0; |     lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_WRONLY, &cfg1) => 0; | ||||||
|  |     lfs_file_write(&lfs, &file, "hi", 2) => 2; | ||||||
|     lfs_file_close(&lfs, &file) => 0; |     lfs_file_close(&lfs, &file) => 0; | ||||||
|     memset(buffer, 0, 15); |     memset(buffer, 0, 15); | ||||||
|     attrs1[1].size = 6; |     attrs1[1].size = 6; | ||||||
|     lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_RDONLY, &cfg1) => 0; |     lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_RDONLY, &cfg1) => 0; | ||||||
|     lfs_file_close(&lfs, &file) => 0; |     lfs_file_close(&lfs, &file) => 0; | ||||||
|     memcmp(buffer,    "aaaa",         4) => 0; |     assert(memcmp(buffer,    "aaaa",         4) == 0); | ||||||
|     memcmp(buffer+4,  "\0\0\0\0\0\0", 6) => 0; |     assert(memcmp(buffer+4,  "\0\0\0\0\0\0", 6) == 0); | ||||||
|     memcmp(buffer+10, "ccccc",        5) => 0; |     assert(memcmp(buffer+10, "ccccc",        5) == 0); | ||||||
|  |  | ||||||
|     attrs1[1].size = 6; |     attrs1[1].size = 6; | ||||||
|     lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_WRONLY, &cfg1) => 0; |     lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_WRONLY, &cfg1) => 0; | ||||||
|     memcpy(buffer+4,  "dddddd", 6); |     memcpy(buffer+4,  "dddddd", 6); | ||||||
|  |     lfs_file_write(&lfs, &file, "hi", 2) => 2; | ||||||
|     lfs_file_close(&lfs, &file) => 0; |     lfs_file_close(&lfs, &file) => 0; | ||||||
|     memset(buffer, 0, 15); |     memset(buffer, 0, 15); | ||||||
|     attrs1[1].size = 6; |     attrs1[1].size = 6; | ||||||
|     lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_RDONLY, &cfg1) => 0; |     lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_RDONLY, &cfg1) => 0; | ||||||
|     lfs_file_close(&lfs, &file) => 0; |     lfs_file_close(&lfs, &file) => 0; | ||||||
|     memcmp(buffer,    "aaaa",   4) => 0; |     assert(memcmp(buffer,    "aaaa",   4) == 0); | ||||||
|     memcmp(buffer+4,  "dddddd", 6) => 0; |     assert(memcmp(buffer+4,  "dddddd", 6) == 0); | ||||||
|     memcmp(buffer+10, "ccccc",  5) => 0; |     assert(memcmp(buffer+10, "ccccc",  5) == 0); | ||||||
|  |  | ||||||
|     attrs1[1].size = 3; |     attrs1[1].size = 3; | ||||||
|     lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_WRONLY, &cfg1) => 0; |     lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_WRONLY, &cfg1) => 0; | ||||||
|     memcpy(buffer+4,  "eee", 3); |     memcpy(buffer+4,  "eee", 3); | ||||||
|  |     lfs_file_write(&lfs, &file, "hi", 2) => 2; | ||||||
|     lfs_file_close(&lfs, &file) => 0; |     lfs_file_close(&lfs, &file) => 0; | ||||||
|     memset(buffer, 0, 15); |     memset(buffer, 0, 15); | ||||||
|     attrs1[1].size = 6; |     attrs1[1].size = 6; | ||||||
|     lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_RDONLY, &cfg1) => 0; |     lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_RDONLY, &cfg1) => 0; | ||||||
|     lfs_file_close(&lfs, &file) => 0; |     lfs_file_close(&lfs, &file) => 0; | ||||||
|     memcmp(buffer,    "aaaa",      4) => 0; |     assert(memcmp(buffer,    "aaaa",      4) == 0); | ||||||
|     memcmp(buffer+4,  "eee\0\0\0", 6) => 0; |     assert(memcmp(buffer+4,  "eee\0\0\0", 6) == 0); | ||||||
|     memcmp(buffer+10, "ccccc",     5) => 0; |     assert(memcmp(buffer+10, "ccccc",     5) == 0); | ||||||
|  |  | ||||||
|     attrs1[0].size = LFS_ATTR_MAX+1; |     attrs1[0].size = LFS_ATTR_MAX+1; | ||||||
|     lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_WRONLY, &cfg1) |     lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_WRONLY, &cfg1) | ||||||
| @@ -231,6 +235,7 @@ code = ''' | |||||||
|     struct lfs_file_config cfg2 = {.attrs=attrs2, .attr_count=3}; |     struct lfs_file_config cfg2 = {.attrs=attrs2, .attr_count=3}; | ||||||
|     lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_RDWR, &cfg2) => 0; |     lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_RDWR, &cfg2) => 0; | ||||||
|     memcpy(buffer+4,  "fffffffff", 9); |     memcpy(buffer+4,  "fffffffff", 9); | ||||||
|  |     lfs_file_write(&lfs, &file, "hi", 2) => 2; | ||||||
|     lfs_file_close(&lfs, &file) => 0; |     lfs_file_close(&lfs, &file) => 0; | ||||||
|     attrs1[0].size = 4; |     attrs1[0].size = 4; | ||||||
|     lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_RDONLY, &cfg1) => 0; |     lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_RDONLY, &cfg1) => 0; | ||||||
| @@ -249,13 +254,13 @@ code = ''' | |||||||
|  |  | ||||||
|     lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_RDONLY, &cfg3) => 0; |     lfs_file_opencfg(&lfs, &file, "hello/hello", LFS_O_RDONLY, &cfg3) => 0; | ||||||
|     lfs_file_close(&lfs, &file) => 0; |     lfs_file_close(&lfs, &file) => 0; | ||||||
|     memcmp(buffer,    "aaaa",      4) => 0; |     assert(memcmp(buffer,    "aaaa",      4) == 0); | ||||||
|     memcmp(buffer+4,  "fffffffff", 9) => 0; |     assert(memcmp(buffer+4,  "fffffffff", 9) == 0); | ||||||
|     memcmp(buffer+13, "ccccc",     5) => 0; |     assert(memcmp(buffer+13, "ccccc",     5) == 0); | ||||||
|  |  | ||||||
|     lfs_file_open(&lfs, &file, "hello/hello", LFS_O_RDONLY) => 0; |     lfs_file_open(&lfs, &file, "hello/hello", LFS_O_RDONLY) => 0; | ||||||
|     lfs_file_read(&lfs, &file, buffer, sizeof(buffer)) => strlen("hello"); |     lfs_file_read(&lfs, &file, buffer, sizeof(buffer)) => strlen("hello"); | ||||||
|     memcmp(buffer, "hello", strlen("hello")) => 0; |     assert(memcmp(buffer, "hillo", strlen("hello")) == 0); | ||||||
|     lfs_file_close(&lfs, &file); |     lfs_file_close(&lfs, &file); | ||||||
|     lfs_unmount(&lfs) => 0; |     lfs_unmount(&lfs) => 0; | ||||||
| ''' | ''' | ||||||
| @@ -287,17 +292,18 @@ code = ''' | |||||||
|     lfs_getattr(&lfs, "hello/hello", 'B', buffer,    9) => 9; |     lfs_getattr(&lfs, "hello/hello", 'B', buffer,    9) => 9; | ||||||
|     lfs_getattr(&lfs, "hello/hello", 'C', buffer+9,  9) => 5; |     lfs_getattr(&lfs, "hello/hello", 'C', buffer+9,  9) => 5; | ||||||
|     lfs_getattr(&lfs, "hello/hello", 'D', buffer+18, 9) => LFS_ERR_NOATTR; |     lfs_getattr(&lfs, "hello/hello", 'D', buffer+18, 9) => LFS_ERR_NOATTR; | ||||||
|     memcmp(buffer,    "fffffffff",          9) => 0; |     assert(memcmp(buffer,    "fffffffff",          9) == 0); | ||||||
|     memcmp(buffer+9,  "ccccc\0\0\0\0",      9) => 0; |     assert(memcmp(buffer+9,  "ccccc\0\0\0\0",      9) == 0); | ||||||
|     memcmp(buffer+18, "\0\0\0\0\0\0\0\0\0", 9) => 0; |     assert(memcmp(buffer+18, "\0\0\0\0\0\0\0\0\0", 9) == 0); | ||||||
|  |  | ||||||
|  |     lfs_file_write(&lfs, &file, "hi", 2) => 2; | ||||||
|     lfs_file_sync(&lfs, &file) => 0; |     lfs_file_sync(&lfs, &file) => 0; | ||||||
|     lfs_getattr(&lfs, "hello/hello", 'B', buffer,    9) => 4; |     lfs_getattr(&lfs, "hello/hello", 'B', buffer,    9) => 4; | ||||||
|     lfs_getattr(&lfs, "hello/hello", 'C', buffer+9,  9) => 0; |     lfs_getattr(&lfs, "hello/hello", 'C', buffer+9,  9) => 0; | ||||||
|     lfs_getattr(&lfs, "hello/hello", 'D', buffer+18, 9) => 4; |     lfs_getattr(&lfs, "hello/hello", 'D', buffer+18, 9) => 4; | ||||||
|     memcmp(buffer,    "gggg\0\0\0\0\0",     9) => 0; |     assert(memcmp(buffer,    "gggg\0\0\0\0\0",     9) == 0); | ||||||
|     memcmp(buffer+9,  "\0\0\0\0\0\0\0\0\0", 9) => 0; |     assert(memcmp(buffer+9,  "\0\0\0\0\0\0\0\0\0", 9) == 0); | ||||||
|     memcmp(buffer+18, "hhhh\0\0\0\0\0",     9) => 0; |     assert(memcmp(buffer+18, "hhhh\0\0\0\0\0",     9) == 0); | ||||||
|  |  | ||||||
|     lfs_file_close(&lfs, &file) => 0; |     lfs_file_close(&lfs, &file) => 0; | ||||||
|     lfs_unmount(&lfs) => 0; |     lfs_unmount(&lfs) => 0; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user