diff --git a/lfs.c b/lfs.c index ba7c6ae3..a36e8035 100644 --- a/lfs.c +++ b/lfs.c @@ -13393,6 +13393,7 @@ static int lfs_deinit(lfs_t *lfs) { // enum lfsr_rcompat { LFSR_RCOMPAT_NONSTANDARD = 0x0001, // Non-standard filesystem format + LFSR_RCOMPAT_WRONLY = 0x0002, // Reading is disallowed LFSR_RCOMPAT_GRM = 0x0004, // May use a global-remove LFSR_RCOMPAT_MSPROUT = 0x0010, // May use an inlined mdir LFSR_RCOMPAT_MLEAF = 0x0020, // May use a single mdir pointer @@ -13418,6 +13419,7 @@ enum lfsr_rcompat { enum lfsr_wcompat { LFSR_WCOMPAT_NONSTANDARD = 0x0001, // Non-standard filesystem format + LFSR_WCOMPAT_RDONLY = 0x0002, // Writing is disallowed // internal LFSR_wcompat_OVERFLOW = 0x8000, // Can't represent all flags }; diff --git a/scripts/dbgflags.py b/scripts/dbgflags.py index 720df81a..f9a602e7 100755 --- a/scripts/dbgflags.py +++ b/scripts/dbgflags.py @@ -149,6 +149,7 @@ FLAGS = [ # Read-compat flags ('RCOMPAT', 'NONSTANDARD', 0x0001, "Non-standard filesystem format" ), + ('RCOMPAT', 'WRONLY', 0x0002, "Reading is disallowed" ), ('RCOMPAT', 'GRM', 0x0004, "May use a global-remove" ), ('RCOMPAT', 'MSPROUT', 0x0010, "May use an inlined mdir" ), ('RCOMPAT', 'MLEAF', 0x0020, "May use a single mdir pointer" ), @@ -164,6 +165,7 @@ FLAGS = [ # Write-compat flags ('WCOMPAT', 'NONSTANDARD', 0x0001, "Non-standard filesystem format" ), + ('WCOMPAT', 'RDONLY', 0x0002, "Writing is disallowed" ), ('wcompat', 'OVERFLOW',0x8000, "Can't represent all flags" ), diff --git a/tests/test_mount.toml b/tests/test_mount.toml index c7248a42..b31ba8d6 100644 --- a/tests/test_mount.toml +++ b/tests/test_mount.toml @@ -716,6 +716,65 @@ code = ''' lfsr_unmount(&lfs) => 0; ''' +# test that we fail to mount rdonly images +[cases.test_mount_incompat_rdonly] +in = 'lfs.c' +code = ''' + // create a superblock + lfs_t lfs; + lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0; + + // set the rdonly flag, this prevents writing from a littlefs image + // + // note we're messing around with internals to do this! this + // is not a user API + lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0; + uint8_t wcompat_buf[LFSR_WCOMPAT_DSIZE]; + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_RATS( + LFSR_RAT( + LFSR_TAG_WCOMPAT, 0, + LFSR_DATA_WCOMPAT( + LFSR_WCOMPAT_COMPAT + | LFSR_WCOMPAT_RDONLY, + wcompat_buf)))) => 0; + lfsr_unmount(&lfs) => 0; + + // mount should now fail + 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 we fail to mount wronly images +[cases.test_mount_incompat_wronly] +in = 'lfs.c' +code = ''' + // create a superblock + lfs_t lfs; + lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0; + + // set the wronly flag, this prevents reading from a littlefs image + // + // note we're messing around with internals to do this! this + // is not a user API + lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0; + uint8_t rcompat_buf[LFSR_RCOMPAT_DSIZE]; + lfsr_mdir_commit(&lfs, &lfs.mroot, LFSR_RATS( + LFSR_RAT( + LFSR_TAG_RCOMPAT, 0, + LFSR_DATA_RCOMPAT( + LFSR_RCOMPAT_COMPAT + | LFSR_RCOMPAT_WRONLY, + rcompat_buf)))) => 0; + lfsr_unmount(&lfs) => 0; + + // mount should now fail + lfsr_mount(&lfs, LFS_M_RDWR, CFG) => LFS_ERR_NOTSUP; + lfsr_mount(&lfs, LFS_M_RDONLY, CFG) => LFS_ERR_NOTSUP; +''' + # these are just a bit harder to detect [cases.test_mount_incompat_rcompat_overflow] defines.OVERFLOW = 72