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

create() implemented, large infrastructure for readdir (unfinished)

parent 5f14e881
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
# required packages
find_package(FUSE3 REQUIRED)
# boost dependencies, system is required for filesystem #TODO VERSION UNTESTED. I USE 1.62
find_package(Boost 1.62 REQUIRED COMPONENTS system filesystem serialization)
find_package(Boost 1.58 REQUIRED COMPONENTS system filesystem serialization)

include_directories(${FUSE3_INCLUDE_DIR} include/)
set(SOURCE_FILES src/main.cpp src/main.h src/fuse_ops.h src/util.cpp
+2 −2
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
# required packages
find_package(FUSE3 REQUIRED)
# boost dependencies, system is required for filesystem #TODO VERSION UNTESTED. I USE 1.62
find_package(Boost 1.62.0 REQUIRED COMPONENTS system filesystem serialization)
find_package(Boost 1.58 REQUIRED COMPONENTS system filesystem serialization)

include_directories(${FUSE3_INCLUDE_DIR} include/)
set(SOURCE_FILES src/main.cpp src/main.h src/fuse_ops.h src/configure.h
@@ -24,7 +24,7 @@ set(SOURCE_FILES src/main.cpp src/main.h src/fuse_ops.h src/configure.h
        src/adafs_ops/metadata_ops.h src/adafs_ops/dentry_ops.h src/adafs_ops/access.h

        src/util.cpp
        src/fuse_ops/file.cpp src/fuse_ops/directory.cpp
        src/fuse_ops/file.cpp src/fuse_ops/directory.cpp src/fuse_ops/sync.cpp
        src/adafs_ops/metadata_ops.cpp src/adafs_ops/dentry_ops.cpp src/adafs_ops/access.cpp

        )
+49 −12
Original line number Diff line number Diff line
@@ -2,6 +2,8 @@
// Created by evie on 3/17/17.
//

#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include "dentry_ops.h"

using namespace std;
@@ -80,24 +82,59 @@ int read_dentries(const uint64_t p_inode, const unsigned long inode) {
    return 0;
}

/**
 * Gets the inode of a directory entry
 * @param req
 * @param parent_inode
 * @param name
 * @return inode
 */
uint64_t do_lookup(fuse_req_t& req, const uint64_t p_inode, const string& name) {

    uint64_t inode;
    // XXX error handling
    // TODO look into cache first
    auto d_path = bfs::path(ADAFS_DATA->dentry_path());
    d_path /= to_string(p_inode);
    // XXX check if this is needed later
    d_path /= name;

    if (!bfs::exists(d_path))
        return static_cast<uint64_t>(-ENOENT);

    bfs::ifstream ifs{d_path};
    //read inode from disk
    boost::archive::binary_iarchive ba(ifs);
    ba >> inode;
    ADAFS_DATA->spdlogger()->debug("the inode that was gotten from do_lookup: {}", inode);

    return inode;
}


/**
 * Creates an empty file in the dentry folder of the parent directory, acting as a dentry for lookup
 * @param parent_dir
 * @param inode
 * @param name
 * @return
 */
int create_dentry(const unsigned long p_inode, const uint64_t inode) {
int create_dentry(const uint64_t p_inode, const uint64_t inode, const string& name, mode_t mode) {
//    ADAFS_DATA->logger->debug("create_dentry() enter with fname: {}", inode);
//    // XXX Errorhandling
//    auto f_path = bfs::path(ADAFS_DATA->dentry_path);
//    f_path /= to_string(p_inode);
//    if (!bfs::exists(f_path)) return -ENOENT;
//
//    f_path /= inode;
//
//    bfs::ofstream ofs{f_path};
//
//    // XXX make sure the file has been created
    // XXX Errorhandling
    auto d_path = bfs::path(ADAFS_DATA->dentry_path());
    d_path /= to_string(p_inode);
    // 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;
}
+3 −1
Original line number Diff line number Diff line
@@ -15,7 +15,9 @@ bool verify_dentry(const uint64_t inode);

int read_dentries(const uint64_t p_inode, const unsigned long inode);

int create_dentry(const unsigned long p_inode, const uint64_t inode);
uint64_t do_lookup(fuse_req_t& req, const uint64_t p_inode, const std::string& name);

int create_dentry(const uint64_t p_inode, const uint64_t inode, const std::string& name, mode_t mode);

int remove_dentry(const unsigned long p_inode, const uint64_t inode);

+60 −1
Original line number Diff line number Diff line
@@ -38,6 +38,12 @@ bool read_all_metadata(Metadata& md, const uint64_t inode) {
    return true;
}

/**
 * Gets the metadata via its inode and puts it into an Metadata object.
 * @param md
 * @param inode
 * @return err
 */
int get_metadata(Metadata& md, const uint64_t inode) {
    ADAFS_DATA->spdlogger()->debug("get_metadata() enter for inode {}", inode);
    // Verify that the file's inode exists
@@ -47,7 +53,40 @@ int get_metadata(Metadata& md, const uint64_t inode) {
        read_all_metadata(md, inode);
        return 0;
    } else
        return ENOENT;
        return -ENOENT;
}

/**
 * Gets the metadata via its inode and puts it into the stat struct.
 *
 * @param req
 * @param attr
 * @param inode
 * @return err
 */
int get_attr(struct stat& attr, const uint64_t inode) {

    // XXX look in cache first
    auto md = make_shared<Metadata>();
    auto err = get_metadata(*md, inode);

    metadata_to_stat(*md, attr);

    return err;
}

void metadata_to_stat(const Metadata& md, struct stat& attr) {
    attr.st_ino = md.inode_no();
    attr.st_mode = md.mode();
    attr.st_nlink = md.link_count();
    attr.st_uid = md.uid();
    attr.st_gid = md.gid();
    attr.st_size = md.size();
    attr.st_blksize = ADAFS_DATA->blocksize();
    attr.st_blocks = md.blocks();
    attr.st_atim.tv_sec = md.atime();
    attr.st_mtim.tv_sec = md.mtime();
    attr.st_ctim.tv_sec = md.ctime();
}

/**
@@ -71,7 +110,27 @@ int get_metadata(Metadata& md, const uint64_t inode) {
//    return 0;
//}

int create_node(fuse_req_t& req, struct fuse_entry_param& fep, uint64_t parent, const string& name, mode_t mode) {

    // create metadata of new file (this will also create a new inode number)
    // mode is used here to init metadata
    auto md = make_shared<Metadata>(S_IFREG | mode, fuse_req_ctx(req)->uid, fuse_req_ctx(req)->gid, req);

    // create directory entry (can fail) in adafs
    create_dentry(parent, md->inode_no(), name, mode);

    // write metadata
    write_all_metadata(*md, md->inode_no());

    // create dentry for Linux
    fep.entry_timeout = 1.0;
    fep.attr_timeout = 1.0;
    fep.ino = md->inode_no();
    //fill fep->attr with the metadata information
    metadata_to_stat(*md, fep.attr);

    return 0;
}



Loading