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

touch() and ls() implemented

parent 5e510a6a
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -59,6 +59,9 @@ int adafs_opendir(const char* p, struct fuse_file_info* fi) {
int adafs_readdir(const char* p, void* buf, fuse_fill_dir_t filler, off_t offset,
                  struct fuse_file_info* fi, enum fuse_readdir_flags flags) {
    ADAFS_DATA->logger->debug("FUSE: adafs_readdir() enter"s);
    // XXX ls also reports the number of allocated blocks IN the directory. Non recursive. Currently not considered


    auto path = bfs::path(p);
    auto md = make_shared<Metadata>();
    // first check that dir exists that is trying to be read. I don't know if this is actually needed,
@@ -72,6 +75,9 @@ int adafs_readdir(const char* p, void* buf, fuse_fill_dir_t filler, off_t offset
    if (read_dentries(*dentries, ADAFS_DATA->hashf(path.string())) != 0)
        return 1; // XXX problemo dedected deal with it later (I mean me)

    // visualizing current and parent dir
    filler(buf, ".", NULL, 0, FUSE_FILL_DIR_PLUS);
    filler(buf, "..", NULL, 0, FUSE_FILL_DIR_PLUS);
    for (auto& dentry : *dentries) {
        // XXX I have no idea what the last parameter really does...
        filler(buf, dentry.c_str(), NULL, 0, FUSE_FILL_DIR_PLUS);
+24 −1
Original line number Diff line number Diff line
@@ -4,11 +4,19 @@

#include "../main.h"
#include "../fuse_ops.h"
#include "../metadata.h"
#include "../metadata_ops.h"

using namespace std;

/** Get file attributes.
 *
 * Similar to stat().  The 'st_dev' and 'st_blksize' fields are
 * ignored. The 'st_ino' field is ignored except if the 'use_ino'
 * mount option is given.
 *
 * `fi` will always be NULL if the file is not currenly open, but
 * may also be NULL if the file is open.
 */
int adafs_getattr(const char* p, struct stat* attr, struct fuse_file_info* fi) {

    auto path = bfs::path(p);
@@ -56,7 +64,20 @@ int adafs_getattr(const char* p, struct stat* attr, struct fuse_file_info* fi) {
 */
int adafs_mknod(const char* p, mode_t mode, dev_t dev) {
    ADAFS_DATA->logger->debug("FUSE: adafs_readdir() enter"s);
    // XXX Errorhandling and beware of transactions. saving dentry and metadata have to be atomic
    auto path = bfs::path(p);

    // XXX check if file exists (how can we omit this? Let's just try to create it and see if it fails)

    // XXX check permissions (omittable)

    // XXX create directory entry (can fail)
    create_dentry(ADAFS_DATA->hashf(path.parent_path().string()), path.filename().string());

    // XXX create metadata of new file
    // mode is used here to init metadata
    auto md = make_unique<Metadata>(mode);
    write_all_metadata(*md, ADAFS_DATA->hashf(path.string()));

    return 0;
}
@@ -77,6 +98,7 @@ int adafs_mknod(const char* p, mode_t mode, dev_t dev) {
 * passed to all file operations.
 */
int adafs_open(const char* p, struct fuse_file_info* ffi) {
    // XXX ignored for now. Will be similar to opendir. Implement when implementing I/O
    return 0;
}

@@ -93,5 +115,6 @@ int adafs_open(const char* p, struct fuse_file_info* ffi) {
 * See the utimensat(2) man page for details.
 */
int adafs_utimens(const char* p, const struct timespec tv[2], struct fuse_file_info* fi) {
    // XXX ignored for now. Later: Make it configurable
    return 0;
}
+21 −0
Original line number Diff line number Diff line
@@ -5,6 +5,27 @@
#include "../main.h"
#include "../fuse_ops.h"

/** Possibly flush cached data
 *
 * BIG NOTE: This is not equivalent to fsync().  It's not a
 * request to sync dirty data.
 *
 * Flush is called on each close() of a file descriptor.  So if a
 * filesystem wants to return write errors in close() and the file
 * has cached dirty data, this is a good place to write back data
 * and return any errors.  Since many applications ignore close()
 * errors this is not always useful.
 *
 * NOTE: The flush() method may be called more than once for each
 * open().	This happens if more than one file descriptor refers
 * to an opened file due to dup(), dup2() or fork() calls.	It is
 * not possible to determine if a flush is final, so each flush
 * should be treated equally.  Multiple write-flush sequences are
 * relatively rare, so this shouldn't be a problem.
 *
 * Filesystems shouldn't assume that flush will always be called
 * after some writes, or that if will be called at all.
 */
int adafs_flush(const char*, struct fuse_file_info*) {
    return 0;
}
+2 −0
Original line number Diff line number Diff line
@@ -39,8 +39,10 @@ void *adafs_init(struct fuse_conn_info *conn, struct fuse_config *cfg) {
        ADAFS_DATA->logger->debug("Root metadata not found. Initializing..."s);
        md->init_ACM_time();
        md->mode(S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO); // chmod 777
        md->size(4096); // XXX just visual. size computation of directory should be done properly at some point
//        md->mode(S_IFDIR | 0755);
        // XXX The gid and uid is the root user for some reason. Should be the user that mounted fuse.
        // This is because fuse is mounted through root although it was triggered by the user
        md->uid(fuse_get_context()->uid);
        md->gid(fuse_get_context()->gid);
        md->inode_no(ADAFS_ROOT_INODE);
+21 −2
Original line number Diff line number Diff line
@@ -94,7 +94,7 @@ int get_metadata(Metadata& md, const bfs::path& path) {
 * Reads all directory entries in a directory with a given @hash. Returns 0 if successful.
 * @dir is assumed to be empty
 */
int read_dentries(vector<string> dir, const unsigned long hash) {
int read_dentries(vector<string>& dir, const unsigned long hash) {
    auto path = bfs::path(ADAFS_DATA->dentry_path);
    path /= to_string(hash);
    if (!bfs::exists(path)) return 1;
@@ -105,11 +105,30 @@ int read_dentries(vector<string> dir, const unsigned long hash) {
    bfs::directory_iterator end_dir_it;
    for (bfs::directory_iterator dir_it(path); dir_it != end_dir_it; ++dir_it) {
        const bfs::path cp = (*dir_it);
        dir.push_back(cp.string());
        dir.push_back(cp.filename().string());
    }
    return 0;
}
/**
 * Creates an empty file in the dentry folder of the parent directory, acting as a dentry for lookup
 * @param parent_dir
 * @param fname
 * @return
 */
int create_dentry(const unsigned long parent_dir_hash, const string& fname) {
    // XXX Errorhandling
    auto f_path = bfs::path(ADAFS_DATA->dentry_path);
    f_path /= to_string(parent_dir_hash);
    if (!bfs::exists(f_path)) return 1;

    f_path /= fname;

    bfs::ofstream ofs{f_path};

    // XXX make sure the file has been created

    return 0;
}



Loading