M module-vfs/drivers/src/purefs/fs/filesystem_littlefs.cpp => module-vfs/drivers/src/purefs/fs/filesystem_littlefs.cpp +3 -3
@@ 341,7 341,7 @@ namespace purefs::fs::drivers
const auto err = invoke_lfs(zfile->mntpoint(), ::lfs_stat, path.c_str(), &linfo);
if (!err) {
auto vmnt = std::static_pointer_cast<mount_point_littlefs>(vfile->mntpoint());
- translate_lfsinfo_to_stat(linfo, *vmnt->lfs_config(), vmnt->flags() & mount_flags::read_only, st);
+ translate_lfsinfo_to_stat(linfo, *vmnt->lfs_config(), vmnt->is_ro(), st);
}
return err;
}
@@ 352,7 352,7 @@ namespace purefs::fs::drivers
const auto err = invoke_lfs(mnt, file, ::lfs_stat, &linfo);
if (!err) {
auto mntp = std::static_pointer_cast<mount_point_littlefs>(mnt);
- translate_lfsinfo_to_stat(linfo, *mntp->lfs_config(), mntp->flags() & mount_flags::read_only, st);
+ translate_lfsinfo_to_stat(linfo, *mntp->lfs_config(), mntp->is_ro(), st);
}
return err;
}
@@ 421,7 421,7 @@ namespace purefs::fs::drivers
int err = invoke_lfs(dirstate, ::lfs_dir_read, &linfo);
if (err == 1) {
auto mntp = std::static_pointer_cast<mount_point_littlefs>(dirstate->mntpoint());
- translate_lfsinfo_to_stat(linfo, *mntp->lfs_config(), mntp->flags() & mount_flags::read_only, filestat);
+ translate_lfsinfo_to_stat(linfo, *mntp->lfs_config(), mntp->is_ro(), filestat);
filename = linfo.name;
err = 0;
}
M module-vfs/drivers/src/purefs/fs/filesystem_vfat.cpp => module-vfs/drivers/src/purefs/fs/filesystem_vfat.cpp +3 -3
@@ 342,7 342,7 @@ namespace purefs::fs::drivers
if (fres == FR_OK) {
const auto vmnt = vfile->mntpoint();
if (vmnt) {
- translate_filinfo_to_stat(finfo, vfile->ff_filp(), vmnt->flags() & mount_flags::read_only, st);
+ translate_filinfo_to_stat(finfo, vfile->ff_filp(), vmnt->is_ro(), st);
}
else {
return -EIO;
@@ 362,7 362,7 @@ namespace purefs::fs::drivers
const auto fspath = vmnt->native_path(file);
const int fres = f_stat(fspath.c_str(), &finfo);
if (fres == FR_OK) {
- translate_filinfo_to_stat(finfo, nullptr, vmnt->flags() & mount_flags::read_only, st);
+ translate_filinfo_to_stat(finfo, nullptr, vmnt->is_ro(), st);
}
return translate_error(fres);
}
@@ 445,7 445,7 @@ namespace purefs::fs::drivers
else {
const auto vmnt = dirp->mntpoint();
if (vmnt) {
- translate_filinfo_to_stat(ffinfo, nullptr, vmnt->flags() & mount_flags::read_only, filestat);
+ translate_filinfo_to_stat(ffinfo, nullptr, vmnt->is_ro(), filestat);
filename = ffinfo.fname;
}
else {
M module-vfs/include/internal/purefs/fs/file_handle.hpp => module-vfs/include/internal/purefs/fs/file_handle.hpp +1 -0
@@ 13,6 13,7 @@ namespace purefs::fs::internal
{
public:
file_handle(const file_handle &) = delete;
+ auto operator=(const file_handle &) = delete;
virtual ~file_handle() = default;
file_handle(std::shared_ptr<mount_point> mp, unsigned flags) : m_mount_point(mp), m_flags(flags)
{}
M module-vfs/include/internal/purefs/fs/mount_point.hpp => module-vfs/include/internal/purefs/fs/mount_point.hpp +9 -2
@@ 5,6 5,7 @@
#include <memory>
#include <string>
#include <iostream>
+#include <purefs/fs/mount_flags.hpp>
namespace purefs::blkdev::internal
{
@@ 28,6 29,8 @@ namespace purefs::fs::internal
std::shared_ptr<filesystem_operations> fs)
: m_diskh(diskh), m_path(path), m_fs(fs), m_flags(flags)
{}
+ mount_point(const mount_point &) = delete;
+ auto operator=(const mount_point &) = delete;
virtual ~mount_point() = default;
auto disk() const noexcept
{
@@ 41,10 44,14 @@ namespace purefs::fs::internal
{
return m_fs.lock();
}
- auto flags() const noexcept
+ auto flags() const noexcept -> unsigned
{
return m_flags;
}
+ auto is_ro() const noexcept -> bool
+ {
+ return (m_flags & mount_flags::read_only) == mount_flags::read_only;
+ }
void modify_flags(unsigned flags) noexcept
{
m_flags = flags;
@@ 70,6 77,6 @@ namespace purefs::fs::internal
const std::weak_ptr<blkdev::internal::disk_handle> m_diskh;
const std::string m_path; //! Mounted path
const std::weak_ptr<filesystem_operations> m_fs; //! Filesystem operation
- unsigned m_flags;
+ volatile unsigned m_flags;
};
} // namespace purefs::fs::internal
M module-vfs/include/user/purefs/fs/filesystem.hpp => module-vfs/include/user/purefs/fs/filesystem.hpp +2 -2
@@ 202,7 202,7 @@ namespace purefs::fs
if (!mountp) {
return -ENOENT;
}
- if (acc == iaccess::rw && (mountp->flags() & mount_flags::read_only)) {
+ if (acc == iaccess::rw && mountp->is_ro()) {
return -EACCES;
}
auto fsops = mountp->fs_ops();
@@ 225,7 225,7 @@ namespace purefs::fs
if (!mountp) {
return -ENOENT;
}
- if (mountp->flags() & mount_flags::read_only) {
+ if (mountp->is_ro()) {
return -EACCES;
}
if (path.compare(0, pathpos, path2, 0, pathpos) != 0) {
M module-vfs/src/purefs/fs/filesystem.cpp => module-vfs/src/purefs/fs/filesystem.cpp +1 -1
@@ 75,7 75,7 @@ namespace purefs::fs
if (mpi != std::end(m_mounts)) {
if (flags & mount_flags::remount) {
// NOTE: Currently only RO is supported
- mpi->second->modify_flags(flags);
+ mpi->second->modify_flags(flags & ~mount_flags::remount);
return {};
}
else {
M module-vfs/tests/unittest_filesystem_core.cpp => module-vfs/tests/unittest_filesystem_core.cpp +73 -0
@@ 272,6 272,79 @@ TEST_CASE("Corefs: Directory operations")
}
}
+TEST_CASE("Read only filesystem")
+{
+ using namespace purefs;
+ auto dm = std::make_shared<blkdev::disk_manager>();
+ auto disk = std::make_shared<blkdev::disk_image>(disk_image);
+ REQUIRE(disk);
+ REQUIRE(dm->register_device(disk, "emmc0") == 0);
+ purefs::fs::filesystem fscore(dm);
+ const auto vfs_vfat = std::make_shared<fs::drivers::filesystem_vfat>();
+ REQUIRE(vfs_vfat->mount_count() == 0);
+ auto ret = fscore.register_filesystem("vfat", vfs_vfat);
+ REQUIRE(ret == 0);
+ REQUIRE(fscore.mount("emmc0part0", "/sys", "vfat", fs::mount_flags::read_only) == 0);
+ SECTION("Open file in O_RDWR")
+ {
+ int hwnd = fscore.open("/sys/rotest.txt", O_RDWR | O_CREAT, 0660);
+ REQUIRE(hwnd == -EACCES);
+ const std::string text = "test";
+ fscore.write(hwnd, text.c_str(), text.size());
+ }
+ SECTION("Check function which not modify fs")
+ {
+ struct statvfs ssv;
+ ret = fscore.stat_vfs("/sys/", ssv);
+ REQUIRE(ret == 0);
+ }
+ SECTION("Check stat to not set S_IW...")
+ {
+ struct stat st;
+ ret = fscore.stat("/sys/current", st);
+ REQUIRE(ret == 0);
+ REQUIRE(st.st_mode & S_IFDIR);
+ REQUIRE((st.st_mode & (S_IWGRP | S_IWUSR | S_IWOTH)) == 0);
+ }
+ REQUIRE(fscore.umount("/sys") == 0);
+}
+
+TEST_CASE("Remount filesystem from RO to RW and to RO")
+{
+ using namespace purefs;
+ auto dm = std::make_shared<blkdev::disk_manager>();
+ auto disk = std::make_shared<blkdev::disk_image>(disk_image);
+ REQUIRE(disk);
+ REQUIRE(dm->register_device(disk, "emmc0") == 0);
+ auto fscore = std::make_shared<purefs::fs::filesystem>(dm);
+ const auto vfs_vfat = std::make_shared<fs::drivers::filesystem_vfat>();
+ REQUIRE(vfs_vfat->mount_count() == 0);
+ auto ret = fscore->register_filesystem("vfat", vfs_vfat);
+ REQUIRE(ret == 0);
+ REQUIRE(fscore->mount("emmc0part0", "/sys", "vfat", fs::mount_flags::read_only) == 0);
+
+ {
+ const int hwnd = fscore->open("/sys/remount_test.txt", O_RDWR | O_CREAT, 0660);
+ REQUIRE(hwnd == -EACCES);
+ }
+ REQUIRE(fscore->mount("", "/sys", "", fs::mount_flags::remount) == 0);
+ {
+ int hwnd = fscore->open("/sys/remount_test4.txt", O_RDWR | O_CREAT, 0660);
+ REQUIRE(hwnd > 2);
+ const std::string text = "test";
+ fscore->write(hwnd, text.c_str(), text.size());
+ REQUIRE(fscore->close(hwnd) == 0);
+ }
+ {
+ struct stat st;
+ ret = fscore->stat("/sys/current", st);
+ REQUIRE(ret == 0);
+ REQUIRE(st.st_mode & S_IFDIR);
+ REQUIRE(st.st_mode & (S_IWGRP | S_IWUSR | S_IWOTH));
+ }
+ REQUIRE(fscore->umount("/sys") == 0);
+}
+
TEST_CASE("Unititest integrated subsystem")
{
auto [disk, vfs] = purefs::subsystem::initialize();