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

uncomplete cleanup and ci requirements

parent d0c031f3
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -62,6 +62,9 @@ gkfs:
    - sed -i 's/constexpr bool use_dentry_cache = false;/constexpr bool use_dentry_cache = true;/g' "${CI_PROJECT_DIR}/include/config.hpp"
    #- sed -i 's/constexpr auto zero_buffer_before_read = false;/constexpr auto zero_buffer_before_read = true;/g' "${CI_PROJECT_DIR}/include/config.hpp"
    #- sed -i 's/constexpr auto implicit_data_removal = true;/constexpr auto implicit_data_removal = false;/g' "${CI_PROJECT_DIR}/include/config.hpp"
    # install libfuse
    - apt update
    - apt install libfuse3-dev fuse3
    # use ccache
    - ccache --zero-stats -M 750MiB -F 800 --evict-older-than 10d
    - /usr/sbin/update-ccache-symlinks
+3 −182
Original line number Diff line number Diff line
@@ -46,8 +46,7 @@ extern "C" {
#define FUSE_USE_VERSION FUSE_MAKE_VERSION(3, 12)
#include <fuse3/fuse_lowlevel.h>

// TODO do we really need this? Now its to replace the libc.hpp def for the
// sizeof(DIR) statement
// TODO do we really need this? sizeof(DIR) statement, copied from gkfs_libc.hpp
struct __dirstream {
    int fd; // File descriptor.
    //__libc_lock_define (, lock) // Mutex lock for this structure. //TODO
@@ -75,29 +74,10 @@ struct __dirstream {
#include <pthread.h>
#include <sys/file.h>
#include <sys/xattr.h>

/* We are re-using pointers to our `struct lo_inode` and `struct
   lo_dirp` elements as inodes. This means that we must be able to
   store uintptr_t values in a fuse_ino_t variable. The following
   incantation checks this condition at compile time. */
#if defined(__GNUC__) &&                                                       \
        (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 6) &&              \
        !defined __cplusplus
_Static_assert(sizeof(fuse_ino_t) >= sizeof(uintptr_t),
               "fuse_ino_t too small to hold uintptr_t values!");
#else
struct _uintptr_to_must_hold_fuse_ino_t_dummy_struct {
    unsigned _uintptr_to_must_hold_fuse_ino_t
        : ((sizeof(fuse_ino_t) >= sizeof(uintptr_t)) ? 1 : -1);
};
#endif

#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <filesystem>
#include <unordered_map>
#include <string>
#include <mutex>
@@ -117,98 +97,6 @@ struct _uintptr_to_must_hold_fuse_ino_t_dummy_struct {
#include <client/preload_context.hpp>
#include <client/user_functions.hpp>

static inline int
do_fallocate(int fd, int mode, off_t offset, off_t length) {
#ifdef HAVE_FALLOCATE
    if(fallocate(fd, mode, offset, length) == -1)
        return -errno;
    return 0;
#else // HAVE_FALLOCATE

#ifdef HAVE_POSIX_FALLOCATE
    if(mode == 0)
        return -posix_fallocate(fd, offset, length);
#endif

#ifdef HAVE_FSPACECTL
    // 0x3 == FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE
    if(mode == 0x3) {
        struct spacectl_range sr;

        sr.r_offset = offset;
        sr.r_len = length;
        if(fspacectl(fd, SPACECTL_DEALLOC, &sr, 0, NULL) == -1)
            return -errno;
        return 0;
    }
#endif

    return -EOPNOTSUPP;
#endif // HAVE_FALLOCATE
}

// all from the gkfs_libc
enum class PathStatus { External, Internal, Error };

/**
 * @brief Resolves a path in the context of GekkoFS.
 * (Details as in original comment)
 */
static inline PathStatus
resolve_gkfs_path(int dirfd, const char* path, std::string& resolved,
                  int flags = 0, bool resolve_last_link = true) {
    const auto status = CTX->relativize_fd_path(dirfd, path, resolved, flags,
                                                resolve_last_link);
    switch(status) {
        case gkfs::preload::RelativizeStatus::internal:
            return PathStatus::Internal;
        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
            errno = ENOTDIR;
            return PathStatus::Error;
        case gkfs::preload::RelativizeStatus::fd_unknown:
            errno = EBADF;
            return PathStatus::Error;
        default: // Assuming other statuses mean external or not applicable
            return PathStatus::External;
    }
}

#define DEBUG_INFO(...)                                                        \
    do {                                                                       \
        if(CTX->interception_enabled())                                        \
            LOG(DEBUG, __VA_ARGS__);                                           \
    } while(0)

#define GKFS_PATH_OPERATION(name, dirfd, path, ...)                            \
    if(CTX->interception_enabled()) {                                          \
        std::string resolved;                                                  \
        switch(resolve_gkfs_path(dirfd, path, resolved)) {                     \
            case PathStatus::Internal:                                         \
                fuse_log(FUSE_LOG_DEBUG, "[GKFS] {}(path='{}')\n", #name,      \
                         resolved.c_str());                                    \
                return gkfs::syscall::gkfs_##name(resolved, __VA_ARGS__);      \
            case PathStatus::Error:                                            \
                return -1;                                                     \
            default: /* External */                                            \
                break;                                                         \
        }                                                                      \
    }

#define GKFS_PATH_OPERATION1(name, dirfd, path)                                \
    if(CTX->interception_enabled()) {                                          \
        std::string resolved;                                                  \
        switch(resolve_gkfs_path(dirfd, path, resolved)) {                     \
            case PathStatus::Internal:                                         \
                fuse_log(FUSE_LOG_DEBUG, "[GKFS] {}(path='{}')\n", #name,      \
                         resolved.c_str());                                    \
                gkfs::syscall::gkfs_##name(resolved);                          \
            case PathStatus::Error:                                            \
                fuse_reply_err(req, -1);                                       \
            default: /* External */                                            \
                fuse_reply_err(req, -1);                                       \
        }                                                                      \
    }

struct GkfsDir { // Hypothetical structure that might be used if DIR is cast
    int fd;
    long int tell_pos; // for telldir/seekdir
@@ -216,73 +104,6 @@ struct GkfsDir { // Hypothetical structure that might be used if DIR is cast
    // other members libc DIR might have
};

static inline std::pair<int, std::string>
lol_path(int dfd, const char* path, int flags) {
    std::string resolved = "";
    int err = 0;
    if(CTX->interception_enabled()) {
        // AT_SYMLINK_NOFOLLOW means lstat behavior, otherwise stat behavior.
        bool follow_link = !(flags & AT_SYMLINK_NOFOLLOW);
        // Path resolution needs to know if it's for lstat or stat context for
        // the final component. resolve_gkfs_path's `resolve_last_link`
        // parameter handles this.
        switch(resolve_gkfs_path(dfd, path, resolved, flags, follow_link)) {
            case PathStatus::Internal:
                break;
            case PathStatus::Error:
                err = -1;
                break;
            default: // External
                break;
        }
    }
    return std::make_pair(err, resolved);
}

static inline int
lol_fstatat(int dfd, const char* path, struct stat* buf, int flags) {

    if(CTX->interception_enabled()) {
        std::string resolved;
        // AT_SYMLINK_NOFOLLOW means lstat behavior, otherwise stat behavior.
        bool follow_link = !(flags & AT_SYMLINK_NOFOLLOW);
        // Path resolution needs to know if it's for lstat or stat context for
        // the final component. resolve_gkfs_path's `resolve_last_link`
        // parameter handles this.
        switch(resolve_gkfs_path(dfd, path, resolved, flags, follow_link)) {
            case PathStatus::Internal:
                return gkfs::syscall::gkfs_stat(resolved, buf, follow_link);
            case PathStatus::Error:
                return -1; // errno set
            default:       // External
                break;
        }
    }
    return -1;
}

static inline int
lol_openat(int dfd, const char* path, mode_t mode, int flags) {
    if(CTX->interception_enabled()) {
        std::string resolved;
        // AT_SYMLINK_NOFOLLOW means lstat behavior, otherwise stat behavior.
        bool follow_link = !(flags & AT_SYMLINK_NOFOLLOW);
        // Path resolution needs to know if it's for lstat or stat context for
        // the final component. resolve_gkfs_path's `resolve_last_link`
        // parameter handles this.
        switch(resolve_gkfs_path(dfd, path, resolved, flags, follow_link)) {
            case PathStatus::Internal:
                fuse_log(FUSE_LOG_DEBUG, "lol_openat internal\n");
                return gkfs::syscall::gkfs_open(resolved, mode, follow_link);
            case PathStatus::Error:
                return -1; // errno set
            default:       // External
                break;
        }
    }
    return -1;
}

/*
 * Creates files on the underlying file system in response to a FUSE_MKNOD
 * operation
@@ -294,12 +115,12 @@ mknod_wrapper(int dirfd, const char* path, const char* link, int mode,
    int res = -1;

    if(S_ISREG(mode)) {
        res = lol_openat(dirfd, path, mode, O_CREAT | O_EXCL | O_WRONLY);
        //res = lol_openat(dirfd, path, mode, O_CREAT | O_EXCL | O_WRONLY);
        fuse_log(FUSE_LOG_DEBUG, "lol_openat internal %s\n", res);
        if(res >= 0)
            res = gkfs::syscall::gkfs_close(res);
    } else if(S_ISDIR(mode)) {
        GKFS_PATH_OPERATION(create, dirfd, path, mode | S_IFDIR)
        //GKFS_PATH_OPERATION(create, dirfd, path, mode | S_IFDIR)
        // res = gkfs::syscall::gkfs_create(resolved, mode | S_IFDIR);
        //  res = mkdirat(dirfd, path, mode);
    } else if(S_ISLNK(mode) && link != NULL) {
+2 −8
Original line number Diff line number Diff line
@@ -37,14 +37,7 @@
  SPDX-License-Identifier: LGPL-3.0-or-later
*/

#include "client/env.hpp"
#include "common/env_util.hpp"
#include <cerrno>
#include <client/fuse/fuse_client.hpp>
#include <cstdio>
#include <cstdlib>
#include <dirent.h>
#include <iostream>

struct lo_inode {
    struct lo_inode* next; /* protected by lo->mutex */
@@ -532,7 +525,7 @@ main(int argc, char* argv[]) {
    int ret = -1;

    /* Don't mask creation mode, kernel already did that */
    umask(0);
    umask(0); // TODO do we need this and why?

    pthread_mutex_init(&lo.mutex, NULL);
    lo.root.next = lo.root.prev = &lo.root;
@@ -634,6 +627,7 @@ main(int argc, char* argv[]) {
        exit(1);
    }

    // TODO do we still want this? what do we want?
    fuse_log(FUSE_LOG_DEBUG, "hier 1\n");
    lo.root.fd = gkfs::syscall::gkfs_open(lo.source, 755, O_PATH);
    if(lo.root.fd == -1) {