Commit 5fb17e06 authored by Marc Vef's avatar Marc Vef
Browse files

Moving path code from preload context, updating hooks.cpp with new method

parent 06ee81b5
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -17,12 +17,22 @@
namespace gkfs {
namespace path {

enum class NormalizeStatus {
    ok,
    fd_unknown,
    fd_not_a_dir
};

unsigned int match_components(const std::string& path, unsigned int& path_components,
                              const std::vector<std::string>& components);

bool resolve(const std::string& path, std::string& resolved, bool resolve_last_link = true);

std::string normalize(const std::string& path);
NormalizeStatus normalize(int dirfd, const char* raw_path, std::string& normalized_path, bool resolve_last_link = true);

std::string normalize(const char* raw_path, bool resolve_last_link = true);

bool is_in_gkfs(std::string& path, bool cut_mountdir_prefix = false);

std::string get_sys_cwd();

+0 −20
Original line number Diff line number Diff line
@@ -54,12 +54,6 @@ struct FsConfig {

};

enum class RelativizeStatus {
    ok,
    fd_unknown,
    fd_not_a_dir
};

/**
 * Singleton class of the client context with all relevant global data
 */
@@ -117,24 +111,10 @@ public:

    void clear_hosts();


    uint64_t local_host_id() const;

    void local_host_id(uint64_t id);

    bool is_gkfs_path(std::string& path);

    RelativizeStatus normalize_path(int dirfd, const char* raw_path, std::string& normalized_path, bool resolve_last_link = true);

    std::string normalize_path(const char* raw_path, bool resolve_last_link = true);

    RelativizeStatus relativize_fd_path(int dirfd,
                                        const char* raw_path,
                                        std::string& relative_path,
                                        bool resolve_last_link = true) const;

    bool relativize_path(const char* raw_path, std::string& relative_path, bool resolve_last_link = true) const;

    const std::shared_ptr<gkfs::filemap::OpenFileMap>& file_map() const;

    void distributor(std::shared_ptr<gkfs::rpc::Distributor> distributor);
+71 −71
Original line number Diff line number Diff line
@@ -47,17 +47,17 @@ int hook_openat(int dirfd, const char* cpath, int flags, mode_t mode) {
        __func__, dirfd, cpath, flags, mode);

    std::string normalized_path{};
    auto status = CTX->normalize_path(dirfd, cpath, normalized_path);
    auto status = gkfs::path::normalize(dirfd, cpath, normalized_path);

    switch (status) {
        case gkfs::preload::RelativizeStatus::fd_unknown:
        case gkfs::path::NormalizeStatus::fd_unknown:
            return syscall_no_intercept(SYS_openat, dirfd, cpath, flags, mode);

        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
        case gkfs::path::NormalizeStatus::fd_not_a_dir:
            return -ENOTDIR;

        case gkfs::preload::RelativizeStatus::ok:
            if (CTX->is_gkfs_path(normalized_path))
        case gkfs::path::NormalizeStatus::ok:
            if (gkfs::path::is_in_gkfs(normalized_path, true))
                return with_errno(gkfs::syscall::gkfs_open(normalized_path, mode, flags));
            else
                return syscall_no_intercept(SYS_openat, dirfd, normalized_path.c_str(), flags, mode);
@@ -113,8 +113,8 @@ int hook_stat(const char* path, struct stat* buf) {
    LOG(DEBUG, "{}() called with path: \"{}\", buf: {}",
        __func__, path, fmt::ptr(buf));

    auto normalized_path = CTX->normalize_path(path, false);
    if (CTX->is_gkfs_path(normalized_path))
    auto normalized_path = gkfs::path::normalize(path, false);
    if (gkfs::path::is_in_gkfs(normalized_path, true))
        return with_errno(gkfs::syscall::gkfs_stat(normalized_path, buf));
    else
        return syscall_no_intercept(SYS_stat, normalized_path.c_str(), buf);
@@ -127,17 +127,17 @@ int hook_statx(int dirfd, const char* path, int flags, unsigned int mask, struct
        __func__, dirfd, path, flags, mask, fmt::ptr(buf));

    std::string normalized_path{};
    auto status = CTX->normalize_path(dirfd, path, normalized_path);
    auto status = gkfs::path::normalize(dirfd, path, normalized_path);

    switch (status) {
        case gkfs::preload::RelativizeStatus::fd_unknown:
        case gkfs::path::NormalizeStatus::fd_unknown:
            return syscall_no_intercept(SYS_statx, dirfd, path, flags, mask,  buf);

        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
        case gkfs::path::NormalizeStatus::fd_not_a_dir:
            return -ENOTDIR;

        case gkfs::preload::RelativizeStatus::ok:
            if (CTX->is_gkfs_path(normalized_path))
        case gkfs::path::NormalizeStatus::ok:
            if (gkfs::path::is_in_gkfs(normalized_path, true))
                return with_errno(gkfs::syscall::gkfs_statx(dirfd, normalized_path.c_str() , flags, mask, buf));
            else
                return syscall_no_intercept(SYS_statx, dirfd, normalized_path.c_str(), flags, mask,  buf);
@@ -153,8 +153,8 @@ int hook_lstat(const char* path, struct stat* buf) {
    LOG(DEBUG, "{}() called with path: \"{}\", buf: {}",
        __func__, path, fmt::ptr(buf));

    auto normalized_path = CTX->normalize_path(path);
    if (CTX->is_gkfs_path(normalized_path))
    auto normalized_path = gkfs::path::normalize(path);
    if (gkfs::path::is_in_gkfs(normalized_path, true))
        return with_errno(gkfs::syscall::gkfs_stat(normalized_path, buf));
    else
        return syscall_no_intercept(SYS_lstat, normalized_path.c_str(), buf);
@@ -183,17 +183,17 @@ int hook_fstatat(int dirfd, const char* cpath, struct stat* buf, int flags) {
    }

    std::string normalized_path{};
    auto status = CTX->normalize_path(dirfd, cpath, normalized_path);
    auto status = gkfs::path::normalize(dirfd, cpath, normalized_path);

    switch (status) {
        case gkfs::preload::RelativizeStatus::fd_unknown:
        case gkfs::path::NormalizeStatus::fd_unknown:
            return syscall_no_intercept(SYS_newfstatat, dirfd, cpath, buf, flags);

        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
        case gkfs::path::NormalizeStatus::fd_not_a_dir:
            return -ENOTDIR;

        case gkfs::preload::RelativizeStatus::ok:
            if (CTX->is_gkfs_path(normalized_path))
        case gkfs::path::NormalizeStatus::ok:
            if (gkfs::path::is_in_gkfs(normalized_path, true))
                return with_errno(gkfs::syscall::gkfs_stat(normalized_path, buf));
            else
                return syscall_no_intercept(SYS_newfstatat, dirfd, normalized_path.c_str(), buf, flags);
@@ -309,17 +309,17 @@ int hook_unlinkat(int dirfd, const char* cpath, int flags) {
    }

    std::string normalized_path{};
    auto status = CTX->normalize_path(dirfd, cpath, normalized_path, false);
    auto status = gkfs::path::normalize(dirfd, cpath, normalized_path, false);

    switch (status) {
        case gkfs::preload::RelativizeStatus::fd_unknown:
        case gkfs::path::NormalizeStatus::fd_unknown:
            return syscall_no_intercept(SYS_unlinkat, dirfd, cpath, flags);

        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
        case gkfs::path::NormalizeStatus::fd_not_a_dir:
            return -ENOTDIR;

        case gkfs::preload::RelativizeStatus::ok:
            if (CTX->is_gkfs_path(normalized_path)) {
        case gkfs::path::NormalizeStatus::ok:
            if (gkfs::path::is_in_gkfs(normalized_path, true)) {
                if (flags & AT_REMOVEDIR) {
                    return with_errno(gkfs::syscall::gkfs_rmdir(normalized_path));
                } else {
@@ -337,24 +337,24 @@ int hook_symlinkat(const char* oldname, int newdfd, const char* newname) {
    LOG(DEBUG, "{}() called with oldname: \"{}\", newfd: {}, newname: \"{}\"",
        __func__, oldname, newdfd, newname);

    auto old_normalized_path = CTX->normalize_path(oldname);
    if (CTX->is_gkfs_path(old_normalized_path)) {
    auto old_normalized_path = gkfs::path::normalize(oldname);
    if (gkfs::path::is_in_gkfs(old_normalized_path)) {
        LOG(WARNING, "{}() operation not supported", __func__);
        return -ENOTSUP;
    }

    std::string new_normalized_path{};
    auto status = CTX->normalize_path(newdfd, newname, new_normalized_path, false);
    auto status = gkfs::path::normalize(newdfd, newname, new_normalized_path, false);

    switch (status) {
        case gkfs::preload::RelativizeStatus::fd_unknown:
        case gkfs::path::NormalizeStatus::fd_unknown:
            return syscall_no_intercept(SYS_symlinkat, oldname, newdfd, newname);

        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
        case gkfs::path::NormalizeStatus::fd_not_a_dir:
            return -ENOTDIR;

        case gkfs::preload::RelativizeStatus::ok:
            if (CTX->is_gkfs_path(new_normalized_path)) {
        case gkfs::path::NormalizeStatus::ok:
            if (gkfs::path::is_in_gkfs(new_normalized_path)) {
                LOG(WARNING, "{}() operation not supported", __func__);
                return -ENOTSUP;
            } else
@@ -371,8 +371,8 @@ int hook_access(const char* path, int mask) {
    LOG(DEBUG, "{}() called path: \"{}\", mask: {}",
        __func__, path, mask);

    auto normalized_path = CTX->normalize_path(path);
    if (CTX->is_gkfs_path(normalized_path)) {
    auto normalized_path = gkfs::path::normalize(path);
    if (gkfs::path::is_in_gkfs(normalized_path, true)) {
        auto ret = gkfs::syscall::gkfs_access(normalized_path, mask);
        if (ret < 0) {
            return -errno;
@@ -388,17 +388,17 @@ int hook_faccessat(int dirfd, const char* cpath, int mode) {
        __func__, dirfd, cpath, mode);

    std::string normalized_path{};
    auto status = CTX->normalize_path(dirfd, cpath, normalized_path);
    auto status = gkfs::path::normalize(dirfd, cpath, normalized_path);

    switch (status) {
        case gkfs::preload::RelativizeStatus::fd_unknown:
        case gkfs::path::NormalizeStatus::fd_unknown:
            return syscall_no_intercept(SYS_faccessat, dirfd, cpath, mode);

        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
        case gkfs::path::NormalizeStatus::fd_not_a_dir:
            return -ENOTDIR;

        case gkfs::preload::RelativizeStatus::ok:
            if (CTX->is_gkfs_path(normalized_path))
        case gkfs::path::NormalizeStatus::ok:
            if (gkfs::path::is_in_gkfs(normalized_path, true))
                return with_errno(gkfs::syscall::gkfs_access(normalized_path, mode));
            else
                return syscall_no_intercept(SYS_faccessat, dirfd, normalized_path.c_str(), mode);
@@ -431,8 +431,8 @@ int hook_truncate(const char* path, long length) {
    LOG(DEBUG, "{}() called with path: {}, offset: {}",
        __func__, path, length);

    auto normalized_path = CTX->normalize_path(path);
    if (CTX->is_gkfs_path(normalized_path))
    auto normalized_path = gkfs::path::normalize(path);
    if (gkfs::path::is_in_gkfs(normalized_path, true))
        return with_errno(gkfs::syscall::gkfs_truncate(normalized_path, length));
    else
        return syscall_no_intercept(SYS_truncate, normalized_path.c_str(), length);
@@ -516,17 +516,17 @@ int hook_mkdirat(int dirfd, const char* cpath, mode_t mode) {
        __func__, dirfd, cpath, mode);

    std::string normalized_path{};
    auto status = CTX->normalize_path(dirfd, cpath, normalized_path);
    auto status = gkfs::path::normalize(dirfd, cpath, normalized_path);

    switch (status) {
        case gkfs::preload::RelativizeStatus::fd_unknown:
        case gkfs::path::NormalizeStatus::fd_unknown:
            return syscall_no_intercept(SYS_mkdirat, dirfd, cpath, mode);

        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
        case gkfs::path::NormalizeStatus::fd_not_a_dir:
            return -ENOTDIR;

        case gkfs::preload::RelativizeStatus::ok:
            if (CTX->is_gkfs_path(normalized_path))
        case gkfs::path::NormalizeStatus::ok:
            if (gkfs::path::is_in_gkfs(normalized_path, true))
                return with_errno(gkfs::syscall::gkfs_create(normalized_path, mode | S_IFDIR));
            else
                return syscall_no_intercept(SYS_mkdirat, dirfd, normalized_path.c_str(), mode);
@@ -542,17 +542,17 @@ int hook_fchmodat(int dirfd, const char* cpath, mode_t mode) {
        __func__, dirfd, cpath, mode);

    std::string normalized_path{};
    auto status = CTX->normalize_path(dirfd, cpath, normalized_path);
    auto status = gkfs::path::normalize(dirfd, cpath, normalized_path);

    switch (status) {
        case gkfs::preload::RelativizeStatus::fd_unknown:
        case gkfs::path::NormalizeStatus::fd_unknown:
            return syscall_no_intercept(SYS_fchmodat, dirfd, cpath, mode);

        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
        case gkfs::path::NormalizeStatus::fd_not_a_dir:
            return -ENOTDIR;

        case gkfs::preload::RelativizeStatus::ok:
            if (CTX->is_gkfs_path(normalized_path)) {
        case gkfs::path::NormalizeStatus::ok:
            if (gkfs::path::is_in_gkfs(normalized_path)) {
                LOG(WARNING, "{}() operation not supported", __func__);
                return -ENOTSUP;
            } else
@@ -580,8 +580,8 @@ int hook_chdir(const char* path) {
    LOG(DEBUG, "{}() called with path: \"{}\"",
        __func__, path);

    auto normalized_path = CTX->normalize_path(path);
    auto internal = CTX->is_gkfs_path(normalized_path);
    auto normalized_path = gkfs::path::normalize(path);
    auto internal = gkfs::path::is_in_gkfs(normalized_path, true);
    if (internal) {
        //path falls in our namespace
        auto md = gkfs::util::get_metadata(normalized_path);
@@ -593,14 +593,14 @@ int hook_chdir(const char* path) {
            LOG(ERROR, "{}() path is not a directory", __func__);
            return -ENOTDIR;
        }
        //TODO get complete path from relativize_path instead of
        // removing mountdir and then adding again here
        // readd mountdir prefix again for setting current working directory
        normalized_path.insert(0, CTX->mountdir());
        if (gkfs::path::has_trailing_slash(normalized_path)) {
            // open_dir is '/'
            normalized_path.pop_back();
        }
    }
    // TODO fix with LEAF
    try {
        gkfs::path::set_cwd(normalized_path, internal);
    } catch (const std::system_error& se) {
@@ -667,17 +667,17 @@ int hook_readlinkat(int dirfd, const char* cpath, char* buf, int bufsiz) {
        __func__, dirfd, cpath, fmt::ptr(buf), bufsiz);

    std::string normalized_path{};
    auto status = CTX->normalize_path(dirfd, cpath, normalized_path, false);
    auto status = gkfs::path::normalize(dirfd, cpath, normalized_path, false);

    switch (status) {
        case gkfs::preload::RelativizeStatus::fd_unknown:
        case gkfs::path::NormalizeStatus::fd_unknown:
            return syscall_no_intercept(SYS_readlinkat, dirfd, cpath, buf, bufsiz);

        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
        case gkfs::path::NormalizeStatus::fd_not_a_dir:
            return -ENOTDIR;

        case gkfs::preload::RelativizeStatus::ok:
            if (CTX->is_gkfs_path(normalized_path)) {
        case gkfs::path::NormalizeStatus::ok:
            if (gkfs::path::is_in_gkfs(normalized_path)) {
                LOG(WARNING, "{}() not supported", __func__);
                return -ENOTSUP;
            } else
@@ -762,18 +762,18 @@ int hook_renameat(int olddfd, const char* oldname,

    const char* oldpath_pass;
    std::string oldpath_normalized_path{};
    auto status = CTX->normalize_path(olddfd, oldname, oldpath_normalized_path);
    auto status = gkfs::path::normalize(olddfd, oldname, oldpath_normalized_path);

    switch (status) {
        case gkfs::preload::RelativizeStatus::fd_unknown:
        case gkfs::path::NormalizeStatus::fd_unknown:
            oldpath_pass = oldname;
            break;

        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
        case gkfs::path::NormalizeStatus::fd_not_a_dir:
            return -ENOTDIR;

        case gkfs::preload::RelativizeStatus::ok:
            if (CTX->is_gkfs_path(oldpath_normalized_path)) {
        case gkfs::path::NormalizeStatus::ok:
            if (gkfs::path::is_in_gkfs(oldpath_normalized_path)) {
                LOG(WARNING, "{}() not supported", __func__);
                return -ENOTSUP;
            } else {
@@ -788,18 +788,18 @@ int hook_renameat(int olddfd, const char* oldname,

    const char* newpath_pass;
    std::string newpath_normalized_path{};
    status = CTX->normalize_path(newdfd, newname, newpath_normalized_path);
    status = gkfs::path::normalize(newdfd, newname, newpath_normalized_path);

    switch (status) {
        case gkfs::preload::RelativizeStatus::fd_unknown:
        case gkfs::path::NormalizeStatus::fd_unknown:
            newpath_pass = newname;
            break;

        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
        case gkfs::path::NormalizeStatus::fd_not_a_dir:
            return -ENOTDIR;

        case gkfs::preload::RelativizeStatus::ok:
            if (CTX->is_gkfs_path(newpath_normalized_path)) {
        case gkfs::path::NormalizeStatus::ok:
            if (gkfs::path::is_in_gkfs(newpath_normalized_path)) {
                LOG(WARNING, "{}() not supported", __func__);
                return -ENOTSUP;
            } else {
@@ -820,8 +820,8 @@ int hook_statfs(const char* path, struct statfs* buf) {
    LOG(DEBUG, "{}() called with path: \"{}\", buf: {}",
        __func__, path, fmt::ptr(buf));

    auto normalized_path = CTX->normalize_path(path);
    if (CTX->is_gkfs_path(normalized_path))
    auto normalized_path = gkfs::path::normalize(path);
    if (gkfs::path::is_in_gkfs(normalized_path, true))
        return with_errno(gkfs::syscall::gkfs_statfs(buf));
    else
        return syscall_no_intercept(SYS_statfs, normalized_path.c_str(), buf);
+132 −46
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
#include <client/preload.hpp>
#include <client/logging.hpp>
#include <client/env.hpp>
#include <client/open_file_map.hpp>
#include <client/open_dir.hpp>

#include <global/path_util.hpp>

@@ -31,6 +33,61 @@ extern "C" {

using namespace std;

namespace {
/**
 * Normalize a given path with `.` and `..` components. This will not resolve symlinks
 * @param path
 * @return normalized path
 */
string normalize(const string& path) {

    string normalized{}; // final normalized path
    normalized.reserve(path.size());
    string::size_type comp_size = 0; // size of current component
    string::size_type start = 0; // start index of curr component
    string::size_type end = 0; // end index of curr component (last processed Path Separator "separator")
    stack<string::size_type> slash_idx{};
    slash_idx.push(0); // index of all slashes in resolved path (used for rollback due to `..`)

    while (++end < path.size()) {
        start = end;
        // Skip sequence of multiple path-separators.
        while (start < path.size() && path[start] == gkfs::path::separator) {
            start++;
        }
        // Find next component
        end = path.find_first_of(gkfs::path::separator, start);
        if (end == string::npos) {
            end = path.size();
        }
        comp_size = end - start;

        // component is empty (this must be the last component)
        if (comp_size == 0) {
            break;
        }
        // component is '.', we skip it
        if (comp_size == 1 && path.at(start) == '.') {
            continue;
        }
        // component is '..' we need to rollback normalized path
        if (comp_size == 2 && path.at(start) == '.' && path.at(start + 1) == '.') {
            if (!normalized.empty()) {
                normalized.erase(slash_idx.top());
                slash_idx.pop();
            }
            continue;
        }
        // add `/<component>` to the normalized path
        normalized.push_back(gkfs::path::separator);
        slash_idx.push(normalized.size() - 1);
        normalized.append(path, start, comp_size);
    }
    LOG(INFO, "path: '{}', normalized: '{}'", path, normalized);
    return normalized;
}
}

namespace gkfs {
namespace path {

@@ -78,58 +135,87 @@ unsigned int match_components(const string& path, unsigned int& path_components,
    return matched;
}

NormalizeStatus normalize(int dirfd, const char* raw_path, std::string& normalized_path, bool resolve_last_link) {
    // TODO when LEAF is available: return concated path and throw Status instead.
    // Relativize path should be called only after the library constructor has been executed
    assert(CTX->interception_enabled());
    // If we run the constructor we also already setup the mountdir
    assert(!CTX->mountdir().empty());

/**
 * Normalize a given path with `.` and `..` components. This will not resolve symlinks
 * @param path
 * @return normalized path
 */
string normalize(const string& path) {
    // We assume raw path is valid
    assert(raw_path != nullptr);

    string normalized{}; // final normalized path
    normalized.reserve(path.size());
    string::size_type comp_size = 0; // size of current component
    string::size_type start = 0; // start index of curr component
    string::size_type end = 0; // end index of curr component (last processed Path Separator "separator")
    stack<string::size_type> slash_idx{};
    slash_idx.push(0); // index of all slashes in resolved path (used for rollback due to `..`)
    std::string path{};

    while (++end < path.size()) {
        start = end;
        // Skip sequence of multiple path-separators.
        while (start < path.size() && path[start] == path::separator) {
            start++;
    if (raw_path[0] != gkfs::path::separator) {
        // path is relative
        if (dirfd == AT_FDCWD) {
            // path is relative to cwd
            path = gkfs::path::prepend_path(CTX->cwd(), raw_path);
        } else {
            if (!CTX->file_map()->exist(dirfd)) {
                return NormalizeStatus::fd_unknown;
            }
        // Find next component
        end = path.find_first_of(path::separator, start);
        if (end == string::npos) {
            end = path.size();
            // path is relative to fd
            auto dir = CTX->file_map()->get_dir(dirfd);
            if (dir == nullptr) {
                return NormalizeStatus::fd_not_a_dir;
            }
        comp_size = end - start;

        // component is empty (this must be the last component)
        if (comp_size == 0) {
            break;
            path = CTX->mountdir();
            path.append(dir->path());
            path.push_back(gkfs::path::separator);
            path.append(raw_path);
        }
        // component is '.', we skip it
        if (comp_size == 1 && path.at(start) == '.') {
            continue;
    } else {
        path = raw_path;
    }
        // component is '..' we need to rollback normalized path
        if (comp_size == 2 && path.at(start) == '.' && path.at(start + 1) == '.') {
            if (!normalized.empty()) {
                normalized.erase(slash_idx.top());
                slash_idx.pop();
    normalized_path = ::normalize(path);
    return NormalizeStatus::ok;
}
            continue;

std::string normalize(const char* raw_path, bool resolve_last_link) {
    // TODO when LEAF is available: return concated path and throw Status instead.
    // Relativize path should be called only after the library constructor has been executed
    assert(CTX->interception_enabled());
    // If we run the constructor we also already setup the mountdir
    assert(!CTX->mountdir().empty());

    // We assume raw path is valid
    assert(raw_path != nullptr);

    std::string path;

    if (raw_path[0] != gkfs::path::separator) {
        /* Path is not absolute, we need to prepend CWD;
         * First reserve enough space to minimize memory copy
         */
        path = gkfs::path::prepend_path(CTX->cwd(), raw_path);
    } else {
        path = raw_path;
    }
        // add `/<component>` to the normalized path
        normalized.push_back(path::separator);
        slash_idx.push(normalized.size() - 1);
        normalized.append(path, start, comp_size);
    return ::normalize(path);
}

/**
 * Checks if a path is within gkfs namespace. normalize_path() should have been called before
 * as the mountpoint in the path is checked from the beginning and must therefore be absolute.
 *
 * cut_mountdir_prefix can be passed to remove the mountdir prefix from path: /tmp/mountdir/gkfsfile -> /gkfsfile
 * It modifies the given path instead of returning a new string to avoid copying,
 * as this function is performance critical
 *
 * @param path (absolute path)
 * @param cut_mountdir_prefix (default false, if true gkfs mountpoint path is cut if it is within gkfs namespace)
 * @return true if within gkfs namespace else false
 */
bool is_in_gkfs(std::string& path, bool cut_mountdir_prefix) {
    if (path.rfind(CTX->mountdir(), 0) != std::string::npos) {
        if (cut_mountdir_prefix)
            path.erase(1, CTX->mountdir().size());
        return true;
    } else {
        return false;
    }
    LOG(INFO, "path: '{}', normalized: '{}'", path, normalized);
    return normalized;
}

/** Resolve path to its canonical representation
+0 −79

File changed.

Preview size limit exceeded, changes collapsed.