Commit cc7991a0 authored by sevenuz's avatar sevenuz Committed by Julius Athenstaedt
Browse files

unlink, rmdir, releasedir and access handlers

parent b749fe28
Loading
Loading
Loading
Loading
+73 −7
Original line number Diff line number Diff line
@@ -342,6 +342,25 @@ create_handler(fuse_req_t req, fuse_ino_t parent, const char* name, mode_t mode,
    fuse_reply_create(req, &e, fi);
}

/// TODO normally, the file should only be removed if the lookup count is zero,
/// problem?
static void
unlink_handler(fuse_req_t req, fuse_ino_t parent, const char* name) {
    fuse_log(FUSE_LOG_DEBUG, "unlink handler \n");
    auto* parent_inode = get_inode(parent);
    if(!parent_inode) {
        fuse_reply_err(req, ENOENT);
        return;
    }
    std::string path = get_path(parent_inode, name);
    int rc = gkfs::syscall::gkfs_remove(path);
    if(rc == -1) {
        fuse_reply_err(req, 1);
        return;
    }
    fuse_reply_err(req, 0);
}

static void
opendir_handler(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info* fi) {
    fuse_log(FUSE_LOG_DEBUG, "opendir handler \n");
@@ -443,6 +462,24 @@ readdir_handler(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
    free(buf);
}

static void
releasedir_handler(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info* fi) {
    fuse_log(FUSE_LOG_DEBUG, "releasedir handler \n");
    GkfsDir* dir_ptr = reinterpret_cast<GkfsDir*>(fi->fh);
    if(CTX->interception_enabled() && CTX->file_map()->exist(dir_ptr->fd)) {
        int fd = dir_ptr->fd;
        int ret = gkfs::syscall::gkfs_close(fd); // Close GekkoFS internal FD

        if(dir_ptr->path) { // Check if path was strdup'd
            free(dir_ptr->path);
        }
        free(dir_ptr); // Free the DIR struct itself
        fuse_reply_err(req, ret);
        return;
    }
    fuse_reply_err(req, 0);
}

/// releases file descriptor, not connected to lookup_count
static void
release_handler(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info* fi) {
@@ -495,17 +532,30 @@ flush_handler(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info* fi) {
    fuse_log(FUSE_LOG_DEBUG, "flush handler \n");
    auto* inode = get_inode(ino);
    if(!inode) {
        fuse_log(FUSE_LOG_DEBUG, "flush here \n");
        fuse_reply_err(req, ENOENT);
        return;
    }
    int lc = gkfs::syscall::gkfs_fsync(fi->fh);
    if(lc < 0) {
        fuse_log(FUSE_LOG_DEBUG, "flush there \n");
        fuse_reply_err(req, 1);
        return;
    }
    fuse_log(FUSE_LOG_DEBUG, "flush success \n");
    fuse_reply_err(req, 0);
}

static void
access_handler(fuse_req_t req, fuse_ino_t ino, int mask) {
    fuse_log(FUSE_LOG_DEBUG, "access handler \n");
    auto* inode = get_inode(ino);
    if(!inode) {
        fuse_reply_err(req, ENOENT);
        return;
    }
    int lc = gkfs::syscall::gkfs_access(inode->path, mask, true);
    if(lc < 0) {
        fuse_reply_err(req, 1);
        return;
    }
    fuse_reply_err(req, 0);
}

@@ -544,6 +594,22 @@ mkdir_handler(fuse_req_t req, fuse_ino_t parent, const char* name,
    fuse_reply_entry(req, &e);
}

static void
rmdir_handler(fuse_req_t req, fuse_ino_t parent, const char* name) {
    auto* parent_inode = get_inode(parent);
    if(!parent_inode) {
        fuse_reply_err(req, ENOENT);
        return;
    }
    std::string path = get_path(parent_inode, name);
    int rc = gkfs::syscall::gkfs_rmdir(path);
    if(rc == -1) {
        fuse_reply_err(req, 1);
        return;
    }
    fuse_reply_err(req, 0);
}

static void
init_gekkofs() {
    // TODO how to handle mount point
@@ -579,7 +645,7 @@ init_ll_ops(fuse_lowlevel_ops* ops) {
    ops->setattr = setattr_handler;
    ops->open = open_handler;
    ops->create = create_handler;
    // ops->unlink
    ops->unlink = unlink_handler;
    ops->forget = forget_handler;
    // ops->forget_multi
    // ops->readlink
@@ -601,10 +667,10 @@ init_ll_ops(fuse_lowlevel_ops* ops) {
    // directory
    ops->lookup = lookup_handler;
    ops->mkdir = mkdir_handler;
    // ops->rmdir
    ops->rmdir = rmdir_handler;
    ops->readdir = readdir_handler;
    ops->opendir = opendir_handler;
    // ops->releasedir
    ops->releasedir = releasedir_handler;
    // ops->fsyncdir = nullptr;
    // ops->readdirplus

@@ -613,7 +679,7 @@ init_ll_ops(fuse_lowlevel_ops* ops) {
    ops->read = read_handler;

    // permission
    // ops->access
    ops->access = access_handler;

    // misc
    ops->init = init_handler;
+8 −3
Original line number Diff line number Diff line
@@ -58,6 +58,11 @@ def test_read(gkfs_daemon, fuse_client):
    assert sh.ls(fuse_client.mountdir) == "dir  file  file2\n"
    sh.cd(str(dir))
    assert sh.pwd() == str(dir) + "\n"
    sh.mkdir("-p", "fu/bar")
    assert sh.ls() == "fu\n"
    sh.cd("fu")
    sh.mkdir("-p", "foo/bar")
    assert sh.ls() == "foo\n"
    sh.cd("foo")
    sh.rmdir("bar")
    sh.cd("..")
    sh.rmdir("foo")
    sh.rm(str(file2))
    assert sh.ls(fuse_client.mountdir) == "dir  file\n"