Verified Commit 25a5ed7a authored by Marc Vef's avatar Marc Vef
Browse files

Client: Removing shared metadata pointers from gkfs functions

parent 6a228cdb
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -55,7 +55,7 @@ to_underlying(E e) {
    return static_cast<typename std::underlying_type<E>::type>(e);
}

std::shared_ptr<gkfs::metadata::Metadata>
std::optional<gkfs::metadata::Metadata>
get_metadata(const std::string& path, bool follow_links = false);

int
+40 −31
Original line number Diff line number Diff line
@@ -118,8 +118,8 @@ gkfs_open(const std::string& path, mode_t mode, int flags) {
        errno = ENOTSUP;
        return -1;
    }
    // metadata pointer assigned during create or stat
    std::shared_ptr<gkfs::metadata::Metadata> md = nullptr;
    // metadata object filled during create or stat
    gkfs::metadata::Metadata md{};
    if(flags & O_CREAT) {
        if(flags & O_DIRECTORY) {
            LOG(ERROR, "O_DIRECTORY use with O_CREAT. NOT SUPPORTED");
@@ -139,7 +139,14 @@ gkfs_open(const std::string& path, mode_t mode, int flags) {
                }
                // file exists, O_CREAT was set O_EXCL wasnt, so function does
                // not fail this case is actually undefined as per `man 2 open`
                md = gkfs::util::get_metadata(path);
                auto md_ = gkfs::util::get_metadata(path);
                if(!md_) {
                    LOG(ERROR,
                        "Could not get metadata after creating file '{}': '{}'",
                        path, strerror(errno));
                    return -1;
                }
                md = md_.value();
            } else {
                LOG(ERROR, "Error creating file: '{}'", strerror(errno));
                return -1;
@@ -150,40 +157,40 @@ gkfs_open(const std::string& path, mode_t mode, int flags) {
                    std::make_shared<gkfs::filemap::OpenFile>(path, flags));
        }
    } else {
        md = gkfs::util::get_metadata(path);
        if(!md) {
        auto md_ = gkfs::util::get_metadata(path);
        if(!md_) {
            if(errno == ENOENT) {
                // file doesn't exists and O_CREAT was not set
                return -1;
            } else {
                LOG(ERROR, "Error stating existing file");
                LOG(ERROR, "Error stating existing file '{}'", path);
                return -1;
            }
        }
        md = md_.value();
    }
    assert(md);

#ifdef HAS_SYMLINKS
    if(md->is_link()) {
    if(md.is_link()) {
        if(flags & O_NOFOLLOW) {
            LOG(WARNING, "Symlink found and O_NOFOLLOW flag was specified");
            errno = ELOOP;
            return -1;
        }
        return gkfs_open(md->target_path(), mode, flags);
        return gkfs_open(md.target_path(), mode, flags);
    }
#endif

    if(S_ISDIR(md->mode())) {
    if(S_ISDIR(md.mode())) {
        return gkfs_opendir(path);
    }


    /*** Regular file exists ***/
    assert(S_ISREG(md->mode()));
    assert(S_ISREG(md.mode()));

    if((flags & O_TRUNC) && ((flags & O_RDWR) || (flags & O_WRONLY))) {
        if(gkfs_truncate(path, md->size(), 0)) {
        if(gkfs_truncate(path, md.size(), 0)) {
            LOG(ERROR, "Error truncating file");
            return -1;
        }
@@ -247,8 +254,10 @@ gkfs_remove(const std::string& path) {
    if(!md) {
        return -1;
    }
    bool has_data = S_ISREG(md->mode()) && (md->size() != 0);
    auto err = gkfs::rpc::forward_remove(path, !has_data, md->size());
    gkfs::metadata::Metadata md{attr.value()};

    bool has_data = S_ISREG(md.mode()) && (md.size() != 0);
    auto err = gkfs::rpc::forward_remove(path, !has_data, md.size());
    if(err) {
        errno = err;
        return -1;
@@ -268,7 +277,6 @@ int
gkfs_access(const std::string& path, const int mask, bool follow_links) {
    auto md = gkfs::util::get_metadata(path, follow_links);
    if(!md) {
        errno = ENOENT;
        return -1;
    }
    return 0;
@@ -288,7 +296,7 @@ gkfs_stat(const string& path, struct stat* buf, bool follow_links) {
    if(!md) {
        return -1;
    }
    gkfs::util::metadata_to_stat(path, *md, *buf);
    gkfs::util::metadata_to_stat(path, md.value(), *buf);
    return 0;
}

@@ -315,7 +323,7 @@ gkfs_statx(int dirfs, const std::string& path, int flags, unsigned int mask,

    struct stat tmp {};

    gkfs::util::metadata_to_stat(path, *md, tmp);
    gkfs::util::metadata_to_stat(path, md.value(), tmp);

    buf->stx_mask = 0;
    buf->stx_blksize = tmp.st_blksize;
@@ -539,7 +547,8 @@ gkfs_truncate(const std::string& path, off_t length) {
    if(!md) {
        return -1;
    }
    auto size = md->size();

    auto size = md.value().size();
    if(static_cast<unsigned long>(length) > size) {
        LOG(DEBUG, "Length is greater then file size: {} > {}", length, size);
        errno = EINVAL;
@@ -852,12 +861,12 @@ gkfs_pread_ws(int fd, void* buf, size_t count, off64_t offset) {
 */
int
gkfs_opendir(const std::string& path) {

    auto md = gkfs::util::get_metadata(path);
    if(!md) {
        return -1;
    }
    if(!S_ISDIR(md->mode())) {

    if(!S_ISDIR(md.value().mode())) {
        LOG(DEBUG, "Path is not a directory");
        errno = ENOTDIR;
        return -1;
@@ -883,11 +892,10 @@ int
gkfs_rmdir(const std::string& path) {
    auto md = gkfs::util::get_metadata(path);
    if(!md) {
        LOG(DEBUG, "Path '{}' does not exist: ", path);
        errno = ENOENT;
        LOG(DEBUG, "Error: Path '{}' err code '{}' ", path, strerror(errno));
        return -1;
    }
    if(!S_ISDIR(md->mode())) {
    if(!S_ISDIR(md.value().mode())) {
        LOG(DEBUG, "Path '{}' is not a directory", path);
        errno = ENOTDIR;
        return -1;
@@ -1079,8 +1087,8 @@ gkfs_mk_symlink(const std::string& path, const std::string& target_path) {
     *  So that application know we don't support link to directory.
     */
    auto target_md = gkfs::util::get_metadata(target_path, false);
    if(target_md != nullptr) {
        auto trg_mode = target_md->mode();
    if(target_md) {
        auto trg_mode = target_md.value().mode();
        if(!(S_ISREG(trg_mode) || S_ISLNK(trg_mode))) {
            assert(S_ISDIR(trg_mode));
            LOG(DEBUG, "Target path is a directory. Not supported");
@@ -1094,11 +1102,12 @@ gkfs_mk_symlink(const std::string& path, const std::string& target_path) {
    }

    auto link_md = gkfs::util::get_metadata(path, false);
    if(link_md != nullptr) {
    if(link_md) {
        LOG(DEBUG, "Link exists: '{}'", path);
        errno = EEXIST;
        return -1;
    }

    auto err = gkfs::rpc::forward_mk_symlink(path, target_path);
    if(err) {
        errno = err;
@@ -1121,25 +1130,25 @@ gkfs_mk_symlink(const std::string& path, const std::string& target_path) {
int
gkfs_readlink(const std::string& path, char* buf, int bufsize) {
    auto md = gkfs::util::get_metadata(path, false);
    if(md == nullptr) {
    if(!md) {
        LOG(DEBUG, "Named link doesn't exist");
        return -1;
    }
    if(!(md->is_link())) {
    if(!(md.value().is_link())) {
        LOG(DEBUG, "The named file is not a symbolic link");
        errno = EINVAL;
        return -1;
    }
    int path_size = md->target_path().size() + CTX->mountdir().size();
    int path_size = md.value().target_path().size() + CTX->mountdir().size();
    if(path_size >= bufsize) {
        LOG(WARNING, "Destination buffer size is too short: {} < {}, {} ",
            bufsize, path_size, md->target_path());
            bufsize, path_size, md.value().target_path());
        errno = ENAMETOOLONG;
        return -1;
    }

    CTX->mountdir().copy(buf, CTX->mountdir().size());
    std::strcpy(buf + CTX->mountdir().size(), md->target_path().c_str());
    std::strcpy(buf + CTX->mountdir().size(), md.value().target_path().c_str());
    return path_size;
}

+5 −4
Original line number Diff line number Diff line
@@ -615,11 +615,12 @@ hook_chdir(const char* path) {
    if(internal) {
        // path falls in our namespace
        auto md = gkfs::util::get_metadata(rel_path);
        if(md == nullptr) {
            LOG(ERROR, "{}() path does not exists", __func__);
            return -ENOENT;
        if(!md) {
            LOG(ERROR, "{}() path {} errno {}", __func__, path, errno);
            return -errno;
        }
        if(!S_ISDIR(md->mode())) {

        if(!S_ISDIR(md.value().mode())) {
            LOG(ERROR, "{}() path is not a directory", __func__);
            return -ENOTDIR;
        }
+8 −6
Original line number Diff line number Diff line
@@ -165,20 +165,21 @@ load_hostfile(const std::string& path) {

namespace gkfs::util {


/**
 * Retrieve metadata from daemon
 * Retrieve metadata from daemon and return Metadata object
 * errno may be set
 * @param path
 * @param follow_links
 * @return shared_ptr for metadata, nullptr else
 * @return Metadata
 */
std::shared_ptr<gkfs::metadata::Metadata>
optional<gkfs::metadata::Metadata>
get_metadata(const string& path, bool follow_links) {
    std::string attr;
    auto err = gkfs::rpc::forward_stat(path, attr);
    if(err) {
        errno = err;
        return nullptr;
        return {};
    }
#ifdef HAS_SYMLINKS
    if(follow_links) {
@@ -187,15 +188,16 @@ get_metadata(const string& path, bool follow_links) {
            err = gkfs::rpc::forward_stat(md.target_path(), attr);
            if(err) {
                errno = err;
                return nullptr;
                return {};
            }
            md = gkfs::metadata::Metadata{attr};
        }
    }
#endif
    return make_shared<gkfs::metadata::Metadata>(attr);
    return gkfs::metadata::Metadata{attr};
}


/**
 * Converts the Metadata object into a stat struct, which is needed by Linux
 * @param path