Commit 1aae0185 authored by Marc Vef's avatar Marc Vef
Browse files

Local disk I/O without chunks finished

parent 78470a2c
Loading
Loading
Loading
Loading
+53 −0
Original line number Diff line number Diff line
@@ -10,6 +10,59 @@

using namespace std;

/**
 * Reads a specific metadata field from the database and puts it into the corresponding metadata object
 * @tparam T
 * @param inode
 * @param field
 * @return type, 0 might mean failure
 */
void read_metadata_field_md(const fuse_ino_t inode, const Md_fields field, Metadata& md) {
    // XXX I am sure this can be implemented in a better way
    switch (field) {
        case Md_fields::atime:
            md.atime(db_get_mdata<time_t>(
                    db_build_mdata_key(inode, std::get<to_underlying(Md_fields::atime)>(md_field_map))));
            break;
        case Md_fields::mtime:
            md.mtime(db_get_mdata<time_t>(
                    db_build_mdata_key(inode, std::get<to_underlying(Md_fields::mtime)>(md_field_map))));
            break;
        case Md_fields::ctime:
            md.ctime(db_get_mdata<time_t>(
                    db_build_mdata_key(inode, std::get<to_underlying(Md_fields::ctime)>(md_field_map))));
            break;
        case Md_fields::uid:
            md.uid(db_get_mdata<uid_t>(
                    db_build_mdata_key(inode, std::get<to_underlying(Md_fields::uid)>(md_field_map))));
            break;
        case Md_fields::gid:
            md.gid(db_get_mdata<gid_t>(
                    db_build_mdata_key(inode, std::get<to_underlying(Md_fields::gid)>(md_field_map))));
            break;
        case Md_fields::mode:
            md.mode(db_get_mdata<mode_t>(
                    db_build_mdata_key(inode, std::get<to_underlying(Md_fields::mode)>(md_field_map))));
            break;
        case Md_fields::inode_no:
            md.inode_no(db_get_mdata<fuse_ino_t>(
                    db_build_mdata_key(inode, std::get<to_underlying(Md_fields::inode_no)>(md_field_map))));
            break;
        case Md_fields::link_count:
            md.link_count(db_get_mdata<nlink_t>(
                    db_build_mdata_key(inode, std::get<to_underlying(Md_fields::link_count)>(md_field_map))));
            break;
        case Md_fields::size:
            md.size(db_get_mdata<off_t>(
                    db_build_mdata_key(inode, std::get<to_underlying(Md_fields::size)>(md_field_map))));
            break;
        case Md_fields::blocks:
            md.blocks(db_get_mdata<blkcnt_t>(
                    db_build_mdata_key(inode, std::get<to_underlying(Md_fields::blocks)>(md_field_map))));
            break;
    }
}

int write_all_metadata(const Metadata& md) {
    auto inode_key = fmt::FormatInt(md.inode_no()).str();
    // TODO this should be somewhat a batch operation or similar. this errorhandling is bs
+16 −13
Original line number Diff line number Diff line
@@ -14,14 +14,14 @@
using namespace std;

/**
 * Reads a specific metadata field to the database
 * Reads a specific metadata field from the database and returns it
 * @tparam T
 * @param inode
 * @param field
 * @return type, 0 might mean failure
 */
template<typename T>
decltype(auto) read_metadata_field(const fuse_ino_t inode, Md_fields field) {
decltype(auto) read_metadata_field(const fuse_ino_t inode, const Md_fields field) {
    // XXX I am sure this can be implemented in a better way
    switch (field) {
        case Md_fields::atime:
@@ -50,6 +50,8 @@ decltype(auto) read_metadata_field(const fuse_ino_t inode, Md_fields field) {

}

void read_metadata_field_md(const fuse_ino_t inode, const Md_fields field, Metadata& md);

/**
 * writes a specific metadata field to the database
 * @tparam T
@@ -59,40 +61,41 @@ decltype(auto) read_metadata_field(const fuse_ino_t inode, Md_fields field) {
 * @return bool - success
 */
template<typename T>
bool write_metadata_field(const fuse_ino_t inode, const Md_fields field, Metadata& md) {
bool write_metadata_field(const fuse_ino_t inode, const Md_fields field, const T val) {
    // XXX I am sure this can be implemented in a better way
    switch (field) {
        case Md_fields::atime:
            return db_put_mdata(db_build_mdata_key(inode, std::get<to_underlying(Md_fields::atime)>(md_field_map)),
                                md.atime());
                                val);
        case Md_fields::mtime:
            return db_put_mdata(db_build_mdata_key(inode, std::get<to_underlying(Md_fields::mtime)>(md_field_map)),
                                md.mtime());
                                val);
        case Md_fields::ctime:
            return db_put_mdata(db_build_mdata_key(inode, std::get<to_underlying(Md_fields::ctime)>(md_field_map)),
                                md.ctime());
                                val);
        case Md_fields::uid:
            return db_put_mdata(db_build_mdata_key(inode, std::get<to_underlying(Md_fields::uid)>(md_field_map)),
                                md.uid());
                                val);
        case Md_fields::gid:
            return db_put_mdata(db_build_mdata_key(inode, std::get<to_underlying(Md_fields::gid)>(md_field_map)),
                                md.gid());
                                val);
        case Md_fields::mode:
            return db_put_mdata(db_build_mdata_key(inode, std::get<to_underlying(Md_fields::mode)>(md_field_map)),
                                md.mode());
                                val);
        case Md_fields::inode_no:
            return db_put_mdata(db_build_mdata_key(inode, std::get<to_underlying(Md_fields::inode_no)>(md_field_map)),
                                md.inode_no());
                                val);
        case Md_fields::link_count:
            return db_put_mdata(db_build_mdata_key(inode, std::get<to_underlying(Md_fields::link_count)>(md_field_map)),
                                md.link_count());
                                val);
        case Md_fields::size:
            return db_put_mdata(db_build_mdata_key(inode, std::get<to_underlying(Md_fields::size)>(md_field_map)),
                                md.size());
                                val);
        case Md_fields::blocks:
            return db_put_mdata(db_build_mdata_key(inode, std::get<to_underlying(Md_fields::blocks)>(md_field_map)),
                                md.blocks());
                                val);
    }
    return false; // never reached... compiler complains if left out
}


+20 −16
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
#include "../main.hpp"
#include "../fuse_ops.hpp"
#include "../db/db_ops.hpp"
#include "../adafs_ops/mdata_ops.hpp"

using namespace std;

@@ -50,8 +51,7 @@ void adafs_ll_read(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struc
    char* buf = new char[size]();

    auto read_size = static_cast<size_t>(pread(fd, buf, size, off));
//    snprintf(buf, size + 1, buf);
    ADAFS_DATA->spdlogger()->debug("Read the following buf {} wtf", buf);
    ADAFS_DATA->spdlogger()->trace("Read the following buf: {}", buf);

    fuse_reply_buf(req, buf, read_size);

@@ -88,7 +88,8 @@ void adafs_ll_read(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struc
 */
void
adafs_ll_write(fuse_req_t req, fuse_ino_t ino, const char* buf, size_t size, off_t off, struct fuse_file_info* fi) {
    ADAFS_DATA->spdlogger()->info("adafs_ll_write() enter: inode {} size {} offset {} buf {} O_APPEND", ino, size, off,
    ADAFS_DATA->spdlogger()->debug("adafs_ll_write() enter: inode {} size {} offset {} buf {} O_APPEND {}", ino, size,
                                   off,
                                   buf, fi->flags & O_APPEND);
    // TODO Check out how splicing works. This uses the function write_buf then.
    auto chnk_path = bfs::path(ADAFS_DATA->chunk_path());
@@ -101,20 +102,23 @@ adafs_ll_write(fuse_req_t req, fuse_ino_t ino, const char* buf, size_t size, off
        fuse_reply_err(req, EIO);
        return;
    }

    // write to disk
    pwrite(fd, buf, size, off);
    // XXX the metadata size needs to be correct in the metadata. otherwise it won't read the data...
    db_put_mdata(db_build_mdata_key(ino, std::get<to_underlying(Md_fields::size)>(md_field_map)), size);
    // Set new size of the file
//    if (fi->flags & O_APPEND) {
//        truncate(chnk_path.c_str(), md->size() + size);
//        md->size(md->size() + static_cast<uint32_t>(size));
//    } else {
//        truncate(chnk_path.c_str(), size);
//        md->size(static_cast<uint32_t>(size));
//    }

    close(fd);
    // Set new size of the file
    if (fi->flags & O_APPEND) {
        // appending requires to read the old size first so that the new size can be added to it
        Metadata md{};
        read_metadata_field_md(ino, Md_fields::size, md);
        // truncating file
        truncate(chnk_path.c_str(), md.size() + size);
        // refresh metadata size field
        write_metadata_field(ino, Md_fields::size, md.size() + static_cast<off_t>(size));
    } else {
        truncate(chnk_path.c_str(), size);
        write_metadata_field(ino, Md_fields::size, static_cast<off_t>(size));
    }

    fuse_reply_write(req, size);
    close(fd);
}