Commit 4fffcebb authored by Julius Athenstaedt's avatar Julius Athenstaedt
Browse files

code cleanup and bug fixes

parent 16646a84
Loading
Loading
Loading
Loading
Loading
+78 −85
Original line number Diff line number Diff line
@@ -102,6 +102,41 @@ remove_inode_by_path(const std::string path) {
    }
}

static int
fill_fuse_entry_param(const u_data* ud, const std::string path,
                      fuse_entry_param& fep, bool check_path_map = true) {

    struct stat st;
    int rc = gkfs::syscall::gkfs_stat(path, &st);
    if(rc < 0) {
        return rc;
    }

    // See if we already have this path
    ino_mutex.lock();
    auto it_end = path_map.end();
    auto it = check_path_map ? path_map.find(path) : it_end;
    ino_mutex.unlock();

    fuse_ino_t ino;
    if(it != it_end) {
        ino = it->second;
        auto inode = get_inode(ino);
        if(inode) {
            inode->lookup_count++;
        }
    } else {
        ino = alloc_inode(path);
    }

    fep.ino = ino;
    fep.attr = st;
    fep.attr_timeout = ud->timeout;
    fep.entry_timeout = ud->timeout;

    return 0;
}

static struct u_data*
udata(fuse_req_t req) {
    return (struct u_data*) fuse_req_userdata(req);
@@ -268,33 +303,12 @@ lookup_handler(fuse_req_t req, fuse_ino_t parent, const char* name) {
        }
    }

    struct stat st;
    int rc = gkfs::syscall::gkfs_stat(child, &st);
    fuse_entry_param e = {};
    int rc = fill_fuse_entry_param(ud, child, e);
    if(rc < 0) {
        fuse_reply_err(req, ENOENT);
        return;
    }

    // See if we already have this path
    // TODO Do we have to lock here? The test ends up in a deadlock!
    // std::lock_guard<std::mutex> lk(ino_mutex);
    auto it = path_map.find(child);
    fuse_ino_t ino;
    if(it != path_map.end()) {
        ino = it->second;
        auto inode = get_inode(ino);
        if(inode) {
            inode->lookup_count++;
        }
    } else {
        ino = alloc_inode(child);
    }

    fuse_entry_param e = {};
    e.ino = ino;
    e.attr = st;
    e.attr_timeout = ud->timeout;
    e.entry_timeout = ud->timeout;
    fuse_reply_entry(req, &e);
}

@@ -441,6 +455,19 @@ create_handler(fuse_req_t req, fuse_ino_t parent, const char* name, mode_t mode,
        return;
    }
    std::string path = get_path(parent_inode, name);
    // This is the code of commit: d79429bd1f188a3a87d0d9b00c773965c82c714d
    // somehow the changes there break vim but on the other side with this,
    // compss has some errors
    /*
    int rc = gkfs::syscall::gkfs_create(path, mode);
    int errno_bu = errno;
    if(rc == -1) {
        fuse_log(FUSE_LOG_DEBUG,
                 "create failed, here here mode %i flags %i errno %i\n", mode,
                 fi->flags, errno);
    }
    int fd = gkfs::syscall::gkfs_open(path, mode, fi->flags);
    */
    DEBUG_INFO(ud, "create handler %s", path.c_str());
    int fd = gkfs::syscall::gkfs_open(path, mode, fi->flags | O_CREAT);
    if(fd < 0) {
@@ -450,19 +477,13 @@ create_handler(fuse_req_t req, fuse_ino_t parent, const char* name, mode_t mode,
    }
    fi->fh = fd;
    fi->direct_io = ud->direct_io;
    struct stat st;
    int sc = gkfs::syscall::gkfs_stat(path, &st);
    if(sc == -1) {

    fuse_entry_param e = {};
    int sc = fill_fuse_entry_param(ud, path, e, false);
    if(sc < 0) {
        fuse_reply_err(req, ENOENT);
        return;
    }
    fuse_ino_t ino = alloc_inode(path);
    DEBUG_INFO(ud, "create new inode ino %i", ino);
    fuse_entry_param e = {};
    e.ino = ino;
    e.attr = st;
    e.attr_timeout = ud->timeout;
    e.entry_timeout = ud->timeout;
    fuse_reply_create(req, &e, fi);
}

@@ -629,50 +650,29 @@ readdirplus_handler(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
    while(pos < open_dir->size()) {
        auto de = open_dir->getdent(pos);

        // --- TODO maybe refactor into fn with lookup_handler
        std::string child = open_dir->path() == "/"
                                    ? "/" + de.name()
                                    : open_dir->path() + "/" + de.name();
        DEBUG_INFO(ud, "read dirplus child %s", child.c_str());

        struct stat st{};
        fuse_entry_param e = {};

        if(de.name() == "." || de.name() == "..") {
            struct stat st{};
            st.st_ino = std::hash<std::string>()(open_dir->path() + "/" +
                                                 de.name());
            st.st_mode = (de.type() == gkfs::filemap::FileType::regular)
                                 ? S_IFREG
                                 : S_IFDIR;
            e.attr = st;
        } else {
            int rc = gkfs::syscall::gkfs_stat(child, &st);
            if(rc < 0) {
            int sc = fill_fuse_entry_param(ud, child, e);
            if(sc < 0) {
                fuse_reply_err(req, ENOENT);
                return;
            }

            // See if we already have this path
            // TODO Do we have to lock here? The test ends up in a deadlock!
            // std::lock_guard<std::mutex> lk(ino_mutex);
            auto it = path_map.find(child);
            fuse_ino_t ino;
            if(it != path_map.end()) {
                ino = it->second;
                auto inode = get_inode(ino);
                if(inode) {
                    inode->lookup_count++;
                }
            } else {
                ino = alloc_inode(child);
        }

            e.ino = ino;
        }
        e.attr = st;
        e.attr_timeout = ud->timeout;
        e.entry_timeout = ud->timeout;
        // ---

        size_t entry_size = fuse_add_direntry_plus(
                req, buf + bytes_filled, size - bytes_filled, de.name().c_str(),
                &e, pos + 1);
@@ -847,19 +847,13 @@ mkdir_handler(fuse_req_t req, fuse_ino_t parent, const char* name,
        fuse_reply_err(req, 1);
        return;
    }
    struct stat st;
    int sc = gkfs::syscall::gkfs_stat(path, &st);
    if(sc == -1) {
        fuse_reply_err(req, 1);

    fuse_entry_param e = {};
    int err = fill_fuse_entry_param(ud, path, e, false);
    if(err < 0) {
        fuse_reply_err(req, ENOENT);
        return;
    }
    fuse_ino_t ino = alloc_inode(path);
    DEBUG_INFO(ud, "create new inode ino %i", ino);
    fuse_entry_param e = {};
    e.ino = ino;
    e.attr = st;
    e.attr_timeout = ud->timeout;
    e.entry_timeout = ud->timeout;
    fuse_reply_entry(req, &e);
}

@@ -925,30 +919,25 @@ symlink_handler(fuse_req_t req, const char* linkname, fuse_ino_t parent,
                          target.substr(strlen(ud->mountpoint)).c_str());
    }

    DEBUG_INFO(ud, "mk symlink path %s target %s", path.c_str());
    DEBUG_INFO(ud, "mk symlink path %s target %s", path.c_str(), target.c_str());
    int rc = gkfs::syscall::gkfs_mk_symlink(path, target);
    if(rc < 0) {
        fuse_reply_err(req, 1);
        return;
    }

    fuse_entry_param e = {};
    // Stat the new symlink so we can reply with entry info
    struct stat st;
    if(gkfs::syscall::gkfs_stat(path, &st) < 0) {
        DEBUG_INFO(ud, "stat failed %i", errno);
        fuse_reply_err(req, errno);
    int sc = fill_fuse_entry_param(ud, path, e, false);
    if(sc < 0) {
        fuse_reply_err(req, ENOENT);
        return;
    }
    DEBUG_INFO(ud, "stat mode %i, iflink %i", st.st_mode, S_IFLNK);
    // TODO this meta is not saved and therefore on restart gone
    // this shows the link on ls -l
    st.st_mode = S_IFLNK | 0777; // mark as symlink + full perms
    fuse_entry_param e = {};
    e.ino = alloc_inode(path);
    e.attr = st;
    st.st_size = strlen(target.c_str());
    e.attr_timeout = ud->timeout;
    e.entry_timeout = ud->timeout;
    e.attr.st_mode = S_IFLNK | 0777; // mark as symlink + full perms
    e.attr.st_size = strlen(target.c_str());
    //DEBUG_INFO(ud, "stat mode %i, iflink %i", e.attr.st_mode, S_IFLNK);
    fuse_reply_entry(req, &e);
#else
    fuse_reply_err(req, ENOTSUP);
@@ -999,9 +988,14 @@ rename_handler(fuse_req_t req, fuse_ino_t old_parent, const char* old_name,
        return;
    }

    fuse_ino_t src_ino = 0;
    ino_mutex.lock();
    auto it_end = path_map.end();
    auto it_src = path_map.find(old_path);
    if(it_src != path_map.end()) {
    ino_mutex.unlock();

    fuse_ino_t src_ino = 0;

    if(it_src != it_end) {
        src_ino = it_src->second;
        path_map.erase(it_src);
        path_map[new_path] = src_ino;
@@ -1105,7 +1099,6 @@ init_gekkofs() {
        exit(1);
    }
    root_inode = {root_path, 1};
    ino_map[FUSE_ROOT_ID] = root_inode;
    path_map[root_path] = FUSE_ROOT_ID;
    std::cout << "root node allocated" << std::endl;
}