Added useful handling of LFS_M_RDONLY
It was a bit tricky to figure out what this should look like.
Traditionally, filesystems tend to fallback to readonly if they detect
unsupported wcompat (ro_compat) flags or similar config mismatch.
We could do something similar in littlefs, but since we default to
asserting on writes to readonly objects for smaller code size, this
would be really weird and hard to use from a users perspective...
Instead, lfsr_mount returns LFS_ERR_NOTSUP on encountering wcompat-
mismatch in RDWR mode, but _not_ RDONLY mode. This allows the common
rdonly-fallback pattern to be implemented on the user's side of things,
similar to the common format-fallback pattern:
int err = lfsr_mount(&lfs, LFS_M_RDWR, &cfg);
if (err && err != LFS_ERR_NOTSUP) {
return err;
}
if (err == LFS_ERR_NOTSUP) {
err = lfsr_mount(&lfs, LFS_M_RDONLY, &cfg);
if (err) {
return err;
}
}
Note that lfsr_mount may still return LFS_ERR_NOTSUP if it encounters
rcompat-flags, even with RDONLY. Detecting this state will likely need
two lfsr_mount calls with the current API, but I don't think that will
be a big deal.
The main benefit of this scheme is that it is quite cheap thanks to
pushing the fallback logic on the user:
code stack
before: 36356 2664
after: 36396 (+0.1%) 2664 (+0.0%)
One missing puzzle piece here is how do you upgrade the filesystem? But I
think the lesson from the on-disk v2.0 -> v2.1 version bump is that this
should really be an explicit function (lfsr_fs_upgrade?). If explicit
and stand-alone, like lfsr_format, we shouldn't need a weird pseudo-
rdonly mode at all.
This commit is contained in:
@@ -9926,11 +9926,12 @@ int lfsr_file_opencfg(lfs_t *lfs, lfsr_file_t *file,
|
|||||||
| LFS_O_FLUSH
|
| LFS_O_FLUSH
|
||||||
| LFS_O_SYNC
|
| LFS_O_SYNC
|
||||||
| LFS_O_DESYNC)) == 0);
|
| LFS_O_DESYNC)) == 0);
|
||||||
|
// writeable files require a writeable filesystem
|
||||||
|
LFS_ASSERT(!lfsr_m_isrdonly(lfs->flags) || lfsr_o_isrdonly(flags));
|
||||||
// these flags require a writable file
|
// these flags require a writable file
|
||||||
LFS_ASSERT(!lfsr_o_isrdonly(flags) || !lfsr_o_iscreat(flags));
|
LFS_ASSERT(!lfsr_o_isrdonly(flags) || !lfsr_o_iscreat(flags));
|
||||||
LFS_ASSERT(!lfsr_o_isrdonly(flags) || !lfsr_o_isexcl(flags));
|
LFS_ASSERT(!lfsr_o_isrdonly(flags) || !lfsr_o_isexcl(flags));
|
||||||
LFS_ASSERT(!lfsr_o_isrdonly(flags) || !lfsr_o_istrunc(flags));
|
LFS_ASSERT(!lfsr_o_isrdonly(flags) || !lfsr_o_istrunc(flags));
|
||||||
LFS_ASSERT(!lfsr_o_isrdonly(flags) || !lfsr_o_isappend(flags));
|
|
||||||
|
|
||||||
if (!lfsr_o_isrdonly(flags)) {
|
if (!lfsr_o_isrdonly(flags)) {
|
||||||
// prepare our filesystem for writing
|
// prepare our filesystem for writing
|
||||||
@@ -11534,6 +11535,8 @@ lfs_soff_t lfsr_file_size(lfs_t *lfs, lfsr_file_t *file) {
|
|||||||
|
|
||||||
int lfsr_file_truncate(lfs_t *lfs, lfsr_file_t *file, lfs_off_t size_) {
|
int lfsr_file_truncate(lfs_t *lfs, lfsr_file_t *file, lfs_off_t size_) {
|
||||||
LFS_ASSERT(lfsr_omdir_isopen(lfs, &file->o.o));
|
LFS_ASSERT(lfsr_omdir_isopen(lfs, &file->o.o));
|
||||||
|
// can't write to readonly files
|
||||||
|
LFS_ASSERT(!lfsr_o_isrdonly(file->o.o.flags));
|
||||||
|
|
||||||
// exceeds our file limit?
|
// exceeds our file limit?
|
||||||
if (size_ > lfs->file_limit) {
|
if (size_ > lfs->file_limit) {
|
||||||
@@ -11640,6 +11643,8 @@ failed:;
|
|||||||
|
|
||||||
int lfsr_file_fruncate(lfs_t *lfs, lfsr_file_t *file, lfs_off_t size_) {
|
int lfsr_file_fruncate(lfs_t *lfs, lfsr_file_t *file, lfs_off_t size_) {
|
||||||
LFS_ASSERT(lfsr_omdir_isopen(lfs, &file->o.o));
|
LFS_ASSERT(lfsr_omdir_isopen(lfs, &file->o.o));
|
||||||
|
// can't write to readonly files
|
||||||
|
LFS_ASSERT(!lfsr_o_isrdonly(file->o.o.flags));
|
||||||
|
|
||||||
// exceeds our file limit?
|
// exceeds our file limit?
|
||||||
if (size_ > lfs->file_limit) {
|
if (size_ > lfs->file_limit) {
|
||||||
@@ -12275,16 +12280,14 @@ static int lfsr_mountmroot(lfs_t *lfs, const lfsr_mdir_t *mroot) {
|
|||||||
lfsr_data_t data;
|
lfsr_data_t data;
|
||||||
int err = lfsr_mdir_lookup(lfs, mroot, LFSR_TAG_VERSION,
|
int err = lfsr_mdir_lookup(lfs, mroot, LFSR_TAG_VERSION,
|
||||||
&data);
|
&data);
|
||||||
if (err) {
|
if (err && err != LFS_ERR_NOENT) {
|
||||||
if (err == LFS_ERR_NOENT) {
|
|
||||||
LFS_ERROR("No littlefs version found");
|
|
||||||
return LFS_ERR_CORRUPT;
|
|
||||||
}
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
lfs_ssize_t d = lfsr_data_read(lfs, &data, version, 2);
|
if (err != LFS_ERR_NOENT) {
|
||||||
if (d < 0) {
|
lfs_ssize_t d = lfsr_data_read(lfs, &data, version, 2);
|
||||||
return err;
|
if (d < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version[0] != LFS_DISK_VERSION_MAJOR
|
if (version[0] != LFS_DISK_VERSION_MAJOR
|
||||||
@@ -12336,13 +12339,15 @@ static int lfsr_mountmroot(lfs_t *lfs, const lfsr_mdir_t *mroot) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO switch to readonly?
|
|
||||||
if (lfsr_wcompat_isincompat(wcompat)) {
|
if (lfsr_wcompat_isincompat(wcompat)) {
|
||||||
LFS_ERROR("Incompatible wcompat flags 0x%0"PRIx16
|
LFS_WARN("Incompatible wcompat flags 0x%0"PRIx16
|
||||||
" (!= 0x%0"PRIx16")",
|
" (!= 0x%0"PRIx16")",
|
||||||
wcompat,
|
wcompat,
|
||||||
LFSR_WCOMPAT_COMPAT);
|
LFSR_WCOMPAT_COMPAT);
|
||||||
return LFS_ERR_NOTSUP;
|
// we can continue if rdonly
|
||||||
|
if (!lfsr_m_isrdonly(lfs->flags)) {
|
||||||
|
return LFS_ERR_NOTSUP;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// we don't bother to check for any ocompatflags, we would just
|
// we don't bother to check for any ocompatflags, we would just
|
||||||
@@ -12542,37 +12547,40 @@ static int lfsr_mountinited(lfs_t *lfs) {
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for any orphaned files
|
// check for any orphaned files, note we only need this if
|
||||||
for (lfs_size_t rid = 0;
|
// filesystem will be writable
|
||||||
rid < mdir->rbyd.weight;
|
if (!lfsr_m_isrdonly(lfs->flags)) {
|
||||||
rid++) {
|
for (lfs_size_t rid = 0;
|
||||||
lfsr_tag_t tag;
|
rid < mdir->rbyd.weight;
|
||||||
err = lfsr_rbyd_sublookup(lfs, &mdir->rbyd, rid, LFSR_TAG_NAME,
|
rid++) {
|
||||||
&tag, NULL);
|
lfsr_tag_t tag;
|
||||||
if (err) {
|
err = lfsr_rbyd_sublookup(lfs, &mdir->rbyd,
|
||||||
LFS_ASSERT(err != LFS_ERR_NOENT);
|
rid, LFSR_TAG_NAME,
|
||||||
return err;
|
&tag, NULL);
|
||||||
}
|
if (err) {
|
||||||
// name 0 should be reserved
|
LFS_ASSERT(err != LFS_ERR_NOENT);
|
||||||
LFS_ASSERT(tag != (LFSR_TAG_NAME + 0));
|
return err;
|
||||||
|
}
|
||||||
|
// name 0 should be reserved
|
||||||
|
LFS_ASSERT(tag != (LFSR_TAG_NAME + 0));
|
||||||
|
|
||||||
// found an orphaned file?
|
// found an orphaned file?
|
||||||
if (tag == LFSR_TAG_ORPHAN) {
|
if (tag == LFSR_TAG_ORPHAN) {
|
||||||
LFS_DEBUG("Found orphan "
|
LFS_DEBUG("Found orphan "
|
||||||
"%"PRId32".%"PRId32,
|
"%"PRId32".%"PRId32,
|
||||||
lfsr_mid_bid(lfs, mdir->mid) >> lfs->mdir_bits,
|
lfsr_mid_bid(lfs, mdir->mid) >> lfs->mdir_bits,
|
||||||
rid);
|
rid);
|
||||||
lfs->flags |= LFS_F_ORPHANS;
|
lfs->flags |= LFS_F_ORPHANS;
|
||||||
|
|
||||||
// found an unknown file type?
|
// found an unknown file type?
|
||||||
} else if (lfsr_tag_isunknown(tag)) {
|
} else if (lfsr_tag_isunknown(tag)) {
|
||||||
// TODO switch to readonly?
|
LFS_WARN("Found unknown file type "
|
||||||
LFS_ERROR("Found unknown file type "
|
"%"PRId32".%"PRId32" 0x%"PRIx16,
|
||||||
"%"PRId32".%"PRId32" 0x%"PRIx16,
|
lfsr_mid_bid(lfs, mdir->mid) >> lfs->mdir_bits,
|
||||||
lfsr_mid_bid(lfs, mdir->mid) >> lfs->mdir_bits,
|
rid,
|
||||||
rid,
|
lfsr_tag_subtype(tag));
|
||||||
lfsr_tag_subtype(tag));
|
return LFS_ERR_NOTSUP;
|
||||||
return LFS_ERR_NOTSUP;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -12628,9 +12636,6 @@ static int lfsr_mountinited(lfs_t *lfs) {
|
|||||||
|
|
||||||
int lfsr_mount(lfs_t *lfs, uint32_t flags,
|
int lfsr_mount(lfs_t *lfs, uint32_t flags,
|
||||||
const struct lfs_config *cfg) {
|
const struct lfs_config *cfg) {
|
||||||
// some flags don't make sense when only traversing the mtree
|
|
||||||
LFS_ASSERT(!lfsr_t_ismtreeonly(flags) || !lfsr_t_islookahead(flags));
|
|
||||||
LFS_ASSERT(!lfsr_t_ismtreeonly(flags) || !lfsr_t_isckdata(flags));
|
|
||||||
// unknown flags?
|
// unknown flags?
|
||||||
LFS_ASSERT((flags & ~(
|
LFS_ASSERT((flags & ~(
|
||||||
LFS_M_RDWR
|
LFS_M_RDWR
|
||||||
@@ -12644,6 +12649,13 @@ int lfsr_mount(lfs_t *lfs, uint32_t flags,
|
|||||||
| LFS_M_COMPACT
|
| LFS_M_COMPACT
|
||||||
| LFS_M_CKMETA
|
| LFS_M_CKMETA
|
||||||
| LFS_M_CKDATA)) == 0);
|
| LFS_M_CKDATA)) == 0);
|
||||||
|
// these flags require a writable filesystem
|
||||||
|
LFS_ASSERT(!lfsr_m_isrdonly(flags) || !lfsr_t_ismkconsistent(flags));
|
||||||
|
LFS_ASSERT(!lfsr_m_isrdonly(flags) || !lfsr_t_islookahead(flags));
|
||||||
|
LFS_ASSERT(!lfsr_m_isrdonly(flags) || !lfsr_t_iscompact(flags));
|
||||||
|
// some flags don't make sense when only traversing the mtree
|
||||||
|
LFS_ASSERT(!lfsr_t_ismtreeonly(flags) || !lfsr_t_islookahead(flags));
|
||||||
|
LFS_ASSERT(!lfsr_t_ismtreeonly(flags) || !lfsr_t_isckdata(flags));
|
||||||
|
|
||||||
int err = lfs_init(lfs, flags, cfg);
|
int err = lfs_init(lfs, flags, cfg);
|
||||||
if (err) {
|
if (err) {
|
||||||
@@ -12671,16 +12683,24 @@ int lfsr_mount(lfs_t *lfs, uint32_t flags,
|
|||||||
1 << lfs->mdir_bits);
|
1 << lfs->mdir_bits);
|
||||||
|
|
||||||
// run gc if requested
|
// run gc if requested
|
||||||
err = lfsr_fs_gc(lfs, -1,
|
if (flags & (
|
||||||
flags & (
|
LFS_M_MTREEONLY
|
||||||
LFS_M_MTREEONLY
|
| LFS_M_MKCONSISTENT
|
||||||
| LFS_M_MKCONSISTENT
|
| LFS_M_LOOKAHEAD
|
||||||
| LFS_M_LOOKAHEAD
|
| LFS_M_COMPACT
|
||||||
| LFS_M_COMPACT
|
| LFS_M_CKMETA
|
||||||
| LFS_M_CKMETA
|
| LFS_M_CKDATA)) {
|
||||||
| LFS_M_CKDATA));
|
err = lfsr_fs_gc(lfs, -1,
|
||||||
if (err) {
|
flags & (
|
||||||
goto failed;
|
LFS_M_MTREEONLY
|
||||||
|
| LFS_M_MKCONSISTENT
|
||||||
|
| LFS_M_LOOKAHEAD
|
||||||
|
| LFS_M_COMPACT
|
||||||
|
| LFS_M_CKMETA
|
||||||
|
| LFS_M_CKDATA));
|
||||||
|
if (err) {
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -12962,6 +12982,9 @@ static int lfsr_fs_fixorphans(lfs_t *lfs) {
|
|||||||
|
|
||||||
// prepare the filesystem for mutation
|
// prepare the filesystem for mutation
|
||||||
int lfsr_fs_mkconsistent(lfs_t *lfs) {
|
int lfsr_fs_mkconsistent(lfs_t *lfs) {
|
||||||
|
// filesystem must be writeable
|
||||||
|
LFS_ASSERT(!lfsr_m_isrdonly(lfs->flags));
|
||||||
|
|
||||||
// fix pending grms
|
// fix pending grms
|
||||||
if (lfsr_grm_count(lfs) > 0) {
|
if (lfsr_grm_count(lfs) > 0) {
|
||||||
if (lfsr_grm_count(lfs) == 2) {
|
if (lfsr_grm_count(lfs) == 2) {
|
||||||
@@ -13035,6 +13058,10 @@ int lfsr_fs_gc(lfs_t *lfs, lfs_soff_t steps, uint32_t flags) {
|
|||||||
| LFS_GC_COMPACT
|
| LFS_GC_COMPACT
|
||||||
| LFS_GC_CKMETA
|
| LFS_GC_CKMETA
|
||||||
| LFS_GC_CKDATA)) == 0);
|
| LFS_GC_CKDATA)) == 0);
|
||||||
|
// these flags require a writable filesystem
|
||||||
|
LFS_ASSERT(!lfsr_m_isrdonly(lfs->flags) || !lfsr_t_ismkconsistent(flags));
|
||||||
|
LFS_ASSERT(!lfsr_m_isrdonly(lfs->flags) || !lfsr_t_islookahead(flags));
|
||||||
|
LFS_ASSERT(!lfsr_m_isrdonly(lfs->flags) || !lfsr_t_iscompact(flags));
|
||||||
// some flags don't make sense when only traversing the mtree
|
// some flags don't make sense when only traversing the mtree
|
||||||
LFS_ASSERT(!lfsr_t_ismtreeonly(flags) || !lfsr_t_islookahead(flags));
|
LFS_ASSERT(!lfsr_t_ismtreeonly(flags) || !lfsr_t_islookahead(flags));
|
||||||
LFS_ASSERT(!lfsr_t_ismtreeonly(flags) || !lfsr_t_isckdata(flags));
|
LFS_ASSERT(!lfsr_t_ismtreeonly(flags) || !lfsr_t_isckdata(flags));
|
||||||
@@ -13150,6 +13177,8 @@ int lfsr_fs_gc(lfs_t *lfs, lfs_soff_t steps, uint32_t flags) {
|
|||||||
|
|
||||||
|
|
||||||
int lfsr_fs_grow(lfs_t *lfs, lfs_size_t block_count_) {
|
int lfsr_fs_grow(lfs_t *lfs, lfs_size_t block_count_) {
|
||||||
|
// filesystem must be writeable
|
||||||
|
LFS_ASSERT(!lfsr_m_isrdonly(lfs->flags));
|
||||||
// shrinking the filesystem is not supported
|
// shrinking the filesystem is not supported
|
||||||
LFS_ASSERT(block_count_ >= lfs->block_count);
|
LFS_ASSERT(block_count_ >= lfs->block_count);
|
||||||
|
|
||||||
@@ -13221,6 +13250,10 @@ int lfsr_traversal_open(lfs_t *lfs, lfsr_traversal_t *t, uint32_t flags) {
|
|||||||
| LFS_T_COMPACT
|
| LFS_T_COMPACT
|
||||||
| LFS_T_CKMETA
|
| LFS_T_CKMETA
|
||||||
| LFS_T_CKDATA)) == 0);
|
| LFS_T_CKDATA)) == 0);
|
||||||
|
// these flags require a writable filesystem
|
||||||
|
LFS_ASSERT(!lfsr_m_isrdonly(lfs->flags) || !lfsr_t_ismkconsistent(flags));
|
||||||
|
LFS_ASSERT(!lfsr_m_isrdonly(lfs->flags) || !lfsr_t_islookahead(flags));
|
||||||
|
LFS_ASSERT(!lfsr_m_isrdonly(lfs->flags) || !lfsr_t_iscompact(flags));
|
||||||
// some flags don't make sense when only traversing the mtree
|
// some flags don't make sense when only traversing the mtree
|
||||||
LFS_ASSERT(!lfsr_t_ismtreeonly(flags) || !lfsr_t_islookahead(flags));
|
LFS_ASSERT(!lfsr_t_ismtreeonly(flags) || !lfsr_t_islookahead(flags));
|
||||||
LFS_ASSERT(!lfsr_t_ismtreeonly(flags) || !lfsr_t_isckdata(flags));
|
LFS_ASSERT(!lfsr_t_ismtreeonly(flags) || !lfsr_t_isckdata(flags));
|
||||||
|
|||||||
@@ -452,6 +452,7 @@ code = '''
|
|||||||
|
|
||||||
// mount should now fail
|
// mount should now fail
|
||||||
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => LFS_ERR_CORRUPT;
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => LFS_ERR_CORRUPT;
|
||||||
|
lfsr_mount(&lfs, LFS_M_RDONLY, CFG) => LFS_ERR_CORRUPT;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# test that we fail if we find bad magic
|
# test that we fail if we find bad magic
|
||||||
@@ -475,6 +476,7 @@ code = '''
|
|||||||
|
|
||||||
// mount should now fail
|
// mount should now fail
|
||||||
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => LFS_ERR_CORRUPT;
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => LFS_ERR_CORRUPT;
|
||||||
|
lfsr_mount(&lfs, LFS_M_RDONLY, CFG) => LFS_ERR_CORRUPT;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# test that we fail to mount after a major version bump
|
# test that we fail to mount after a major version bump
|
||||||
@@ -500,6 +502,7 @@ code = '''
|
|||||||
|
|
||||||
// mount should now fail
|
// mount should now fail
|
||||||
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => LFS_ERR_NOTSUP;
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => LFS_ERR_NOTSUP;
|
||||||
|
lfsr_mount(&lfs, LFS_M_RDONLY, CFG) => LFS_ERR_NOTSUP;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# test that we fail to mount after a minor version bump
|
# test that we fail to mount after a minor version bump
|
||||||
@@ -525,6 +528,7 @@ code = '''
|
|||||||
|
|
||||||
// mount should now fail
|
// mount should now fail
|
||||||
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => LFS_ERR_NOTSUP;
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => LFS_ERR_NOTSUP;
|
||||||
|
lfsr_mount(&lfs, LFS_M_RDONLY, CFG) => LFS_ERR_NOTSUP;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# test that we fail to mount incompatible rcompat flags
|
# test that we fail to mount incompatible rcompat flags
|
||||||
@@ -551,6 +555,7 @@ code = '''
|
|||||||
|
|
||||||
// mount should now fail
|
// mount should now fail
|
||||||
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => LFS_ERR_NOTSUP;
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => LFS_ERR_NOTSUP;
|
||||||
|
lfsr_mount(&lfs, LFS_M_RDONLY, CFG) => LFS_ERR_NOTSUP;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# test that we fail to mount incompatible wcompat flags
|
# test that we fail to mount incompatible wcompat flags
|
||||||
@@ -577,6 +582,10 @@ code = '''
|
|||||||
|
|
||||||
// mount should now fail
|
// mount should now fail
|
||||||
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => LFS_ERR_NOTSUP;
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => LFS_ERR_NOTSUP;
|
||||||
|
|
||||||
|
// but we _can_ mount readonly
|
||||||
|
lfsr_mount(&lfs, LFS_M_RDONLY, CFG) => 0;
|
||||||
|
lfsr_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# test that an incompatible ocompat flag is a noop
|
# test that an incompatible ocompat flag is a noop
|
||||||
@@ -604,6 +613,8 @@ code = '''
|
|||||||
// mount should _not_ fail, ocompat should always be ignored
|
// mount should _not_ fail, ocompat should always be ignored
|
||||||
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
||||||
lfsr_unmount(&lfs) => 0;
|
lfsr_unmount(&lfs) => 0;
|
||||||
|
lfsr_mount(&lfs, LFS_M_RDONLY, CFG) => 0;
|
||||||
|
lfsr_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# these are just a bit harder to detect
|
# these are just a bit harder to detect
|
||||||
@@ -628,6 +639,7 @@ code = '''
|
|||||||
|
|
||||||
// mount should now fail
|
// mount should now fail
|
||||||
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => LFS_ERR_NOTSUP;
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => LFS_ERR_NOTSUP;
|
||||||
|
lfsr_mount(&lfs, LFS_M_RDONLY, CFG) => LFS_ERR_NOTSUP;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[cases.test_mount_incompat_wcompat_overflow]
|
[cases.test_mount_incompat_wcompat_overflow]
|
||||||
@@ -651,6 +663,10 @@ code = '''
|
|||||||
|
|
||||||
// mount should now fail
|
// mount should now fail
|
||||||
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => LFS_ERR_NOTSUP;
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => LFS_ERR_NOTSUP;
|
||||||
|
|
||||||
|
// but we _can_ mount readonly
|
||||||
|
lfsr_mount(&lfs, LFS_M_RDONLY, CFG) => 0;
|
||||||
|
lfsr_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[cases.test_mount_incompat_ocompat_overflow]
|
[cases.test_mount_incompat_ocompat_overflow]
|
||||||
@@ -675,6 +691,8 @@ code = '''
|
|||||||
// mount should _not_ fail, ocompat should always be ignored
|
// mount should _not_ fail, ocompat should always be ignored
|
||||||
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;
|
||||||
lfsr_unmount(&lfs) => 0;
|
lfsr_unmount(&lfs) => 0;
|
||||||
|
lfsr_mount(&lfs, LFS_M_RDONLY, CFG) => 0;
|
||||||
|
lfsr_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# test that we fail to mount incompatible block sizes
|
# test that we fail to mount incompatible block sizes
|
||||||
@@ -701,6 +719,7 @@ code = '''
|
|||||||
|
|
||||||
// mount should now fail
|
// mount should now fail
|
||||||
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => LFS_ERR_NOTSUP;
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => LFS_ERR_NOTSUP;
|
||||||
|
lfsr_mount(&lfs, LFS_M_RDONLY, CFG) => LFS_ERR_NOTSUP;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# test that we fail to mount after incompatible block counts
|
# test that we fail to mount after incompatible block counts
|
||||||
@@ -727,6 +746,7 @@ code = '''
|
|||||||
|
|
||||||
// mount should now fail
|
// mount should now fail
|
||||||
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => LFS_ERR_NOTSUP;
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => LFS_ERR_NOTSUP;
|
||||||
|
lfsr_mount(&lfs, LFS_M_RDONLY, CFG) => LFS_ERR_NOTSUP;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# test that we fail to mount after incompatible name limit
|
# test that we fail to mount after incompatible name limit
|
||||||
@@ -751,6 +771,7 @@ code = '''
|
|||||||
|
|
||||||
// mount should now fail
|
// mount should now fail
|
||||||
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => LFS_ERR_NOTSUP;
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => LFS_ERR_NOTSUP;
|
||||||
|
lfsr_mount(&lfs, LFS_M_RDONLY, CFG) => LFS_ERR_NOTSUP;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# test that we fail to mount after incompatible file limit
|
# test that we fail to mount after incompatible file limit
|
||||||
@@ -779,6 +800,7 @@ code = '''
|
|||||||
|
|
||||||
// mount should now fail
|
// mount should now fail
|
||||||
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => LFS_ERR_NOTSUP;
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => LFS_ERR_NOTSUP;
|
||||||
|
lfsr_mount(&lfs, LFS_M_RDONLY, CFG) => LFS_ERR_NOTSUP;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# test what happens if we find an unknown config
|
# test what happens if we find an unknown config
|
||||||
@@ -799,6 +821,7 @@ code = '''
|
|||||||
|
|
||||||
// mount should now fail
|
// mount should now fail
|
||||||
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => LFS_ERR_NOTSUP;
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => LFS_ERR_NOTSUP;
|
||||||
|
lfsr_mount(&lfs, LFS_M_RDONLY, CFG) => LFS_ERR_NOTSUP;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# test what happens if we find an unknown file type
|
# test what happens if we find an unknown file type
|
||||||
@@ -846,4 +869,8 @@ code = '''
|
|||||||
|
|
||||||
// mount should now fail
|
// mount should now fail
|
||||||
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => LFS_ERR_NOTSUP;
|
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => LFS_ERR_NOTSUP;
|
||||||
|
|
||||||
|
// but we _can_ mount readonly
|
||||||
|
lfsr_mount(&lfs, LFS_M_RDONLY, CFG) => 0;
|
||||||
|
lfsr_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|||||||
Reference in New Issue
Block a user