~aleteoryx/muditaos

79a6264b7c6e92c8cb44f9624c26b119ea661a0f — Lucjan Bryndza 5 years ago 6f3a6b4
[EGD-5020] Add autodetect filesystem

Add support for autodetect filesystem in the fs core
M module-vfs/include/user/purefs/blkdev/disk_manager.hpp => module-vfs/include/user/purefs/blkdev/disk_manager.hpp +9 -0
@@ 8,6 8,7 @@
#include <vector>
#include <unordered_map>
#include <tuple>
#include <optional>
#include "defs.hpp"
#include "partition.hpp"



@@ 102,6 103,14 @@ namespace purefs::blkdev
         */
        [[nodiscard]] auto partitions(disk_fd dfd) const -> std::vector<partition>;
        [[nodiscard]] auto partitions(std::string_view device_name) const -> std::vector<partition>;

        /** Get the selected partition info
         * @Param[in] Disk manager fd
         * @return Partition info data
         */
        [[nodiscard]] auto partition_info(disk_fd dfd) const -> std::optional<partition>;
        [[nodiscard]] auto partition_info(std::string_view device_name) const -> std::optional<partition>;

        /** Get media device info
         * @param[in] dfd Disk manager handle
         * @param[in] what Information type @see info_type

M module-vfs/include/user/purefs/fs/filesystem.hpp => module-vfs/include/user/purefs/fs/filesystem.hpp +1 -1
@@ 163,8 163,8 @@ namespace purefs::fs
        auto add_filehandle(fsfile file) noexcept -> int;
        auto remove_filehandle(int fds) noexcept -> fsfile;
        auto find_filehandle(int fds) const noexcept -> fsfile;
        auto autodetect_filesystem_type(std::string_view dev_or_part) const noexcept -> std::string;

      private:
        enum class iaccess : bool
        {
            ro, //! Syscall is RO

M module-vfs/src/purefs/blkdev/disk_manager.cpp => module-vfs/src/purefs/blkdev/disk_manager.cpp +35 -0
@@ 261,6 261,32 @@ namespace purefs::blkdev
        }
        return disk->partitions();
    }
    auto disk_manager::partition_info(disk_fd dfd) const -> std::optional<partition>
    {
        if (!dfd) {
            LOG_ERROR("Disk handle doesn't exists");
            return std::nullopt;
        }
        auto disk = dfd->disk();
        if (!disk) {
            LOG_ERROR("Disk doesn't exists");
            return std::nullopt;
        }
        if (dfd->has_partition()) {
            auto parts = disk->partitions();
            if (size_t(dfd->partition()) >= parts.size()) {
                LOG_ERROR("Partition num out of range");
                return std::nullopt;
            }
            else {
                return {parts[dfd->partition()]};
            }
        }
        else {
            LOG_ERROR("No paritions on disc");
            return std::nullopt;
        }
    }
    auto disk_manager::get_info(disk_fd dfd, info_type what) const -> scount_t
    {
        if (!dfd) {


@@ 374,6 400,14 @@ namespace purefs::blkdev
        else
            return {};
    }
    auto disk_manager::partition_info(std::string_view device_name) const -> std::optional<partition>
    {
        auto dfd = device_handle(device_name);
        if (dfd)
            return partition_info(dfd);
        else
            return std::nullopt;
    }
    auto disk_manager::get_info(std::string_view device_name, info_type what) const -> scount_t
    {
        auto dfd = device_handle(device_name);


@@ 395,4 429,5 @@ namespace purefs::blkdev
        const auto new_name = std::get<0>(parse_device_name(disk->name()));
        return std::make_shared<internal::disk_handle>(disk->disk(), new_name);
    }

} // namespace purefs::blkdev

M module-vfs/src/purefs/fs/filesystem.cpp => module-vfs/src/purefs/fs/filesystem.cpp +46 -2
@@ 13,6 13,13 @@

namespace purefs::fs
{
    namespace
    {
        constexpr std::pair<short, std::string_view> part_types_to_vfs[] = {
            {0x0b, "vfat"},
            {0x9e, "littlefs"},
        };
    }
    filesystem::filesystem(std::shared_ptr<blkdev::disk_manager> diskmm)
        : m_diskmm(diskmm), m_lock(new cpp_freertos::MutexRecursive)
    {}


@@ 91,9 98,20 @@ namespace purefs::fs
                LOG_ERROR("VFS: partition already used %.*s", int(dev_or_part.length()), dev_or_part.data());
                return -EBUSY;
            }
            const auto vsi = m_fstypes.find(std::string(fs_type));
            std::string filesystem_type;
            if (fs_type.compare("auto") == 0) {
                filesystem_type = autodetect_filesystem_type(std::string(dev_or_part));
                if (filesystem_type.empty()) {
                    LOG_ERROR("Unable to auto detect filesystem");
                    return -ENODEV;
                }
            }
            else {
                filesystem_type = fs_type;
            }
            const auto vsi = m_fstypes.find(filesystem_type);
            if (vsi == std::end(m_fstypes)) {
                LOG_ERROR("VFS: requested filesystem %.*s not registered", int(fs_type.length()), fs_type.data());
                LOG_ERROR("VFS: requested filesystem %s not registered", filesystem_type.c_str());
                return -ENODEV;
            }
            // Trying to open disk or part by manager


@@ 263,4 281,30 @@ namespace purefs::fs
        return ret;
    }

    auto filesystem::autodetect_filesystem_type(std::string_view dev_or_part) const noexcept -> std::string
    {
        auto disk_mgr = m_diskmm.lock();
        if (disk_mgr) {
            auto part = disk_mgr->partition_info(dev_or_part);
            if (part) {
                for (auto &ptype : part_types_to_vfs) {
                    if (ptype.first == part.value().type) {
                        const auto ret = std::string(ptype.second);
                        LOG_INFO("Autodetected filesystem type %s", ret.c_str());
                        return ret;
                    }
                }
                LOG_ERROR("Unable to detect filesystem type");
                return {};
            }
            else {
                LOG_ERROR("No partition on device");
                return {};
            }
        }
        else {
            LOG_ERROR("VFS: Unable to lock device manager");
            return {};
        }
    }
} // namespace purefs::fs

M module-vfs/tests/unittest_filesystem_core.cpp => module-vfs/tests/unittest_filesystem_core.cpp +16 -0
@@ 345,6 345,22 @@ TEST_CASE("Remount filesystem from RO to RW and to RO")
    REQUIRE(fscore->umount("/sys") == 0);
}

TEST_CASE("Autodetect filesystems")
{
    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", "auto") == 0);
    REQUIRE(fscore->umount("/sys") == 0);
}

TEST_CASE("Unititest integrated subsystem")
{
    auto [disk, vfs] = purefs::subsystem::initialize();