Commit 96ee41af authored by Marc Vef's avatar Marc Vef
Browse files

getattr() implemented, read and write metadata is back online, major...

getattr() implemented, read and write metadata is back online, major restructuring of how the userdata is accessed.
File system paths are now accessible from anywhere without fuse_req_t being required. Fields might become somewhat const in the future.
spdlogger is now available systemwide.
parent 00e69aaf
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -19,6 +19,14 @@ find_package(FUSE3 REQUIRED)
find_package(Boost 1.56.0 COMPONENTS system filesystem serialization)

include_directories(${FUSE3_INCLUDE_DIR} include/)
set(SOURCE_FILES src/main.cpp src/main.h src/fuse_ops.h src/classes/metadata.h src/classes/metadata.cpp src/util.cpp src/fuse_ops/file.cpp)
set(SOURCE_FILES src/main.cpp src/main.h src/fuse_ops.h src/configure.h
        src/classes/metadata.h src/classes/metadata.cpp
        src/adafs_ops/metadata_ops.h #src/adafs_ops/dentry_ops.h

        src/util.cpp
        src/fuse_ops/file.cpp src/fuse_ops/directory.cpp
        src/adafs_ops/metadata_ops.cpp #src/adafs_ops/dentry_ops.cpp

        )
add_executable(adafs ${SOURCE_FILES} src/main.cpp)
target_link_libraries(adafs ${FUSE3_LIBRARIES} -lpthread -lboost_system -lboost_filesystem -lboost_serialization -pg)
 No newline at end of file
+60 −59
Original line number Diff line number Diff line
@@ -9,31 +9,29 @@
#include <boost/archive/binary_oarchive.hpp>

// TODO error handling. Each read_metadata_field should check for boolean, i.e., if I/O failed.
bool write_all_metadata(const Metadata& md, const unsigned long hash) {
    write_metadata_field(md.atime(), hash, md_field_map.at(Md_fields::atime));
    write_metadata_field(md.mtime(), hash, md_field_map.at(Md_fields::mtime));
    write_metadata_field(md.ctime(), hash, md_field_map.at(Md_fields::ctime));
    write_metadata_field(md.uid(), hash, md_field_map.at(Md_fields::uid));
    write_metadata_field(md.gid(), hash, md_field_map.at(Md_fields::gid));
    write_metadata_field(md.mode(), hash, md_field_map.at(Md_fields::mode));
    write_metadata_field(md.inode_no(), hash, md_field_map.at(Md_fields::inode_no));
    write_metadata_field(md.link_count(), hash, md_field_map.at(Md_fields::link_count));
    write_metadata_field(md.size(), hash, md_field_map.at(Md_fields::size));
    write_metadata_field(md.blocks(), hash, md_field_map.at(Md_fields::blocks));
bool write_all_metadata(const Metadata& md, const uint64_t inode) {
    write_metadata_field(md.atime(), md_field_map.at(Md_fields::atime), inode);
    write_metadata_field(md.mtime(), md_field_map.at(Md_fields::mtime), inode);
    write_metadata_field(md.ctime(), md_field_map.at(Md_fields::ctime), inode);
    write_metadata_field(md.uid(), md_field_map.at(Md_fields::uid), inode);
    write_metadata_field(md.gid(), md_field_map.at(Md_fields::gid), inode);
    write_metadata_field(md.mode(), md_field_map.at(Md_fields::mode), inode);
    write_metadata_field(md.inode_no(), md_field_map.at(Md_fields::inode_no), inode);
    write_metadata_field(md.link_count(), md_field_map.at(Md_fields::link_count), inode);
    write_metadata_field(md.size(), md_field_map.at(Md_fields::size), inode);
    write_metadata_field(md.blocks(), md_field_map.at(Md_fields::blocks), inode);

    return true;
}

// TODO error handling.
template<typename T>
bool write_metadata_field(const T& field, const unsigned long hash, const string& leaf_name) {
    auto i_path = bfs::path(ADAFS_DATA->inode_path);
    i_path /= to_string(hash);
bool write_metadata_field(const T& field, const string& field_name, const uint64_t inode) {
    auto i_path = bfs::path(Fs_paths::inode_path);
    i_path /= to_string(inode);
    bfs::create_directories(i_path);
    i_path /= field_name;

    i_path /= leaf_name;
    // for some reason auto ofs = bfs::ofstream(file); does not work. That is why I use the old style.
    // std::basic_ofstream does not encounter this problem
    bfs::ofstream ofs{i_path};
    // write to disk in binary form
    boost::archive::binary_oarchive ba(ofs);
@@ -43,26 +41,26 @@ bool write_metadata_field(const T& field, const unsigned long hash, const string
}

// TODO error handling. Each read_metadata_field should check for nullptr, i.e., if I/O failed.
bool read_all_metadata(Metadata& md, const unsigned long hash) {
    md.atime(*read_metadata_field<time_t>(hash, md_field_map.at(Md_fields::atime)));
    md.mtime(*read_metadata_field<time_t>(hash, md_field_map.at(Md_fields::mtime)));
    md.ctime(*read_metadata_field<time_t>(hash, md_field_map.at(Md_fields::ctime)));
    md.uid(*read_metadata_field<uint32_t>(hash, md_field_map.at(Md_fields::uid)));
    md.gid(*read_metadata_field<uint32_t>(hash, md_field_map.at(Md_fields::gid)));
    md.mode(*read_metadata_field<uint32_t>(hash, md_field_map.at(Md_fields::mode)));
    md.inode_no(*read_metadata_field<uint64_t>(hash, md_field_map.at(Md_fields::inode_no)));
    md.link_count(*read_metadata_field<uint32_t>(hash, md_field_map.at(Md_fields::link_count)));
    md.size(*read_metadata_field<uint32_t>(hash, md_field_map.at(Md_fields::size)));
    md.blocks(*read_metadata_field<uint32_t>(hash, md_field_map.at(Md_fields::blocks)));
bool read_all_metadata(Metadata& md, const uint64_t inode) {
    md.atime(*read_metadata_field<time_t>(md_field_map.at(Md_fields::atime), inode));
    md.mtime(*read_metadata_field<time_t>(md_field_map.at(Md_fields::mtime), inode));
    md.ctime(*read_metadata_field<time_t>(md_field_map.at(Md_fields::ctime), inode));
    md.uid(*read_metadata_field<uint32_t>(md_field_map.at(Md_fields::uid), inode));
    md.gid(*read_metadata_field<uint32_t>(md_field_map.at(Md_fields::gid), inode));
    md.mode(*read_metadata_field<uint32_t>(md_field_map.at(Md_fields::mode), inode));
    md.inode_no(*read_metadata_field<uint64_t>(md_field_map.at(Md_fields::inode_no), inode));
    md.link_count(*read_metadata_field<uint32_t>(md_field_map.at(Md_fields::link_count), inode));
    md.size(*read_metadata_field<uint32_t>(md_field_map.at(Md_fields::size), inode));
    md.blocks(*read_metadata_field<uint32_t>(md_field_map.at(Md_fields::blocks), inode));
    return true;
}


template<typename T>
unique_ptr<T> read_metadata_field(const unsigned long hash, const string& leaf_name) {
    auto path = bfs::path(ADAFS_DATA->inode_path);
    path /= to_string(hash);
    path /= leaf_name;
unique_ptr<T> read_metadata_field(const string& field_name, const uint64_t inode) {
    auto path = bfs::path(Fs_paths::inode_path);
    path /= to_string(inode);
    path /= field_name;
    if (!bfs::exists(path)) return nullptr;

    bfs::ifstream ifs{path};
@@ -74,20 +72,23 @@ unique_ptr<T> read_metadata_field(const unsigned long hash, const string& leaf_n
    return field;
}

int get_metadata(Metadata& md, const string& path) {
    return get_metadata(md, bfs::path(path));
}

int get_metadata(Metadata& md, const bfs::path& path) {
    ADAFS_DATA->logger->debug("get_metadata() enter for path {}", path.string());
    // Verify that the file is a valid dentry of the parent dir
    if (verify_dentry(path)) {
        // Metadata for file exists
        read_all_metadata(md, ADAFS_DATA->hashf(path.string()));
int get_metadata(Metadata& md, const uint64_t inode) {
    spdlogger->debug("get_metadata() enter for inode {}", inode);
    // Verify that the file is a valid dentry of the parent dir XXX put back in later when we have dentry ops
//    if (verify_dentry(inode)) {
//        // Metadata for file exists
//        read_all_metadata(req, md, ADAFS_DATA->hashf(inode));
//        return 0;
//    } else {
//        return -ENOENT;
//    }
    auto path = bfs::path(Fs_paths::inode_path);
    path /= to_string(inode);
    if (bfs::exists(path)) {
        read_all_metadata(md, inode);
        return 0;
    } else {
        return -ENOENT;
    }
    } else
        return ENOENT;
}

/**
@@ -96,20 +97,20 @@ int get_metadata(Metadata& md, const bfs::path& path) {
 * @return
 */
// XXX Errorhandling
int remove_metadata(const unsigned long hash) {
    auto i_path = bfs::path(ADAFS_DATA->inode_path);
    i_path /= to_string(hash);
    // XXX below could be omitted
    if (!bfs::exists(i_path)) {
        ADAFS_DATA->logger->error("remove_metadata() metadata_path '{}' not found", i_path.string());
        return -ENOENT;
    }

    bfs::remove_all(i_path);
    // XXX make sure metadata has been deleted

    return 0;
}
//int remove_metadata(const unsigned long hash) {
//    auto i_path = bfs::path(ADAFS_DATA->inode_path);
//    i_path /= to_string(hash);
//    // XXX below could be omitted
//    if (!bfs::exists(i_path)) {
//        ADAFS_DATA->spdlogger->error("remove_metadata() metadata_path '{}' not found", i_path.string());
//        return -ENOENT;
//    }
//
//    bfs::remove_all(i_path);
//    // XXX make sure metadata has been deleted
//
//    return 0;
//}



+16 −17
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@ using namespace std;
// mapping of enum to string to get the file names for metadata
enum class Md_fields { atime, mtime, ctime, uid, gid, mode, inode_no, link_count, size, blocks };

// TODO make static so that it is resolved at compile time
const std::map<Md_fields, std::string> md_field_map = {
        {Md_fields::atime,      "/atime"},
        {Md_fields::mtime,      "/mtime"},
@@ -26,20 +27,18 @@ const std::map<Md_fields, std::string> md_field_map = {
        {Md_fields::blocks,     "/blocks"}
};

bool write_all_metadata(const Metadata& md, const unsigned long hash);
bool write_all_metadata(const Metadata& md, const uint64_t inode);

template<typename T>
bool write_metadata_field(const T& field, const unsigned long hash, const string& leaf_name);
bool write_metadata_field(const T& field, const string& field_name, const uint64_t inode);

bool read_all_metadata(Metadata& md, const unsigned long hash);
bool read_all_metadata(Metadata& md, const uint64_t inode);

template<typename T>
unique_ptr<T> read_metadata_field(const unsigned long hash, const string& leaf_name);
unique_ptr<T> read_metadata_field(const string& field_name, const uint64_t inode);

int get_metadata(Metadata& md, const std::string& path);
int get_metadata(Metadata& md, const uint64_t inode);

int get_metadata(Metadata& md, const boost::filesystem::path& path);

int remove_metadata(const unsigned long hash);
//int remove_metadata(const unsigned long hash);

#endif //FS_METADATA_OPS_H
+1 −1
Original line number Diff line number Diff line
@@ -110,7 +110,7 @@ Metadata::Metadata(mode_t mode, uint32_t uid, uint32_t gid, fuse_req_t& req) :
        size_(0),
        blocks_(0) {
    init_ACM_time();
    inode_no_ = util::generate_inode_no(ADAFS_DATA(req)->inode_mutex, ADAFS_DATA(req)->inode_count);
    inode_no_ = Util::generate_inode_no(ADAFS_DATA(req)->inode_mutex, ADAFS_DATA(req)->inode_count);
}

Metadata::Metadata(mode_t mode, uint32_t uid, uint32_t gid, uint64_t inode) :
+1 −1
Original line number Diff line number Diff line
@@ -12,7 +12,7 @@ void adafs_ll_getattr(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info* fi)


// directory

void adafs_ll_lookup(fuse_req_t req, fuse_ino_t parent, const char* name);


// I/O
Loading