Commit abd2dffe authored by Marc Vef's avatar Marc Vef
Browse files

dentries now handled by rocksdb. using strings instead of c_strings

parent 6f045044
Loading
Loading
Loading
Loading
+49 −9
Original line number Diff line number Diff line
@@ -4,10 +4,11 @@

#include "db_ops.hpp"


using namespace rocksdb;
using namespace std;

inline const string db_get_mdata_helper(const char* key) {
inline const string db_get_mdata_helper(const string& key) {
    auto db = ADAFS_DATA->rdb().get();
    string val_str;
    db->Get(ReadOptions(), key, &val_str);
@@ -15,28 +16,67 @@ inline const string db_get_mdata_helper(const char* key) {
}

template<>
unsigned long db_get_mdata<unsigned long>(const char* key) {
unsigned long db_get_mdata<unsigned long>(const string& key) {
    return stoul(db_get_mdata_helper(key));
}

template<>
long db_get_mdata<long>(const char* key) {
long db_get_mdata<long>(const string& key) {
    return stol(db_get_mdata_helper(key));
}

template<>
unsigned int db_get_mdata<unsigned int>(const char* key) {
unsigned int db_get_mdata<unsigned int>(const string& key) {
    return static_cast<unsigned int>(stoul(db_get_mdata_helper(key)));
}

bool db_dentry_exists(const char* key) {
//    auto db = ADAFS_DATA->rdb().get();
    //TODO
    return true;
bool db_dentry_exists(const fuse_ino_t p_inode, const string& name, string& val) {
    auto db = ADAFS_DATA->rdb().get();
    auto key = fmt::FormatInt(p_inode).str() + "_d_" + name;
    return db->Get(rocksdb::ReadOptions(), key, &val).ok();
}

bool db_mdata_exists(const char* key) {
bool db_mdata_exists(const string& key) {
    auto db = ADAFS_DATA->rdb().get();
    string val_str;
    return db->Get(ReadOptions(), key, &val_str).ok();
}

bool db_put_dentry(const string& key, const string& val) {
    auto db = ADAFS_DATA->rdb().get();
    return db->Put(rocksdb::WriteOptions(), key, val).ok();
}

void db_get_dentries(vector<Dentry>& dentries, const fuse_ino_t dir_inode) {
    string key;
    string val;
    size_t pos;
    auto delim = "_"s;
    auto db = ADAFS_DATA->rdb();
    auto prefix = fmt::FormatInt(dir_inode).str() + "_d"s;
    // Do RangeScan on parent inode
    auto dentry_iter = db->NewIterator(rocksdb::ReadOptions());
    for (dentry_iter->Seek(prefix);
         dentry_iter->Valid() && dentry_iter->key().starts_with(prefix); dentry_iter->Next()) {
        key = dentry_iter->key().ToString();
        val = dentry_iter->value().ToString();

        // Retrieve filename from key
        pos = key.find(delim); // Split <ParentInode_d_filename> by _
        key.erase(0, pos + 3); // Erase ParentInode + _d_
        Dentry dentry{key}; // key holds only filename

        // Retrieve inode and mode from val
        pos = val.find(delim); // Split <inode_mode> by _
        dentry.inode(static_cast<fuse_ino_t>(stoul(val.substr(0, pos)))); // Substring from 0 to pos holds inode
        val.erase(0, pos + 1); // Erase inode + delim
        dentry.mode(static_cast<mode_t>(stoul(val))); // val holds only mode
        // append dentry to dentries vector
        ADAFS_DATA->spdlogger()->info("Retrieved dentry: name {} inode {} mode {}", dentry.name(), dentry.inode(),
                                      dentry.mode());
        dentries.push_back(dentry);
    }
}


+10 −3
Original line number Diff line number Diff line
@@ -6,17 +6,24 @@
#define LFS_DB_OPS_HPP

#include "../main.hpp"
#include "../classes/dentry.h"

template<typename T>
bool db_put_mdata(const char* key, const T val) {
bool db_put_mdata(const std::string& key, const T val) {
    auto db = ADAFS_DATA->rdb().get();
    auto val_str = fmt::FormatInt(val).c_str();
    return db->Put(rocksdb::WriteOptions(), key, val_str).ok();
}

template<typename T>
T db_get_mdata(const char* key);
T db_get_mdata(const std::string& key);

bool db_mdata_exists(const char* key);
bool db_dentry_exists(const fuse_ino_t p_inode, const std::string& name, std::string& val);

bool db_mdata_exists(const std::string& key);

bool db_put_dentry(const std::string& key, const std::string& val);

void db_get_dentries(std::vector<Dentry>& dentries, const fuse_ino_t dir_inode);

#endif //LFS_DB_OPS_HPP
+13 −57
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include "dentry_ops.hpp"
#include "db_ops.hpp"

#include "../classes/dentry.h"

@@ -90,35 +91,11 @@ int read_dentries(const fuse_ino_t p_inode, const fuse_ino_t inode) {
 * cleared before it is used.
 * @param dentries assumed to be empty
 * @param dir_inode
 * @return
 */
int get_dentries(vector<Dentry>& dentries, const fuse_ino_t dir_inode) {
    ADAFS_DATA->spdlogger()->debug("get_dentries: inode {}", dir_inode);
    auto d_path = bfs::path(ADAFS_DATA->dentry_path());
    d_path /= fmt::FormatInt(dir_inode).c_str();
    // shortcut if path is empty = no files in directory
    if (bfs::is_empty(d_path)) return 0;

    auto dir_it = bfs::directory_iterator(d_path);
    for (const auto& it : dir_it) {
        auto dentry = make_shared<Dentry>(it.path().filename().string());
        // retrieve inode number and mode in dentry
        uint64_t inode;
        mode_t mode;
        d_path /= it.path().filename();
        bfs::ifstream ifs{d_path};
        boost::archive::binary_iarchive ba(ifs);
        ba >> inode;
        ba >> mode;
        dentry->inode(inode);
        dentry->mode(mode);
        // append dentry to dentries vector
        dentries.push_back(*dentry);
        d_path.remove_filename();
void get_dentries(vector<Dentry>& dentries, const fuse_ino_t dir_inode) {
    db_get_dentries(dentries, dir_inode);
}

    return 0;
}

/**
 * Gets the inode of a directory entry
@@ -128,21 +105,13 @@ int get_dentries(vector<Dentry>& dentries, const fuse_ino_t dir_inode) {
 * @return pair<err, inode>
 */
pair<int, fuse_ino_t> do_lookup(fuse_req_t& req, const fuse_ino_t p_inode, const string& name) {

    fuse_ino_t inode;
    // XXX error handling
    // TODO look into cache first
    auto d_path = bfs::path(ADAFS_DATA->dentry_path());
    d_path /= fmt::FormatInt(p_inode).c_str();
    // XXX check if this is needed later
    d_path /= name;
    if (!bfs::exists(d_path))
    string val; // will we filled by dentry exist check
    if (db_dentry_exists(p_inode, name, val) == 0) { // dentry NOT found
        return make_pair(ENOENT, INVALID_INODE);
    }

    bfs::ifstream ifs{d_path};
    //read inode from disk
    boost::archive::binary_iarchive ba(ifs);
    ba >> inode;
    auto pos = val.find("_");
    auto inode = static_cast<fuse_ino_t>(stoul(val.substr(0, pos)));

    return make_pair(0, inode);
}
@@ -155,24 +124,11 @@ pair<int, fuse_ino_t> do_lookup(fuse_req_t& req, const fuse_ino_t p_inode, const
 * @return
 */
int create_dentry(const fuse_ino_t p_inode, const fuse_ino_t inode, const string& name, mode_t mode) {
//    ADAFS_DATA->logger->debug("create_dentry() enter with fname: {}", inode);
    // XXX Errorhandling
    auto d_path = bfs::path(ADAFS_DATA->dentry_path());
    d_path /= fmt::FormatInt(p_inode).c_str();
    // XXX check if this is needed later
//    if (!bfs::exists(d_path)) return -ENOENT;

    d_path /= name;

    bfs::ofstream ofs{d_path};
    // write to disk in binary form
    boost::archive::binary_oarchive ba(ofs);
    ba << inode;
    ba << mode;

    // XXX make sure the file has been created

    return 0;
    auto key = fmt::FormatInt(p_inode).str() + "_d_" + name;
    auto val = fmt::FormatInt(inode).str() + "_" + fmt::FormatInt(mode).str();
    // XXX check later if we need to check if dentry of father already exists
    return db_put_dentry(key, val);
}

/**
+1 −1
Original line number Diff line number Diff line
@@ -17,7 +17,7 @@ bool verify_dentry(const fuse_ino_t inode);

int read_dentries(const fuse_ino_t p_inode, const fuse_ino_t inode);

int get_dentries(std::vector<Dentry>& dentries, const fuse_ino_t dir_inode);
void get_dentries(std::vector<Dentry>& dentries, const fuse_ino_t dir_inode);

std::pair<int, fuse_ino_t> do_lookup(fuse_req_t& req, const fuse_ino_t p_inode, const std::string& name);

+20 −23
Original line number Diff line number Diff line
@@ -11,16 +11,16 @@
bool write_all_metadata(const Metadata& md, const fuse_ino_t inode) {
    auto inode_key = fmt::FormatInt(inode).str();

    db_put_mdata((inode_key + "atime"s).c_str(), md.atime());
    db_put_mdata((inode_key + "mtime"s).c_str(), md.mtime());
    db_put_mdata((inode_key + "ctime"s).c_str(), md.ctime());
    db_put_mdata((inode_key + "uid"s).c_str(), md.uid());
    db_put_mdata((inode_key + "gid"s).c_str(), md.gid());
    db_put_mdata((inode_key + "mode"s).c_str(), md.mode());
    db_put_mdata((inode_key + "inodeno"s).c_str(), md.inode_no());
    db_put_mdata((inode_key + "linkcnt"s).c_str(), md.link_count());
    db_put_mdata((inode_key + "size"s).c_str(), md.size());
    db_put_mdata((inode_key + "blocks"s).c_str(), md.blocks());
    db_put_mdata(inode_key + "atime"s, md.atime());
    db_put_mdata(inode_key + "mtime"s, md.mtime());
    db_put_mdata(inode_key + "ctime"s, md.ctime());
    db_put_mdata(inode_key + "uid"s, md.uid());
    db_put_mdata(inode_key + "gid"s, md.gid());
    db_put_mdata(inode_key + "mode"s, md.mode());
    db_put_mdata(inode_key + "inodeno"s, md.inode_no());
    db_put_mdata(inode_key + "linkcnt"s, md.link_count());
    db_put_mdata(inode_key + "size"s, md.size());
    db_put_mdata(inode_key + "blocks"s, md.blocks());
    return true;
}

@@ -28,16 +28,16 @@ bool write_all_metadata(const Metadata& md, const fuse_ino_t inode) {
bool read_all_metadata(Metadata& md, const fuse_ino_t inode) {
    auto inode_key = fmt::FormatInt(inode).str();

    md.atime(db_get_mdata<time_t>((inode_key + "atime"s).c_str()));
    md.mtime(db_get_mdata<time_t>((inode_key + "mtime"s).c_str()));
    md.ctime(db_get_mdata<time_t>((inode_key + "ctime"s).c_str()));
    md.uid(db_get_mdata<uid_t>((inode_key + "uid"s).c_str()));
    md.gid(db_get_mdata<gid_t>((inode_key + "gid"s).c_str()));
    md.mode(db_get_mdata<mode_t>((inode_key + "mode"s).c_str()));
    md.inode_no(db_get_mdata<fuse_ino_t>((inode_key + "inodeno"s).c_str()));
    md.link_count(db_get_mdata<nlink_t>((inode_key + "linkcnt"s).c_str()));
    md.size(db_get_mdata<off_t>((inode_key + "size"s).c_str()));
    md.blocks(db_get_mdata<blkcnt_t>((inode_key + "blocks"s).c_str()));
    md.atime(db_get_mdata<time_t>(inode_key + "atime"s));
    md.mtime(db_get_mdata<time_t>(inode_key + "mtime"s));
    md.ctime(db_get_mdata<time_t>(inode_key + "ctime"s));
    md.uid(db_get_mdata<uid_t>(inode_key + "uid"s));
    md.gid(db_get_mdata<gid_t>(inode_key + "gid"s));
    md.mode(db_get_mdata<mode_t>(inode_key + "mode"s));
    md.inode_no(db_get_mdata<fuse_ino_t>(inode_key + "inodeno"s));
    md.link_count(db_get_mdata<nlink_t>(inode_key + "linkcnt"s));
    md.size(db_get_mdata<off_t>(inode_key + "size"s));
    md.blocks(db_get_mdata<blkcnt_t>(inode_key + "blocks"s));
    return true;
}

@@ -50,9 +50,6 @@ bool read_all_metadata(Metadata& md, const fuse_ino_t inode) {
int get_metadata(Metadata& md, const fuse_ino_t inode) {
    ADAFS_DATA->spdlogger()->debug("get_metadata() enter for inode {}", inode);
    // Verify that the file's inode exists
    auto path = bfs::path(ADAFS_DATA->inode_path());
    path /= fmt::FormatInt(inode).c_str();
    // TODO CHECK FOR DENTRY INSTEAD and remove the db_mdata_exists function!
    if (db_mdata_exists((fmt::FormatInt(inode).str() + "mtime"s).c_str())) {
        read_all_metadata(md, inode);
        return 0;
Loading