~aleteoryx/muditaos

cb5b5a37b8aeb5cb9d75d5df443078e1a1a67551 — Lucjan Bryndza 5 years ago 37aee39
[EGD-5170] Fix native diropen

In the current implementation diropen is unable to listdir
in the native filesystem. This patch fix this issue.
M board/linux/libiosyscalls/include/iosyscalls.hpp => board/linux/libiosyscalls/include/iosyscalls.hpp +7 -0
@@ 6,6 6,8 @@
#include <stdio.h>
#include <purefs/vfs_subsystem.hpp>

struct __dirstream;

namespace vfsn::linux::internal
{
    bool redirect_to_image();


@@ 25,6 27,11 @@ namespace vfsn::linux::internal
    bool is_filex(const void* fd);
    void remove_filex(FILEX *fil);


    void add_DIR_to_image_list(__dirstream* indir);
    void remove_DIR_from_image_list(__dirstream* indir);
    bool is_image_DIR(__dirstream* indir);

    template <class Base, typename T, typename... Args>
        auto invoke_fs( T Base::*lfs_fun, Args&& ... args)
        -> decltype((static_cast<Base *>(nullptr)->*lfs_fun)(std::forward<Args>(args)...))

M board/linux/libiosyscalls/src/dirent.cpp => board/linux/libiosyscalls/src/dirent.cpp +11 -7
@@ 31,7 31,7 @@ extern "C" {
        }
        else
        {
            if( redirect_to_image() )
            if( redirect_to_image(dirname) )
            {
                auto vfs = purefs::subsystem::vfs_core();
                if(!vfs)


@@ 63,6 63,9 @@ extern "C" {
                        }
                    }
                }
                if(ret) {
                    add_DIR_to_image_list(ret);
                }
            }
            else
            {


@@ 87,7 90,7 @@ extern "C" {
                ret = -1;
                break;
            }
            if(redirect_to_image()) {
            if(is_image_DIR(dirp)) {
                auto vfs = purefs::subsystem::vfs_core();
                if(!vfs) {
                    errno = EIO;


@@ 99,6 102,7 @@ extern "C" {
                    errno = -ret;
                    ret = -1;
                }
                remove_DIR_from_image_list(dirp);
                delete dirp;
            } else {
                auto r_closedir = reinterpret_cast<int (*)(DIR*)>(dlsym(RTLD_NEXT,"closedir"));


@@ 118,7 122,7 @@ extern "C" {
                errno = EBADF;
                break;
            }
            if(redirect_to_image()) {
            if(is_image_DIR(dirp)) {
                auto vfs = purefs::subsystem::vfs_core();
                if(!vfs) {
                    errno = EIO;


@@ 161,7 165,7 @@ extern "C" {
            errno = EBADF;
            return -1;
        }
        if(redirect_to_image()) {
        if(is_image_DIR(dirp)) {
            auto vfs = purefs::subsystem::vfs_core();
            if(!vfs) {
                errno = EIO;


@@ 201,7 205,7 @@ extern "C" {
            errno = EBADF;
            return;
        }
        if(redirect_to_image())
        if(is_image_DIR(dirp))
        {
            auto vfs = purefs::subsystem::vfs_core();
            if(!vfs) {


@@ 228,7 232,7 @@ extern "C" {
            errno = EBADF;
            return;
        }
        if( redirect_to_image() )
        if( is_image_DIR(dirp) )
        {
            if (loc < 0) {
                return;


@@ 262,7 266,7 @@ extern "C" {
            errno = EBADF;
            return -1;
        }
        if( redirect_to_image() )
        if( is_image_DIR(dirp) )
        {
            return dirp->position;
        }

M board/linux/libiosyscalls/src/iosyscalls.cpp => board/linux/libiosyscalls/src/iosyscalls.cpp +37 -0
@@ 10,6 10,7 @@
#include <dlfcn.h>
#include <stdarg.h>
#include <debug.hpp>
#include <dirent.h>

namespace {
    constexpr auto ENV_NAME = "IOSYSCALLS_REDIRECT_TO_IMAGE";


@@ 20,6 21,11 @@ namespace {
        "/dev/",
        "/etc/",
        "/sys/",
        "/usr/share",
        "/run/user",
        "/home",
        "/proc",
        "/dev/shm",
        "PurePhone.img",
        nullptr,
    };


@@ 42,6 48,7 @@ namespace {

    pthread_mutex_t g_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
    phmap::flat_hash_set<vfsn::linux::internal::FILEX*> g_fdlist;
    phmap::flat_hash_set<DIR*> g_dirlist;
}

namespace vfsn::linux::internal


@@ 126,6 133,36 @@ namespace vfsn::linux::internal
        return ret;
    }

    void add_DIR_to_image_list(DIR* indir)
    {
        pthread_mutex_lock(&g_lock);
        g_dirlist.emplace( indir );
        pthread_mutex_unlock(&g_lock);
    }

    void remove_DIR_from_image_list(DIR* indir)
    {
        pthread_mutex_lock(&g_lock);
        auto fres = g_dirlist.find(indir);
        if(fres != g_dirlist.end())
        {
            g_dirlist.erase(fres);
        }
        pthread_mutex_unlock(&g_lock);
    }

    bool is_image_DIR(DIR* indir)
    {
        if(indir==nullptr) {
            return false;
        }
        pthread_mutex_lock(&g_lock);
        auto fres = g_dirlist.find(indir);
        auto isntdir = ( fres != g_dirlist.end() );
        pthread_mutex_unlock(&g_lock);
        return isntdir;
    }

    bool is_filex(const void* fd)
    {
        if(fd==nullptr) {

M module-vfs/src/purefs/fs/filesystem_syscalls.cpp => module-vfs/src/purefs/fs/filesystem_syscalls.cpp +2 -2
@@ 110,7 110,7 @@ namespace purefs::fs
        const auto abspath     = absolute_path(path);
        auto [mountp, pathpos] = find_mount_point(abspath);
        if (!mountp) {
            LOG_ERROR("VFS: Unable to find mount point");
            LOG_ERROR("VFS: Unable to find mount point: %.*s", int(path.size()), path.data());
            return -ENOENT;
        }
        auto fsops = mountp->fs_ops();


@@ 146,7 146,7 @@ namespace purefs::fs
        const auto abspath     = absolute_path(path);
        auto [mountp, pathpos] = find_mount_point(abspath);
        if (!mountp) {
            LOG_ERROR("VFS: Unable to find mount point");
            LOG_ERROR("VFS: Unable to find mount point: %.*s", int(path.size()), path.data());
            return std::make_shared<internal::directory_handle>(nullptr, -ENOENT);
        }
        auto fsops = mountp->fs_ops();