Merge pull request #838 from littlefs-project/fs-stat
Add lfs_fs_stat for access to filesystem status/configuration
This commit is contained in:
@@ -371,7 +371,8 @@ jobs:
|
|||||||
# on one geometry
|
# on one geometry
|
||||||
- name: test-valgrind
|
- name: test-valgrind
|
||||||
run: |
|
run: |
|
||||||
TESTFLAGS="$TESTFLAGS --valgrind -Gdefault -Pnone" make test
|
TESTFLAGS="$TESTFLAGS --valgrind --context=1024 -Gdefault -Pnone" \
|
||||||
|
make test
|
||||||
|
|
||||||
# test that compilation is warning free under clang
|
# test that compilation is warning free under clang
|
||||||
# run with Clang, mostly to check for Clang-specific warnings
|
# run with Clang, mostly to check for Clang-specific warnings
|
||||||
|
|||||||
@@ -415,11 +415,11 @@ static inline uint8_t lfs_gstate_getorphans(const lfs_gstate_t *a) {
|
|||||||
static inline bool lfs_gstate_hasmove(const lfs_gstate_t *a) {
|
static inline bool lfs_gstate_hasmove(const lfs_gstate_t *a) {
|
||||||
return lfs_tag_type1(a->tag);
|
return lfs_tag_type1(a->tag);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline bool lfs_gstate_needssuperblock(const lfs_gstate_t *a) {
|
static inline bool lfs_gstate_needssuperblock(const lfs_gstate_t *a) {
|
||||||
return lfs_tag_size(a->tag) >> 9;
|
return lfs_tag_size(a->tag) >> 9;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline bool lfs_gstate_hasmovehere(const lfs_gstate_t *a,
|
static inline bool lfs_gstate_hasmovehere(const lfs_gstate_t *a,
|
||||||
const lfs_block_t *pair) {
|
const lfs_block_t *pair) {
|
||||||
@@ -535,7 +535,6 @@ static int lfs_file_outline(lfs_t *lfs, lfs_file_t *file);
|
|||||||
static int lfs_file_flush(lfs_t *lfs, lfs_file_t *file);
|
static int lfs_file_flush(lfs_t *lfs, lfs_file_t *file);
|
||||||
|
|
||||||
static int lfs_fs_deorphan(lfs_t *lfs, bool powerloss);
|
static int lfs_fs_deorphan(lfs_t *lfs, bool powerloss);
|
||||||
static void lfs_fs_prepsuperblock(lfs_t *lfs, bool needssuperblock);
|
|
||||||
static int lfs_fs_preporphans(lfs_t *lfs, int8_t orphans);
|
static int lfs_fs_preporphans(lfs_t *lfs, int8_t orphans);
|
||||||
static void lfs_fs_prepmove(lfs_t *lfs,
|
static void lfs_fs_prepmove(lfs_t *lfs,
|
||||||
uint16_t id, const lfs_block_t pair[2]);
|
uint16_t id, const lfs_block_t pair[2]);
|
||||||
@@ -546,6 +545,8 @@ static lfs_stag_t lfs_fs_parent(lfs_t *lfs, const lfs_block_t dir[2],
|
|||||||
static int lfs_fs_forceconsistency(lfs_t *lfs);
|
static int lfs_fs_forceconsistency(lfs_t *lfs);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void lfs_fs_prepsuperblock(lfs_t *lfs, bool needssuperblock);
|
||||||
|
|
||||||
#ifdef LFS_MIGRATE
|
#ifdef LFS_MIGRATE
|
||||||
static int lfs1_traverse(lfs_t *lfs,
|
static int lfs1_traverse(lfs_t *lfs,
|
||||||
int (*cb)(void*, lfs_block_t), void *data);
|
int (*cb)(void*, lfs_block_t), void *data);
|
||||||
@@ -4324,11 +4325,9 @@ static int lfs_rawmount(lfs_t *lfs, const struct lfs_config *cfg) {
|
|||||||
"v%"PRIu16".%"PRIu16" < v%"PRIu16".%"PRIu16,
|
"v%"PRIu16".%"PRIu16" < v%"PRIu16".%"PRIu16,
|
||||||
major_version, minor_version,
|
major_version, minor_version,
|
||||||
LFS_DISK_VERSION_MAJOR, LFS_DISK_VERSION_MINOR);
|
LFS_DISK_VERSION_MAJOR, LFS_DISK_VERSION_MINOR);
|
||||||
#ifndef LFS_READONLY
|
|
||||||
// note this bit is reserved on disk, so fetching more gstate
|
// note this bit is reserved on disk, so fetching more gstate
|
||||||
// will not interfere here
|
// will not interfere here
|
||||||
lfs_fs_prepsuperblock(lfs, true);
|
lfs_fs_prepsuperblock(lfs, true);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check superblock configuration
|
// check superblock configuration
|
||||||
@@ -4421,6 +4420,42 @@ static int lfs_rawunmount(lfs_t *lfs) {
|
|||||||
|
|
||||||
|
|
||||||
/// Filesystem filesystem operations ///
|
/// Filesystem filesystem operations ///
|
||||||
|
static int lfs_fs_rawstat(lfs_t *lfs, struct lfs_fsinfo *fsinfo) {
|
||||||
|
// if the superblock is up-to-date, we must be on the most recent
|
||||||
|
// minor version of littlefs
|
||||||
|
if (!lfs_gstate_needssuperblock(&lfs->gstate)) {
|
||||||
|
fsinfo->disk_version = LFS_DISK_VERSION;
|
||||||
|
|
||||||
|
// otherwise we need to read the minor version on disk
|
||||||
|
} else {
|
||||||
|
// fetch the superblock
|
||||||
|
lfs_mdir_t dir;
|
||||||
|
int err = lfs_dir_fetch(lfs, &dir, lfs->root);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
lfs_superblock_t superblock;
|
||||||
|
lfs_stag_t tag = lfs_dir_get(lfs, &dir, LFS_MKTAG(0x7ff, 0x3ff, 0),
|
||||||
|
LFS_MKTAG(LFS_TYPE_INLINESTRUCT, 0, sizeof(superblock)),
|
||||||
|
&superblock);
|
||||||
|
if (tag < 0) {
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
lfs_superblock_fromle32(&superblock);
|
||||||
|
|
||||||
|
// read the on-disk version
|
||||||
|
fsinfo->disk_version = superblock.version;
|
||||||
|
}
|
||||||
|
|
||||||
|
// other on-disk configuration, we cache all of these for internal use
|
||||||
|
fsinfo->name_max = lfs->name_max;
|
||||||
|
fsinfo->file_max = lfs->file_max;
|
||||||
|
fsinfo->attr_max = lfs->attr_max;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int lfs_fs_rawtraverse(lfs_t *lfs,
|
int lfs_fs_rawtraverse(lfs_t *lfs,
|
||||||
int (*cb)(void *data, lfs_block_t block), void *data,
|
int (*cb)(void *data, lfs_block_t block), void *data,
|
||||||
bool includeorphans) {
|
bool includeorphans) {
|
||||||
@@ -4631,12 +4666,10 @@ static lfs_stag_t lfs_fs_parent(lfs_t *lfs, const lfs_block_t pair[2],
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef LFS_READONLY
|
|
||||||
static void lfs_fs_prepsuperblock(lfs_t *lfs, bool needssuperblock) {
|
static void lfs_fs_prepsuperblock(lfs_t *lfs, bool needssuperblock) {
|
||||||
lfs->gstate.tag = (lfs->gstate.tag & ~LFS_MKTAG(0, 0, 0x200))
|
lfs->gstate.tag = (lfs->gstate.tag & ~LFS_MKTAG(0, 0, 0x200))
|
||||||
| (uint32_t)needssuperblock << 9;
|
| (uint32_t)needssuperblock << 9;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef LFS_READONLY
|
#ifndef LFS_READONLY
|
||||||
static int lfs_fs_preporphans(lfs_t *lfs, int8_t orphans) {
|
static int lfs_fs_preporphans(lfs_t *lfs, int8_t orphans) {
|
||||||
@@ -4934,6 +4967,7 @@ static lfs_ssize_t lfs_fs_rawsize(lfs_t *lfs) {
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef LFS_MIGRATE
|
#ifdef LFS_MIGRATE
|
||||||
////// Migration from littelfs v1 below this //////
|
////// Migration from littelfs v1 below this //////
|
||||||
|
|
||||||
@@ -6053,6 +6087,20 @@ int lfs_dir_rewind(lfs_t *lfs, lfs_dir_t *dir) {
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lfs_fs_stat(lfs_t *lfs, struct lfs_fsinfo *fsinfo) {
|
||||||
|
int err = LFS_LOCK(lfs->cfg);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
LFS_TRACE("lfs_fs_stat(%p, %p)", (void*)lfs, (void*)fsinfo);
|
||||||
|
|
||||||
|
err = lfs_fs_rawstat(lfs, fsinfo);
|
||||||
|
|
||||||
|
LFS_TRACE("lfs_fs_stat -> %d", err);
|
||||||
|
LFS_UNLOCK(lfs->cfg);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
lfs_ssize_t lfs_fs_size(lfs_t *lfs) {
|
lfs_ssize_t lfs_fs_size(lfs_t *lfs) {
|
||||||
int err = LFS_LOCK(lfs->cfg);
|
int err = LFS_LOCK(lfs->cfg);
|
||||||
if (err) {
|
if (err) {
|
||||||
|
|||||||
@@ -280,6 +280,21 @@ struct lfs_info {
|
|||||||
char name[LFS_NAME_MAX+1];
|
char name[LFS_NAME_MAX+1];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Filesystem info structure
|
||||||
|
struct lfs_fsinfo {
|
||||||
|
// On-disk version.
|
||||||
|
uint32_t disk_version;
|
||||||
|
|
||||||
|
// Upper limit on the length of file names in bytes.
|
||||||
|
lfs_size_t name_max;
|
||||||
|
|
||||||
|
// Upper limit on the size of files in bytes.
|
||||||
|
lfs_size_t file_max;
|
||||||
|
|
||||||
|
// Upper limit on the size of custom attributes in bytes.
|
||||||
|
lfs_size_t attr_max;
|
||||||
|
};
|
||||||
|
|
||||||
// Custom attribute structure, used to describe custom attributes
|
// Custom attribute structure, used to describe custom attributes
|
||||||
// committed atomically during file writes.
|
// committed atomically during file writes.
|
||||||
struct lfs_attr {
|
struct lfs_attr {
|
||||||
@@ -659,6 +674,12 @@ int lfs_dir_rewind(lfs_t *lfs, lfs_dir_t *dir);
|
|||||||
|
|
||||||
/// Filesystem-level filesystem operations
|
/// Filesystem-level filesystem operations
|
||||||
|
|
||||||
|
// Find on-disk info about the filesystem
|
||||||
|
//
|
||||||
|
// Fills out the fsinfo structure based on the filesystem found on-disk.
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_fs_stat(lfs_t *lfs, struct lfs_fsinfo *fsinfo);
|
||||||
|
|
||||||
// Finds the current size of the filesystem
|
// Finds the current size of the filesystem
|
||||||
//
|
//
|
||||||
// Note: Result is best effort. If files share COW structures, the returned
|
// Note: Result is best effort. If files share COW structures, the returned
|
||||||
|
|||||||
+83
-35
@@ -22,14 +22,16 @@ code = '''
|
|||||||
#define STRINGIZE_(x) #x
|
#define STRINGIZE_(x) #x
|
||||||
#include STRINGIZE(LFSP)
|
#include STRINGIZE(LFSP)
|
||||||
#else
|
#else
|
||||||
#define LFSP_VERSION LFS_VERSION
|
#define LFSP_DISK_VERSION LFS_DISK_VERSION
|
||||||
#define LFSP_VERSION_MAJOR LFS_VERSION_MAJOR
|
#define LFSP_DISK_VERSION_MAJOR LFS_DISK_VERSION_MAJOR
|
||||||
#define LFSP_VERSION_MINOR LFS_VERSION_MINOR
|
#define LFSP_DISK_VERSION_MINOR LFS_DISK_VERSION_MINOR
|
||||||
#define lfsp_t lfs_t
|
#define lfsp_t lfs_t
|
||||||
#define lfsp_config lfs_config
|
#define lfsp_config lfs_config
|
||||||
#define lfsp_format lfs_format
|
#define lfsp_format lfs_format
|
||||||
#define lfsp_mount lfs_mount
|
#define lfsp_mount lfs_mount
|
||||||
#define lfsp_unmount lfs_unmount
|
#define lfsp_unmount lfs_unmount
|
||||||
|
#define lfsp_fsinfo lfs_fsinfo
|
||||||
|
#define lfsp_fs_stat lfs_fs_stat
|
||||||
#define lfsp_dir_t lfs_dir_t
|
#define lfsp_dir_t lfs_dir_t
|
||||||
#define lfsp_info lfs_info
|
#define lfsp_info lfs_info
|
||||||
#define LFSP_TYPE_REG LFS_TYPE_REG
|
#define LFSP_TYPE_REG LFS_TYPE_REG
|
||||||
@@ -58,7 +60,7 @@ code = '''
|
|||||||
|
|
||||||
# test we can mount in a new version
|
# test we can mount in a new version
|
||||||
[cases.test_compat_forward_mount]
|
[cases.test_compat_forward_mount]
|
||||||
if = 'LFS_VERSION_MAJOR == LFSP_VERSION_MAJOR'
|
if = 'LFS_DISK_VERSION_MAJOR == LFSP_DISK_VERSION_MAJOR'
|
||||||
code = '''
|
code = '''
|
||||||
// create the previous version
|
// create the previous version
|
||||||
struct lfsp_config cfgp;
|
struct lfsp_config cfgp;
|
||||||
@@ -74,13 +76,19 @@ code = '''
|
|||||||
// now test the new mount
|
// now test the new mount
|
||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
|
// we should be able to read the version using lfs_fs_stat
|
||||||
|
struct lfs_fsinfo fsinfo;
|
||||||
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
|
assert(fsinfo.disk_version == LFSP_DISK_VERSION);
|
||||||
|
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# test we can read dirs in a new version
|
# test we can read dirs in a new version
|
||||||
[cases.test_compat_forward_read_dirs]
|
[cases.test_compat_forward_read_dirs]
|
||||||
defines.COUNT = 5
|
defines.COUNT = 5
|
||||||
if = 'LFS_VERSION_MAJOR == LFSP_VERSION_MAJOR'
|
if = 'LFS_DISK_VERSION_MAJOR == LFSP_DISK_VERSION_MAJOR'
|
||||||
code = '''
|
code = '''
|
||||||
// create the previous version
|
// create the previous version
|
||||||
struct lfsp_config cfgp;
|
struct lfsp_config cfgp;
|
||||||
@@ -102,6 +110,11 @@ code = '''
|
|||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
|
// we should be able to read the version using lfs_fs_stat
|
||||||
|
struct lfs_fsinfo fsinfo;
|
||||||
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
|
assert(fsinfo.disk_version == LFSP_DISK_VERSION);
|
||||||
|
|
||||||
// can we list the directories?
|
// can we list the directories?
|
||||||
lfs_dir_t dir;
|
lfs_dir_t dir;
|
||||||
lfs_dir_open(&lfs, &dir, "/") => 0;
|
lfs_dir_open(&lfs, &dir, "/") => 0;
|
||||||
@@ -132,7 +145,7 @@ code = '''
|
|||||||
defines.COUNT = 5
|
defines.COUNT = 5
|
||||||
defines.SIZE = [4, 32, 512, 8192]
|
defines.SIZE = [4, 32, 512, 8192]
|
||||||
defines.CHUNK = 4
|
defines.CHUNK = 4
|
||||||
if = 'LFS_VERSION_MAJOR == LFSP_VERSION_MAJOR'
|
if = 'LFS_DISK_VERSION_MAJOR == LFSP_DISK_VERSION_MAJOR'
|
||||||
code = '''
|
code = '''
|
||||||
// create the previous version
|
// create the previous version
|
||||||
struct lfsp_config cfgp;
|
struct lfsp_config cfgp;
|
||||||
@@ -166,6 +179,11 @@ code = '''
|
|||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
|
// we should be able to read the version using lfs_fs_stat
|
||||||
|
struct lfs_fsinfo fsinfo;
|
||||||
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
|
assert(fsinfo.disk_version == LFSP_DISK_VERSION);
|
||||||
|
|
||||||
// can we list the files?
|
// can we list the files?
|
||||||
lfs_dir_t dir;
|
lfs_dir_t dir;
|
||||||
lfs_dir_open(&lfs, &dir, "/") => 0;
|
lfs_dir_open(&lfs, &dir, "/") => 0;
|
||||||
@@ -214,7 +232,7 @@ code = '''
|
|||||||
defines.COUNT = 5
|
defines.COUNT = 5
|
||||||
defines.SIZE = [4, 32, 512, 8192]
|
defines.SIZE = [4, 32, 512, 8192]
|
||||||
defines.CHUNK = 4
|
defines.CHUNK = 4
|
||||||
if = 'LFS_VERSION_MAJOR == LFSP_VERSION_MAJOR'
|
if = 'LFS_DISK_VERSION_MAJOR == LFSP_DISK_VERSION_MAJOR'
|
||||||
code = '''
|
code = '''
|
||||||
// create the previous version
|
// create the previous version
|
||||||
struct lfsp_config cfgp;
|
struct lfsp_config cfgp;
|
||||||
@@ -251,6 +269,11 @@ code = '''
|
|||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
|
// we should be able to read the version using lfs_fs_stat
|
||||||
|
struct lfs_fsinfo fsinfo;
|
||||||
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
|
assert(fsinfo.disk_version == LFSP_DISK_VERSION);
|
||||||
|
|
||||||
// can we list the directories?
|
// can we list the directories?
|
||||||
lfs_dir_t dir;
|
lfs_dir_t dir;
|
||||||
lfs_dir_open(&lfs, &dir, "/") => 0;
|
lfs_dir_open(&lfs, &dir, "/") => 0;
|
||||||
@@ -321,7 +344,7 @@ code = '''
|
|||||||
# test we can write dirs in a new version
|
# test we can write dirs in a new version
|
||||||
[cases.test_compat_forward_write_dirs]
|
[cases.test_compat_forward_write_dirs]
|
||||||
defines.COUNT = 10
|
defines.COUNT = 10
|
||||||
if = 'LFS_VERSION_MAJOR == LFSP_VERSION_MAJOR'
|
if = 'LFS_DISK_VERSION_MAJOR == LFSP_DISK_VERSION_MAJOR'
|
||||||
code = '''
|
code = '''
|
||||||
// create the previous version
|
// create the previous version
|
||||||
struct lfsp_config cfgp;
|
struct lfsp_config cfgp;
|
||||||
@@ -343,6 +366,11 @@ code = '''
|
|||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
|
// we should be able to read the version using lfs_fs_stat
|
||||||
|
struct lfs_fsinfo fsinfo;
|
||||||
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
|
assert(fsinfo.disk_version == LFSP_DISK_VERSION);
|
||||||
|
|
||||||
// write another COUNT/2 dirs
|
// write another COUNT/2 dirs
|
||||||
for (lfs_size_t i = COUNT/2; i < COUNT; i++) {
|
for (lfs_size_t i = COUNT/2; i < COUNT; i++) {
|
||||||
char name[8];
|
char name[8];
|
||||||
@@ -380,7 +408,7 @@ code = '''
|
|||||||
defines.COUNT = 5
|
defines.COUNT = 5
|
||||||
defines.SIZE = [4, 32, 512, 8192]
|
defines.SIZE = [4, 32, 512, 8192]
|
||||||
defines.CHUNK = 2
|
defines.CHUNK = 2
|
||||||
if = 'LFS_VERSION_MAJOR == LFSP_VERSION_MAJOR'
|
if = 'LFS_DISK_VERSION_MAJOR == LFSP_DISK_VERSION_MAJOR'
|
||||||
code = '''
|
code = '''
|
||||||
// create the previous version
|
// create the previous version
|
||||||
struct lfsp_config cfgp;
|
struct lfsp_config cfgp;
|
||||||
@@ -420,6 +448,11 @@ code = '''
|
|||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
|
// we should be able to read the version using lfs_fs_stat
|
||||||
|
struct lfs_fsinfo fsinfo;
|
||||||
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
|
assert(fsinfo.disk_version == LFSP_DISK_VERSION);
|
||||||
|
|
||||||
// write half COUNT files
|
// write half COUNT files
|
||||||
prng = 42;
|
prng = 42;
|
||||||
for (lfs_size_t i = 0; i < COUNT; i++) {
|
for (lfs_size_t i = 0; i < COUNT; i++) {
|
||||||
@@ -494,7 +527,7 @@ code = '''
|
|||||||
defines.COUNT = 5
|
defines.COUNT = 5
|
||||||
defines.SIZE = [4, 32, 512, 8192]
|
defines.SIZE = [4, 32, 512, 8192]
|
||||||
defines.CHUNK = 2
|
defines.CHUNK = 2
|
||||||
if = 'LFS_VERSION_MAJOR == LFSP_VERSION_MAJOR'
|
if = 'LFS_DISK_VERSION_MAJOR == LFSP_DISK_VERSION_MAJOR'
|
||||||
code = '''
|
code = '''
|
||||||
// create the previous version
|
// create the previous version
|
||||||
struct lfsp_config cfgp;
|
struct lfsp_config cfgp;
|
||||||
@@ -537,6 +570,11 @@ code = '''
|
|||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
lfs_mount(&lfs, cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
|
// we should be able to read the version using lfs_fs_stat
|
||||||
|
struct lfs_fsinfo fsinfo;
|
||||||
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
|
assert(fsinfo.disk_version == LFSP_DISK_VERSION);
|
||||||
|
|
||||||
// write half COUNT files
|
// write half COUNT files
|
||||||
prng = 42;
|
prng = 42;
|
||||||
for (lfs_size_t i = 0; i < COUNT; i++) {
|
for (lfs_size_t i = 0; i < COUNT; i++) {
|
||||||
@@ -636,7 +674,7 @@ code = '''
|
|||||||
|
|
||||||
# test we can mount in an old version
|
# test we can mount in an old version
|
||||||
[cases.test_compat_backward_mount]
|
[cases.test_compat_backward_mount]
|
||||||
if = 'LFS_VERSION == LFSP_VERSION'
|
if = 'LFS_DISK_VERSION == LFSP_DISK_VERSION'
|
||||||
code = '''
|
code = '''
|
||||||
// create the new version
|
// create the new version
|
||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
@@ -651,13 +689,14 @@ code = '''
|
|||||||
memcpy(&cfgp, cfg, sizeof(cfgp));
|
memcpy(&cfgp, cfg, sizeof(cfgp));
|
||||||
lfsp_t lfsp;
|
lfsp_t lfsp;
|
||||||
lfsp_mount(&lfsp, &cfgp) => 0;
|
lfsp_mount(&lfsp, &cfgp) => 0;
|
||||||
|
|
||||||
lfsp_unmount(&lfsp) => 0;
|
lfsp_unmount(&lfsp) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# test we can read dirs in an old version
|
# test we can read dirs in an old version
|
||||||
[cases.test_compat_backward_read_dirs]
|
[cases.test_compat_backward_read_dirs]
|
||||||
defines.COUNT = 5
|
defines.COUNT = 5
|
||||||
if = 'LFS_VERSION == LFSP_VERSION'
|
if = 'LFS_DISK_VERSION == LFSP_DISK_VERSION'
|
||||||
code = '''
|
code = '''
|
||||||
// create the new version
|
// create the new version
|
||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
@@ -709,7 +748,7 @@ code = '''
|
|||||||
defines.COUNT = 5
|
defines.COUNT = 5
|
||||||
defines.SIZE = [4, 32, 512, 8192]
|
defines.SIZE = [4, 32, 512, 8192]
|
||||||
defines.CHUNK = 4
|
defines.CHUNK = 4
|
||||||
if = 'LFS_VERSION == LFSP_VERSION'
|
if = 'LFS_DISK_VERSION == LFSP_DISK_VERSION'
|
||||||
code = '''
|
code = '''
|
||||||
// create the new version
|
// create the new version
|
||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
@@ -791,7 +830,7 @@ code = '''
|
|||||||
defines.COUNT = 5
|
defines.COUNT = 5
|
||||||
defines.SIZE = [4, 32, 512, 8192]
|
defines.SIZE = [4, 32, 512, 8192]
|
||||||
defines.CHUNK = 4
|
defines.CHUNK = 4
|
||||||
if = 'LFS_VERSION == LFSP_VERSION'
|
if = 'LFS_DISK_VERSION == LFSP_DISK_VERSION'
|
||||||
code = '''
|
code = '''
|
||||||
// create the new version
|
// create the new version
|
||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
@@ -898,7 +937,7 @@ code = '''
|
|||||||
# test we can write dirs in an old version
|
# test we can write dirs in an old version
|
||||||
[cases.test_compat_backward_write_dirs]
|
[cases.test_compat_backward_write_dirs]
|
||||||
defines.COUNT = 10
|
defines.COUNT = 10
|
||||||
if = 'LFS_VERSION == LFSP_VERSION'
|
if = 'LFS_DISK_VERSION == LFSP_DISK_VERSION'
|
||||||
code = '''
|
code = '''
|
||||||
// create the new version
|
// create the new version
|
||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
@@ -957,7 +996,7 @@ code = '''
|
|||||||
defines.COUNT = 5
|
defines.COUNT = 5
|
||||||
defines.SIZE = [4, 32, 512, 8192]
|
defines.SIZE = [4, 32, 512, 8192]
|
||||||
defines.CHUNK = 2
|
defines.CHUNK = 2
|
||||||
if = 'LFS_VERSION == LFSP_VERSION'
|
if = 'LFS_DISK_VERSION == LFSP_DISK_VERSION'
|
||||||
code = '''
|
code = '''
|
||||||
// create the previous version
|
// create the previous version
|
||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
@@ -1071,7 +1110,7 @@ code = '''
|
|||||||
defines.COUNT = 5
|
defines.COUNT = 5
|
||||||
defines.SIZE = [4, 32, 512, 8192]
|
defines.SIZE = [4, 32, 512, 8192]
|
||||||
defines.CHUNK = 2
|
defines.CHUNK = 2
|
||||||
if = 'LFS_VERSION == LFSP_VERSION'
|
if = 'LFS_DISK_VERSION == LFSP_DISK_VERSION'
|
||||||
code = '''
|
code = '''
|
||||||
// create the previous version
|
// create the previous version
|
||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
@@ -1316,45 +1355,54 @@ code = '''
|
|||||||
|
|
||||||
// mount should still work
|
// mount should still work
|
||||||
lfs_mount(&lfs, cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
|
struct lfs_fsinfo fsinfo;
|
||||||
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
|
assert(fsinfo.disk_version == LFS_DISK_VERSION-1);
|
||||||
|
|
||||||
lfs_file_open(&lfs, &file, "test", LFS_O_RDONLY) => 0;
|
lfs_file_open(&lfs, &file, "test", LFS_O_RDONLY) => 0;
|
||||||
uint8_t buffer[8];
|
uint8_t buffer[8];
|
||||||
lfs_file_read(&lfs, &file, buffer, 8) => 8;
|
lfs_file_read(&lfs, &file, buffer, 8) => 8;
|
||||||
assert(memcmp(buffer, "testtest", 8) == 0);
|
assert(memcmp(buffer, "testtest", 8) == 0);
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
|
|
||||||
|
// minor version should be unchanged
|
||||||
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
|
assert(fsinfo.disk_version == LFS_DISK_VERSION-1);
|
||||||
|
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
// if we write, we need to bump the minor version
|
// if we write, we need to bump the minor version
|
||||||
lfs_mount(&lfs, cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
|
assert(fsinfo.disk_version == LFS_DISK_VERSION-1);
|
||||||
|
|
||||||
lfs_file_open(&lfs, &file, "test", LFS_O_WRONLY | LFS_O_TRUNC) => 0;
|
lfs_file_open(&lfs, &file, "test", LFS_O_WRONLY | LFS_O_TRUNC) => 0;
|
||||||
lfs_file_write(&lfs, &file, "teeeeest", 8) => 8;
|
lfs_file_write(&lfs, &file, "teeeeest", 8) => 8;
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
|
|
||||||
// minor version should have changed
|
// minor version should be changed
|
||||||
lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
lfs_dir_get(&lfs, &mdir, LFS_MKTAG(0x7ff, 0x3ff, 0),
|
assert(fsinfo.disk_version == LFS_DISK_VERSION);
|
||||||
LFS_MKTAG(LFS_TYPE_INLINESTRUCT, 0, sizeof(superblock)),
|
|
||||||
&superblock)
|
|
||||||
=> LFS_MKTAG(LFS_TYPE_INLINESTRUCT, 0, sizeof(superblock));
|
|
||||||
lfs_superblock_fromle32(&superblock);
|
|
||||||
assert((superblock.version >> 16) & 0xffff == LFS_DISK_VERSION_MAJOR);
|
|
||||||
assert((superblock.version >> 0) & 0xffff == LFS_DISK_VERSION_MINOR);
|
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
// and of course mount should still work
|
// and of course mount should still work
|
||||||
lfs_mount(&lfs, cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
|
// minor version should have changed
|
||||||
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
|
assert(fsinfo.disk_version == LFS_DISK_VERSION);
|
||||||
|
|
||||||
lfs_file_open(&lfs, &file, "test", LFS_O_RDONLY) => 0;
|
lfs_file_open(&lfs, &file, "test", LFS_O_RDONLY) => 0;
|
||||||
lfs_file_read(&lfs, &file, buffer, 8) => 8;
|
lfs_file_read(&lfs, &file, buffer, 8) => 8;
|
||||||
assert(memcmp(buffer, "teeeeest", 8) == 0);
|
assert(memcmp(buffer, "teeeeest", 8) == 0);
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
|
|
||||||
// minor version should have changed
|
// yep, still changed
|
||||||
lfs_dir_fetch(&lfs, &mdir, (lfs_block_t[2]){0, 1}) => 0;
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
lfs_dir_get(&lfs, &mdir, LFS_MKTAG(0x7ff, 0x3ff, 0),
|
assert(fsinfo.disk_version == LFS_DISK_VERSION);
|
||||||
LFS_MKTAG(LFS_TYPE_INLINESTRUCT, 0, sizeof(superblock)),
|
|
||||||
&superblock)
|
|
||||||
=> LFS_MKTAG(LFS_TYPE_INLINESTRUCT, 0, sizeof(superblock));
|
|
||||||
lfs_superblock_fromle32(&superblock);
|
|
||||||
assert((superblock.version >> 16) & 0xffff == LFS_DISK_VERSION_MAJOR);
|
|
||||||
assert((superblock.version >> 0) & 0xffff == LFS_DISK_VERSION_MINOR);
|
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|||||||
@@ -34,6 +34,52 @@ code = '''
|
|||||||
lfs_mount(&lfs, cfg) => LFS_ERR_CORRUPT;
|
lfs_mount(&lfs, cfg) => LFS_ERR_CORRUPT;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
# test we can read superblock info through lfs_fs_stat
|
||||||
|
[cases.test_superblocks_stat]
|
||||||
|
code = '''
|
||||||
|
lfs_t lfs;
|
||||||
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
|
||||||
|
// test we can mount and read fsinfo
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
|
struct lfs_fsinfo fsinfo;
|
||||||
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
|
assert(fsinfo.disk_version == LFS_DISK_VERSION);
|
||||||
|
assert(fsinfo.name_max == LFS_NAME_MAX);
|
||||||
|
assert(fsinfo.file_max == LFS_FILE_MAX);
|
||||||
|
assert(fsinfo.attr_max == LFS_ATTR_MAX);
|
||||||
|
|
||||||
|
lfs_unmount(&lfs) => 0;
|
||||||
|
'''
|
||||||
|
|
||||||
|
[cases.test_superblocks_stat_tweaked]
|
||||||
|
defines.TWEAKED_NAME_MAX = 63
|
||||||
|
defines.TWEAKED_FILE_MAX = '(1 << 16)-1'
|
||||||
|
defines.TWEAKED_ATTR_MAX = 512
|
||||||
|
code = '''
|
||||||
|
// create filesystem with tweaked params
|
||||||
|
struct lfs_config tweaked_cfg = *cfg;
|
||||||
|
tweaked_cfg.name_max = TWEAKED_NAME_MAX;
|
||||||
|
tweaked_cfg.file_max = TWEAKED_FILE_MAX;
|
||||||
|
tweaked_cfg.attr_max = TWEAKED_ATTR_MAX;
|
||||||
|
|
||||||
|
lfs_t lfs;
|
||||||
|
lfs_format(&lfs, &tweaked_cfg) => 0;
|
||||||
|
|
||||||
|
// test we can mount and read these params with the original config
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
|
||||||
|
struct lfs_fsinfo fsinfo;
|
||||||
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
|
assert(fsinfo.disk_version == LFS_DISK_VERSION);
|
||||||
|
assert(fsinfo.name_max == TWEAKED_NAME_MAX);
|
||||||
|
assert(fsinfo.file_max == TWEAKED_FILE_MAX);
|
||||||
|
assert(fsinfo.attr_max == TWEAKED_ATTR_MAX);
|
||||||
|
|
||||||
|
lfs_unmount(&lfs) => 0;
|
||||||
|
'''
|
||||||
|
|
||||||
# expanding superblock
|
# expanding superblock
|
||||||
[cases.test_superblocks_expand]
|
[cases.test_superblocks_expand]
|
||||||
defines.BLOCK_CYCLES = [32, 33, 1]
|
defines.BLOCK_CYCLES = [32, 33, 1]
|
||||||
|
|||||||
Reference in New Issue
Block a user