mirror of
https://github.com/eledio-devices/thirdparty-littlefs.git
synced 2025-11-01 08:48:31 +01:00
Now that littlefs has been rebuilt almost from the ground up with the intention to support custom attributes, adding in custom attribute support is relatively easy. The highest bit in the 9-bit type structure indicates that an attribute is a user-specified custom attribute. The user then has a full 8-bits to specify the attribute type. Other than that, custom attributes are treated the same as system-level attributes. Also made some tweaks to custom attributes: - Adopted the opencfg for file-level attributes provided by dpgeorge - Changed setattrs/getattrs to the simpler setattr/getattr functions users will probably be more familiar with. Note that multiple attributes can still be committed atomically with files, though not with directories. - Changed LFS_ATTRS_MAX -> LFS_ATTR_MAX since there's no longer a global limit on the sum of attribute sizes, which was rather confusing. Though they are still limited by what can fit in a metadata-pair.
263 lines
10 KiB
Bash
Executable File
263 lines
10 KiB
Bash
Executable File
#!/bin/bash
|
|
set -eu
|
|
|
|
echo "=== Attr tests ==="
|
|
rm -rf blocks
|
|
tests/test.py << TEST
|
|
lfs_format(&lfs, &cfg) => 0;
|
|
|
|
lfs_mount(&lfs, &cfg) => 0;
|
|
lfs_mkdir(&lfs, "hello") => 0;
|
|
lfs_file_open(&lfs, &file[0], "hello/hello",
|
|
LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
lfs_file_write(&lfs, &file[0], "hello", strlen("hello"))
|
|
=> strlen("hello");
|
|
lfs_file_close(&lfs, &file[0]);
|
|
lfs_unmount(&lfs) => 0;
|
|
TEST
|
|
|
|
echo "--- Set/get attribute ---"
|
|
tests/test.py << TEST
|
|
lfs_mount(&lfs, &cfg) => 0;
|
|
lfs_setattr(&lfs, "hello", 'A', "aaaa", 4) => 0;
|
|
lfs_setattr(&lfs, "hello", 'B', "bbbbbb", 6) => 0;
|
|
lfs_setattr(&lfs, "hello", 'C', "ccccc", 5) => 0;
|
|
lfs_getattr(&lfs, "hello", 'A', buffer, 4) => 4;
|
|
lfs_getattr(&lfs, "hello", 'B', buffer+4, 6) => 6;
|
|
lfs_getattr(&lfs, "hello", 'C', buffer+10, 5) => 5;
|
|
memcmp(buffer, "aaaa", 4) => 0;
|
|
memcmp(buffer+4, "bbbbbb", 6) => 0;
|
|
memcmp(buffer+10, "ccccc", 5) => 0;
|
|
|
|
lfs_setattr(&lfs, "hello", 'B', "", 0) => 0;
|
|
lfs_getattr(&lfs, "hello", 'A', buffer, 4) => 4;
|
|
lfs_getattr(&lfs, "hello", 'B', buffer+4, 6) => 0;
|
|
lfs_getattr(&lfs, "hello", 'C', buffer+10, 5) => 5;
|
|
memcmp(buffer, "aaaa", 4) => 0;
|
|
memcmp(buffer+4, "\0\0\0\0\0\0", 6) => 0;
|
|
memcmp(buffer+10, "ccccc", 5) => 0;
|
|
|
|
lfs_setattr(&lfs, "hello", 'B', "dddddd", 6) => 0;
|
|
lfs_getattr(&lfs, "hello", 'A', buffer, 4) => 4;
|
|
lfs_getattr(&lfs, "hello", 'B', buffer+4, 6) => 6;
|
|
lfs_getattr(&lfs, "hello", 'C', buffer+10, 5) => 5;
|
|
memcmp(buffer, "aaaa", 4) => 0;
|
|
memcmp(buffer+4, "dddddd", 6) => 0;
|
|
memcmp(buffer+10, "ccccc", 5) => 0;
|
|
|
|
lfs_setattr(&lfs, "hello", 'B', "eee", 3) => 0;
|
|
lfs_getattr(&lfs, "hello", 'A', buffer, 4) => 4;
|
|
lfs_getattr(&lfs, "hello", 'B', buffer+4, 6) => 3;
|
|
lfs_getattr(&lfs, "hello", 'C', buffer+10, 5) => 5;
|
|
memcmp(buffer, "aaaa", 4) => 0;
|
|
memcmp(buffer+4, "eee\0\0\0", 6) => 0;
|
|
memcmp(buffer+10, "ccccc", 5) => 0;
|
|
|
|
lfs_setattr(&lfs, "hello", 'A', buffer, LFS_ATTR_MAX+1) => LFS_ERR_NOSPC;
|
|
lfs_setattr(&lfs, "hello", 'B', "fffffffff", 9) => 0;
|
|
lfs_getattr(&lfs, "hello", 'A', buffer, 4) => 4;
|
|
lfs_getattr(&lfs, "hello", 'B', buffer+4, 6) => 9;
|
|
lfs_getattr(&lfs, "hello", 'C', buffer+10, 5) => 5;
|
|
|
|
lfs_unmount(&lfs) => 0;
|
|
TEST
|
|
tests/test.py << TEST
|
|
lfs_mount(&lfs, &cfg) => 0;
|
|
lfs_getattr(&lfs, "hello", 'A', buffer, 4) => 4;
|
|
lfs_getattr(&lfs, "hello", 'B', buffer+4, 9) => 9;
|
|
lfs_getattr(&lfs, "hello", 'C', buffer+13, 5) => 5;
|
|
memcmp(buffer, "aaaa", 4) => 0;
|
|
memcmp(buffer+4, "fffffffff", 9) => 0;
|
|
memcmp(buffer+13, "ccccc", 5) => 0;
|
|
|
|
lfs_file_open(&lfs, &file[0], "hello/hello", LFS_O_RDONLY) => 0;
|
|
lfs_file_read(&lfs, &file[0], buffer, sizeof(buffer)) => strlen("hello");
|
|
memcmp(buffer, "hello", strlen("hello")) => 0;
|
|
lfs_file_close(&lfs, &file[0]);
|
|
lfs_unmount(&lfs) => 0;
|
|
TEST
|
|
|
|
echo "--- Set/get fs attribute ---"
|
|
tests/test.py << TEST
|
|
lfs_mount(&lfs, &cfg) => 0;
|
|
lfs_fs_setattr(&lfs, 'A', "aaaa", 4) => 0;
|
|
lfs_fs_setattr(&lfs, 'B', "bbbbbb", 6) => 0;
|
|
lfs_fs_setattr(&lfs, 'C', "ccccc", 5) => 0;
|
|
lfs_fs_getattr(&lfs, 'A', buffer, 4) => 4;
|
|
lfs_fs_getattr(&lfs, 'B', buffer+4, 6) => 6;
|
|
lfs_fs_getattr(&lfs, 'C', buffer+10, 5) => 5;
|
|
memcmp(buffer, "aaaa", 4) => 0;
|
|
memcmp(buffer+4, "bbbbbb", 6) => 0;
|
|
memcmp(buffer+10, "ccccc", 5) => 0;
|
|
|
|
lfs_fs_setattr(&lfs, 'B', "", 0) => 0;
|
|
lfs_fs_getattr(&lfs, 'A', buffer, 4) => 4;
|
|
lfs_fs_getattr(&lfs, 'B', buffer+4, 6) => 0;
|
|
lfs_fs_getattr(&lfs, 'C', buffer+10, 5) => 5;
|
|
memcmp(buffer, "aaaa", 4) => 0;
|
|
memcmp(buffer+4, "\0\0\0\0\0\0", 6) => 0;
|
|
memcmp(buffer+10, "ccccc", 5) => 0;
|
|
|
|
lfs_fs_setattr(&lfs, 'B', "dddddd", 6) => 0;
|
|
lfs_fs_getattr(&lfs, 'A', buffer, 4) => 4;
|
|
lfs_fs_getattr(&lfs, 'B', buffer+4, 6) => 6;
|
|
lfs_fs_getattr(&lfs, 'C', buffer+10, 5) => 5;
|
|
memcmp(buffer, "aaaa", 4) => 0;
|
|
memcmp(buffer+4, "dddddd", 6) => 0;
|
|
memcmp(buffer+10, "ccccc", 5) => 0;
|
|
|
|
lfs_fs_setattr(&lfs, 'B', "eee", 3) => 0;
|
|
lfs_fs_getattr(&lfs, 'A', buffer, 4) => 4;
|
|
lfs_fs_getattr(&lfs, 'B', buffer+4, 6) => 3;
|
|
lfs_fs_getattr(&lfs, 'C', buffer+10, 5) => 5;
|
|
memcmp(buffer, "aaaa", 4) => 0;
|
|
memcmp(buffer+4, "eee\0\0\0", 6) => 0;
|
|
memcmp(buffer+10, "ccccc", 5) => 0;
|
|
|
|
lfs_fs_setattr(&lfs, 'A', buffer, LFS_ATTR_MAX+1) => LFS_ERR_NOSPC;
|
|
lfs_fs_setattr(&lfs, 'B', "fffffffff", 9) => 0;
|
|
lfs_fs_getattr(&lfs, 'A', buffer, 4) => 4;
|
|
lfs_fs_getattr(&lfs, 'B', buffer+4, 6) => 9;
|
|
lfs_fs_getattr(&lfs, 'C', buffer+10, 5) => 5;
|
|
lfs_unmount(&lfs) => 0;
|
|
TEST
|
|
tests/test.py << TEST
|
|
lfs_mount(&lfs, &cfg) => 0;
|
|
lfs_fs_getattr(&lfs, 'A', buffer, 4) => 4;
|
|
lfs_fs_getattr(&lfs, 'B', buffer+4, 9) => 9;
|
|
lfs_fs_getattr(&lfs, 'C', buffer+13, 5) => 5;
|
|
memcmp(buffer, "aaaa", 4) => 0;
|
|
memcmp(buffer+4, "fffffffff", 9) => 0;
|
|
memcmp(buffer+13, "ccccc", 5) => 0;
|
|
|
|
lfs_file_open(&lfs, &file[0], "hello/hello", LFS_O_RDONLY) => 0;
|
|
lfs_file_read(&lfs, &file[0], buffer, sizeof(buffer)) => strlen("hello");
|
|
memcmp(buffer, "hello", strlen("hello")) => 0;
|
|
lfs_file_close(&lfs, &file[0]);
|
|
lfs_unmount(&lfs) => 0;
|
|
TEST
|
|
|
|
echo "--- Set/get file attribute ---"
|
|
tests/test.py << TEST
|
|
lfs_mount(&lfs, &cfg) => 0;
|
|
struct lfs_attr a1 = {'A', buffer, 4};
|
|
struct lfs_attr b1 = {'B', buffer+4, 6, &a1};
|
|
struct lfs_attr c1 = {'C', buffer+10, 5, &b1};
|
|
struct lfs_file_config cfg1 = {.attrs = &c1};
|
|
|
|
lfs_file_opencfg(&lfs, &file[0], "hello/hello", LFS_O_WRONLY, &cfg1) => 0;
|
|
memcpy(buffer, "aaaa", 4);
|
|
memcpy(buffer+4, "bbbbbb", 6);
|
|
memcpy(buffer+10, "ccccc", 5);
|
|
lfs_file_close(&lfs, &file[0]) => 0;
|
|
memset(buffer, 0, 15);
|
|
lfs_file_opencfg(&lfs, &file[0], "hello/hello", LFS_O_RDONLY, &cfg1) => 0;
|
|
lfs_file_close(&lfs, &file[0]) => 0;
|
|
memcmp(buffer, "aaaa", 4) => 0;
|
|
memcmp(buffer+4, "bbbbbb", 6) => 0;
|
|
memcmp(buffer+10, "ccccc", 5) => 0;
|
|
|
|
b1.size = 0;
|
|
lfs_file_opencfg(&lfs, &file[0], "hello/hello", LFS_O_WRONLY, &cfg1) => 0;
|
|
lfs_file_close(&lfs, &file[0]) => 0;
|
|
memset(buffer, 0, 15);
|
|
b1.size = 6;
|
|
lfs_file_opencfg(&lfs, &file[0], "hello/hello", LFS_O_RDONLY, &cfg1) => 0;
|
|
lfs_file_close(&lfs, &file[0]) => 0;
|
|
memcmp(buffer, "aaaa", 4) => 0;
|
|
memcmp(buffer+4, "\0\0\0\0\0\0", 6) => 0;
|
|
memcmp(buffer+10, "ccccc", 5) => 0;
|
|
|
|
b1.size = 6;
|
|
lfs_file_opencfg(&lfs, &file[0], "hello/hello", LFS_O_WRONLY, &cfg1) => 0;
|
|
memcpy(buffer+4, "dddddd", 6);
|
|
lfs_file_close(&lfs, &file[0]) => 0;
|
|
memset(buffer, 0, 15);
|
|
b1.size = 6;
|
|
lfs_file_opencfg(&lfs, &file[0], "hello/hello", LFS_O_RDONLY, &cfg1) => 0;
|
|
lfs_file_close(&lfs, &file[0]) => 0;
|
|
memcmp(buffer, "aaaa", 4) => 0;
|
|
memcmp(buffer+4, "dddddd", 6) => 0;
|
|
memcmp(buffer+10, "ccccc", 5) => 0;
|
|
|
|
b1.size = 3;
|
|
lfs_file_opencfg(&lfs, &file[0], "hello/hello", LFS_O_WRONLY, &cfg1) => 0;
|
|
memcpy(buffer+4, "eee", 3);
|
|
lfs_file_close(&lfs, &file[0]) => 0;
|
|
memset(buffer, 0, 15);
|
|
b1.size = 6;
|
|
lfs_file_opencfg(&lfs, &file[0], "hello/hello", LFS_O_RDONLY, &cfg1) => 0;
|
|
lfs_file_close(&lfs, &file[0]) => 0;
|
|
memcmp(buffer, "aaaa", 4) => 0;
|
|
memcmp(buffer+4, "eee\0\0\0", 6) => 0;
|
|
memcmp(buffer+10, "ccccc", 5) => 0;
|
|
|
|
a1.size = LFS_ATTR_MAX+1;
|
|
lfs_file_opencfg(&lfs, &file[0], "hello/hello", LFS_O_WRONLY, &cfg1)
|
|
=> LFS_ERR_NOSPC;
|
|
|
|
struct lfs_attr a2 = {'A', buffer, 4};
|
|
struct lfs_attr b2 = {'B', buffer+4, 9, &a2};
|
|
struct lfs_attr c2 = {'C', buffer+13, 5, &b2};
|
|
struct lfs_file_config cfg2 = {.attrs = &c2};
|
|
lfs_file_opencfg(&lfs, &file[0], "hello/hello", LFS_O_RDWR, &cfg2) => 0;
|
|
memcpy(buffer+4, "fffffffff", 9);
|
|
lfs_file_close(&lfs, &file[0]) => 0;
|
|
a1.size = 4;
|
|
lfs_file_opencfg(&lfs, &file[0], "hello/hello", LFS_O_RDONLY, &cfg1) => 0;
|
|
lfs_file_close(&lfs, &file[0]) => 0;
|
|
|
|
lfs_unmount(&lfs) => 0;
|
|
TEST
|
|
tests/test.py << TEST
|
|
lfs_mount(&lfs, &cfg) => 0;
|
|
struct lfs_attr a2 = {'A', buffer, 4};
|
|
struct lfs_attr b2 = {'B', buffer+4, 9, &a2};
|
|
struct lfs_attr c2 = {'C', buffer+13, 5, &b2};
|
|
struct lfs_file_config cfg2 = {.attrs = &c2};
|
|
|
|
lfs_file_opencfg(&lfs, &file[0], "hello/hello", LFS_O_RDONLY, &cfg2) => 0;
|
|
lfs_file_close(&lfs, &file[0]) => 0;
|
|
memcmp(buffer, "aaaa", 4) => 0;
|
|
memcmp(buffer+4, "fffffffff", 9) => 0;
|
|
memcmp(buffer+13, "ccccc", 5) => 0;
|
|
|
|
lfs_file_open(&lfs, &file[0], "hello/hello", LFS_O_RDONLY) => 0;
|
|
lfs_file_read(&lfs, &file[0], buffer, sizeof(buffer)) => strlen("hello");
|
|
memcmp(buffer, "hello", strlen("hello")) => 0;
|
|
lfs_file_close(&lfs, &file[0]);
|
|
lfs_unmount(&lfs) => 0;
|
|
TEST
|
|
|
|
echo "--- Deferred file attributes ---"
|
|
tests/test.py << TEST
|
|
lfs_mount(&lfs, &cfg) => 0;
|
|
struct lfs_attr a1 = {'B', "gggg", 4};
|
|
struct lfs_attr b1 = {'C', "", 0, &a1};
|
|
struct lfs_attr c1 = {'D', "hhhh", 4, &b1};
|
|
struct lfs_file_config cfg1 = {.attrs = &c1};
|
|
|
|
lfs_file_opencfg(&lfs, &file[0], "hello/hello", LFS_O_WRONLY, &cfg1) => 0;
|
|
|
|
lfs_getattr(&lfs, "hello/hello", 'B', buffer, 9) => 9;
|
|
lfs_getattr(&lfs, "hello/hello", 'C', buffer+9, 9) => 5;
|
|
lfs_getattr(&lfs, "hello/hello", 'D', buffer+18, 9) => LFS_ERR_NOATTR;
|
|
memcmp(buffer, "fffffffff", 9) => 0;
|
|
memcmp(buffer+9, "ccccc\0\0\0\0", 9) => 0;
|
|
memcmp(buffer+18, "\0\0\0\0\0\0\0\0\0", 9) => 0;
|
|
|
|
lfs_file_sync(&lfs, &file[0]) => 0;
|
|
lfs_getattr(&lfs, "hello/hello", 'B', buffer, 9) => 4;
|
|
lfs_getattr(&lfs, "hello/hello", 'C', buffer+9, 9) => 0;
|
|
lfs_getattr(&lfs, "hello/hello", 'D', buffer+18, 9) => 4;
|
|
memcmp(buffer, "gggg\0\0\0\0\0", 9) => 0;
|
|
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;
|
|
|
|
lfs_file_close(&lfs, &file[0]) => 0;
|
|
lfs_unmount(&lfs) => 0;
|
|
TEST
|
|
|
|
echo "--- Results ---"
|
|
tests/stats.py
|