M module-vfs/include/user/purefs/fs/filesystem.hpp => module-vfs/include/user/purefs/fs/filesystem.hpp +5 -0
@@ 16,6 16,7 @@
#include <purefs/fs/file_handle.hpp>
#include <purefs/fs/directory_handle.hpp>
#include <purefs/fs/mount_point.hpp>
+#include <type_traits>
struct statvfs;
struct stat;
@@ 70,6 71,10 @@ namespace purefs::fs
*/
template <typename T> auto register_filesystem(std::string_view fsname, std::shared_ptr<T> fops) -> int
{
+ if (!fops || !std::is_convertible_v<T *, filesystem_operations *>) {
+ LOG_ERROR("Filesystem not valid");
+ return -EINVAL;
+ }
return register_filesystem(fsname, std::shared_ptr<filesystem_operations>(fops));
}
auto register_filesystem(std::string_view fsname, std::shared_ptr<filesystem_operations> fops) -> int;
M module-vfs/src/purefs/fs/filesystem.cpp => module-vfs/src/purefs/fs/filesystem.cpp +4 -0
@@ 17,6 17,10 @@ namespace purefs::fs
auto filesystem::register_filesystem(std::string_view fsname, std::shared_ptr<filesystem_operations> fops) -> int
{
+ if (fops == nullptr) {
+ LOG_ERROR("Filesystem operations doesn't exists");
+ return -EINVAL;
+ }
cpp_freertos::LockGuard _lck(m_lock);
const auto it = m_fstypes.find(std::string(fsname));
if (it != std::end(m_fstypes)) {
M module-vfs/src/purefs/fs/filesystem_syscalls.cpp => module-vfs/src/purefs/fs/filesystem_syscalls.cpp +8 -1
@@ 55,7 55,6 @@ namespace purefs::fs
return invoke_fops(&filesystem_operations::chmod, path, mode);
}
-
auto filesystem::write(int fd, const char *ptr, size_t len) noexcept -> ssize_t
{
return invoke_fops(&filesystem_operations::write, fd, ptr, len);
@@ 172,11 171,19 @@ namespace purefs::fs
auto filesystem::dirnext(fsdir dirstate, std::string &filename, struct stat &filestat) noexcept -> int
{
+ if (!dirstate) {
+ LOG_ERROR("No directory handle");
+ return -ENXIO;
+ }
return invoke_fops(&filesystem_operations::dirnext, dirstate, filename, filestat);
}
auto filesystem::dirclose(fsdir dirstate) noexcept -> int
{
+ if (!dirstate) {
+ LOG_ERROR("No directory handle");
+ return -ENXIO;
+ }
return invoke_fops(&filesystem_operations::dirclose, dirstate);
}
M module-vfs/tests/unittest_filesystem_core.cpp => module-vfs/tests/unittest_filesystem_core.cpp +164 -1
@@ 9,6 9,8 @@
#include <purefs/fs/drivers/filesystem_vfat.hpp>
#include <sys/statvfs.h>
#include <sys/stat.h>
+#include <fcntl.h>
+#include <tuple>
namespace
{
@@ 105,4 107,165 @@ TEST_CASE("Corefs: Basic API test")
dirhandle = nullptr;
}
}
-}>
\ No newline at end of file
+ REQUIRE(fscore.umount("/sys") == 0);
+}
+
+TEST_CASE("Corefs: Create new file, write, read from it")
+{
+ 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") == 0);
+
+ int hwnd = fscore.open("/sys/test.txt", O_RDWR | O_CREAT, 0660);
+ REQUIRE(hwnd >= 3);
+ const std::string text = "test";
+ fscore.write(hwnd, text.c_str(), text.size());
+
+ REQUIRE(fscore.close(hwnd) == 0);
+ SECTION("Read from file")
+ {
+ int hwnd = fscore.open("/sys/test.txt", O_RDONLY, 0);
+ REQUIRE(hwnd >= 3);
+ char buf[sizeof(text.c_str())] = {0};
+ REQUIRE(fscore.read(hwnd, buf, sizeof(buf)) == 4);
+ REQUIRE(strcmp(buf, text.c_str()) == 0);
+ fscore.close(hwnd);
+ REQUIRE(fscore.umount("/sys") == 0);
+ }
+
+ SECTION("Test seek file")
+ {
+ int hwnd = fscore.open("/sys/test.txt", O_RDONLY, 0);
+ REQUIRE(hwnd >= 3);
+ char buf[4096]{};
+ REQUIRE(fscore.read(hwnd, buf, sizeof(buf)) == 4);
+ REQUIRE(fscore.seek(hwnd, 0, SEEK_END) == 0);
+ REQUIRE(fscore.read(hwnd, buf, sizeof(buf)) == 0);
+ REQUIRE(fscore.seek(hwnd, 0, SEEK_SET) == 0);
+ fscore.close(hwnd);
+ REQUIRE(fscore.umount("/sys") == 0);
+ }
+}
+
+TEST_CASE("Corefs: Register null 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);
+ REQUIRE(fscore.register_filesystem("vfat", nullptr) == -EINVAL);
+}
+
+TEST_CASE("Corefs: Mount empty strings")
+{
+ 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("", "", "") == -EINVAL);
+ REQUIRE(fscore.umount("") == -ENOENT);
+}
+
+TEST_CASE("Corefs: Write to not valid file descriptor")
+{
+ 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") == 0);
+
+ const auto fd = fscore.open("/sys/.boot.json", 0, 0);
+ REQUIRE(fd >= 3);
+ const auto text = "test";
+ REQUIRE(fscore.write(0, text, sizeof(text)) == -EBADF);
+ REQUIRE(fscore.close(fd) == 0);
+ REQUIRE(fscore.umount("/sys") == 0);
+}
+
+TEST_CASE("Corefs: Directory operations")
+{
+ 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") == 0);
+
+ const auto dirhandle = fscore.diropen("/sys/user");
+ REQUIRE(dirhandle);
+ REQUIRE(dirhandle->error() == 0);
+
+ SECTION("Null pointer handle dirnext")
+ {
+ struct stat st;
+ std::string fnm;
+ REQUIRE(fscore.dirnext(nullptr, fnm, st) == -ENXIO);
+ REQUIRE(fscore.dirclose(dirhandle) == 0);
+ REQUIRE(fscore.umount("/sys") == 0);
+ }
+
+ SECTION("Null pointer handle dirclose")
+ {
+ REQUIRE(fscore.dirclose(nullptr) == -ENXIO);
+ REQUIRE(fscore.dirclose(dirhandle) == 0);
+ REQUIRE(fscore.umount("/sys") == 0);
+ }
+
+ SECTION("Directory reset")
+ {
+ struct stat st;
+ std::vector<std::tuple<std::string, struct stat>> vec;
+ for (std::string fnm;;) {
+ if (fscore.dirnext(dirhandle, fnm, st) != 0) {
+ break;
+ }
+ else {
+ vec.push_back(std::make_tuple(fnm, st));
+ std::cout << "name " << fnm << " size " << st.st_size << std::endl;
+ }
+ }
+
+ fscore.dirreset(dirhandle);
+ int i = 0;
+ for (std::string fnm;; i++) {
+ if (fscore.dirnext(dirhandle, fnm, st) != 0) {
+ break;
+ }
+ else {
+ const auto [fnm_vec, st_vec] = vec[i];
+ REQUIRE(fnm == fnm_vec);
+ REQUIRE(st_vec.st_size == st.st_size);
+ std::cout << "name " << fnm << " size " << st.st_size << std::endl;
+ }
+ }
+ REQUIRE(fscore.dirclose(dirhandle) == 0);
+ REQUIRE(fscore.umount("/sys") == 0);
+ }
+}